layerscape: refresh patches
[openwrt/staging/jow.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 --- /dev/null
531 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
532 @@ -0,0 +1,173 @@
533 +menuconfig FSL_SDK_DPAA_ETH
534 + tristate "DPAA Ethernet"
535 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
536 + select PHYLIB
537 + help
538 + Data Path Acceleration Architecture Ethernet driver,
539 + supporting the Freescale QorIQ chips.
540 + Depends on Freescale Buffer Manager and Queue Manager
541 + driver and Frame Manager Driver.
542 +
543 +if FSL_SDK_DPAA_ETH
544 +
545 +config FSL_DPAA_HOOKS
546 + bool "DPAA Ethernet driver hooks"
547 +
548 +config FSL_DPAA_CEETM
549 + bool "DPAA CEETM QoS"
550 + depends on NET_SCHED
551 + default n
552 + help
553 + Enable QoS offloading support through the CEETM hardware block.
554 +
555 +config FSL_DPAA_OFFLINE_PORTS
556 + bool "Offline Ports support"
557 + depends on FSL_SDK_DPAA_ETH
558 + default y
559 + help
560 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
561 + most of the functionality of the regular, online ports, except they receive their
562 + frames from a core or an accelerator on the SoC, via QMan frame queues,
563 + rather than directly from the network.
564 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
565 + any online FMan port. They deliver the processed frames to frame queues, according
566 + to the applied PCD configurations.
567 +
568 + Choosing this feature will not impact the functionality and/or performance of the system,
569 + so it is safe to have it.
570 +
571 +config FSL_DPAA_ADVANCED_DRIVERS
572 + bool "Advanced DPAA Ethernet drivers"
573 + depends on FSL_SDK_DPAA_ETH
574 + default y
575 + help
576 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
577 + is needed to support advanced scenarios. Select this to also build the advanced
578 + drivers.
579 +
580 +config FSL_DPAA_ETH_JUMBO_FRAME
581 + bool "Optimize for jumbo frames"
582 + default n
583 + help
584 + Optimize the DPAA Ethernet driver throughput for large frames
585 + termination traffic (e.g. 4K and above).
586 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
587 + is set to 9600 bytes.
588 + Using this option in combination with small frames increases
589 + significantly the driver's memory footprint and may even deplete
590 + the system memory. Also, the skb truesize is altered and messages
591 + from the stack that warn against this are bypassed.
592 + This option is not available on LS1043.
593 +
594 +config FSL_DPAA_TS
595 + bool "Linux compliant timestamping"
596 + depends on FSL_SDK_DPAA_ETH
597 + default n
598 + help
599 + Enable Linux API compliant timestamping support.
600 +
601 +config FSL_DPAA_1588
602 + bool "IEEE 1588-compliant timestamping"
603 + depends on FSL_SDK_DPAA_ETH
604 + select FSL_DPAA_TS
605 + default n
606 + help
607 + Enable IEEE1588 support code.
608 +
609 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
610 + bool "Use driver's Tx queue selection mechanism"
611 + default y
612 + depends on FSL_SDK_DPAA_ETH
613 + help
614 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
615 + of the egress FQ. That will override the XPS support for this netdevice.
616 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
617 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
618 + and use the standard XPS support instead.
619 +
620 +config FSL_DPAA_ETH_MAX_BUF_COUNT
621 + int "Maximum nuber of buffers in private bpool"
622 + depends on FSL_SDK_DPAA_ETH
623 + range 64 2048
624 + default "128"
625 + help
626 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
627 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
628 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
629 +
630 +config FSL_DPAA_ETH_REFILL_THRESHOLD
631 + int "Private bpool refill threshold"
632 + depends on FSL_SDK_DPAA_ETH
633 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
634 + default "80"
635 + help
636 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
637 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
638 + modify this value unless one has very specific performance reasons.
639 +
640 +config FSL_DPAA_CS_THRESHOLD_1G
641 + hex "Egress congestion threshold on 1G ports"
642 + depends on FSL_SDK_DPAA_ETH
643 + range 0x1000 0x10000000
644 + default "0x06000000"
645 + help
646 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
647 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
648 + (e.g. by sending UDP datagrams at "while(1) speed"),
649 + and the larger the frame size, the more acute the problem.
650 + So we have to find a balance between these factors:
651 + - avoiding the device staying congested for a prolonged time (risking
652 + the netdev watchdog to fire - see also the tx_timeout module param);
653 + - affecting performance of protocols such as TCP, which otherwise
654 + behave well under the congestion notification mechanism;
655 + - preventing the Tx cores from tightly-looping (as if the congestion
656 + threshold was too low to be effective);
657 + - running out of memory if the CS threshold is set too high.
658 +
659 +config FSL_DPAA_CS_THRESHOLD_10G
660 + hex "Egress congestion threshold on 10G ports"
661 + depends on FSL_SDK_DPAA_ETH
662 + range 0x1000 0x20000000
663 + default "0x10000000"
664 + help
665 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
666 +
667 +config FSL_DPAA_INGRESS_CS_THRESHOLD
668 + hex "Ingress congestion threshold on FMan ports"
669 + depends on FSL_SDK_DPAA_ETH
670 + default "0x10000000"
671 + help
672 + The size in bytes of the ingress tail-drop threshold on FMan ports.
673 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
674 +
675 +config FSL_DPAA_ETH_DEBUGFS
676 + bool "DPAA Ethernet debugfs interface"
677 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
678 + default y
679 + help
680 + This option compiles debugfs code for the DPAA Ethernet driver.
681 +
682 +config FSL_DPAA_ETH_DEBUG
683 + bool "DPAA Ethernet Debug Support"
684 + depends on FSL_SDK_DPAA_ETH
685 + default n
686 + help
687 + This option compiles debug code for the DPAA Ethernet driver.
688 +
689 +config FSL_DPAA_DBG_LOOP
690 + bool "DPAA Ethernet Debug loopback"
691 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
692 + default n
693 + help
694 + This option allows to divert all received traffic on a certain interface A towards a
695 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
696 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
697 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
698 + change the loop setting for interface 4 and divert all received traffic to interface 5
699 + write Tx interface number in the receive interface debugfs file:
700 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
701 + 4->-1
702 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
703 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
704 + 4->5
705 +endif # FSL_SDK_DPAA_ETH
706 --- /dev/null
707 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
708 @@ -0,0 +1,46 @@
709 +#
710 +# Makefile for the Freescale Ethernet controllers
711 +#
712 +ccflags-y += -DVERSION=\"\"
713 +#
714 +# Include netcomm SW specific definitions
715 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
716 +
717 +ccflags-y += -I$(NET_DPA)
718 +
719 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
720 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
721 +
722 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
723 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
724 +fsl_dpa-objs += dpaa_debugfs.o
725 +endif
726 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
727 +fsl_dpa-objs += dpaa_1588.o
728 +endif
729 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
730 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
731 +fsl_dpa-objs += dpaa_eth_ceetm.o
732 +endif
733 +
734 +fsl_mac-objs += mac.o mac-api.o
735 +
736 +# Advanced drivers
737 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
738 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
739 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
740 +
741 +fsl_advanced-objs += dpaa_eth_base.o
742 +# suport for multiple drivers per kernel module comes in kernel 3.14
743 +# so we are forced to generate several modules for the advanced drivers
744 +fsl_proxy-objs += dpaa_eth_proxy.o
745 +
746 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
747 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
748 +
749 +fsl_oh-objs += offline_port.o
750 +endif
751 +endif
752 +
753 +# Needed by the tracing framework
754 +CFLAGS_dpaa_eth.o := -I$(src)
755 --- /dev/null
756 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
757 @@ -0,0 +1,580 @@
758 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
759 + * Copyright (C) 2009 IXXAT Automation, GmbH
760 + *
761 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
762 + *
763 + * This program is free software; you can redistribute it and/or modify
764 + * it under the terms of the GNU General Public License as published by
765 + * the Free Software Foundation; either version 2 of the License, or
766 + * (at your option) any later version.
767 + *
768 + * This program is distributed in the hope that it will be useful,
769 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
770 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
771 + * GNU General Public License for more details.
772 + *
773 + * You should have received a copy of the GNU General Public License along
774 + * with this program; if not, write to the Free Software Foundation, Inc.,
775 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
776 + *
777 + */
778 +#include <linux/io.h>
779 +#include <linux/device.h>
780 +#include <linux/fs.h>
781 +#include <linux/vmalloc.h>
782 +#include <linux/spinlock.h>
783 +#include <linux/ip.h>
784 +#include <linux/ipv6.h>
785 +#include <linux/udp.h>
786 +#include <asm/div64.h>
787 +#include "dpaa_eth.h"
788 +#include "dpaa_eth_common.h"
789 +#include "dpaa_1588.h"
790 +#include "mac.h"
791 +
792 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
793 +{
794 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
795 +
796 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
797 + if (!circ_buf->buf)
798 + return 1;
799 +
800 + circ_buf->head = 0;
801 + circ_buf->tail = 0;
802 + ptp_buf->size = size;
803 + spin_lock_init(&ptp_buf->ptp_lock);
804 +
805 + return 0;
806 +}
807 +
808 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
809 +{
810 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
811 +
812 + circ_buf->head = 0;
813 + circ_buf->tail = 0;
814 + ptp_buf->size = size;
815 +}
816 +
817 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
818 + struct dpa_ptp_data *data)
819 +{
820 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
821 + int size = ptp_buf->size;
822 + struct dpa_ptp_data *tmp;
823 + unsigned long flags;
824 + int head, tail;
825 +
826 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
827 +
828 + head = circ_buf->head;
829 + tail = circ_buf->tail;
830 +
831 + if (CIRC_SPACE(head, tail, size) <= 0)
832 + circ_buf->tail = (tail + 1) & (size - 1);
833 +
834 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
835 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
836 +
837 + circ_buf->head = (head + 1) & (size - 1);
838 +
839 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
840 +
841 + return 0;
842 +}
843 +
844 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
845 + struct dpa_ptp_ident *src)
846 +{
847 + int ret;
848 +
849 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
850 + return 0;
851 +
852 + if ((dst->netw_prot == src->netw_prot)
853 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
854 + if (dst->seq_id != src->seq_id)
855 + return 0;
856 +
857 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
858 + DPA_PTP_SOURCE_PORT_LENGTH);
859 + if (ret)
860 + return 0;
861 + else
862 + return 1;
863 + }
864 +
865 + return 0;
866 +}
867 +
868 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
869 + struct dpa_ptp_ident *ident,
870 + struct dpa_ptp_time *ts)
871 +{
872 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
873 + int size = ptp_buf->size;
874 + int head, tail, idx;
875 + unsigned long flags;
876 + struct dpa_ptp_data *tmp, *tmp2;
877 + struct dpa_ptp_ident *tmp_ident;
878 +
879 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
880 +
881 + head = circ_buf->head;
882 + tail = idx = circ_buf->tail;
883 +
884 + if (CIRC_CNT(head, tail, size) == 0) {
885 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
886 + return 1;
887 + }
888 +
889 + while (idx != head) {
890 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
891 + tmp_ident = &tmp->ident;
892 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
893 + break;
894 + idx = (idx + 1) & (size - 1);
895 + }
896 +
897 + if (idx == head) {
898 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
899 + return 1;
900 + }
901 +
902 + ts->sec = tmp->ts.sec;
903 + ts->nsec = tmp->ts.nsec;
904 +
905 + if (idx != tail) {
906 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
907 + tail = circ_buf->tail =
908 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
909 + }
910 +
911 + while (CIRC_CNT(idx, tail, size) > 0) {
912 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
913 + idx = (idx - 1) & (size - 1);
914 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
915 + *tmp = *tmp2;
916 + }
917 + }
918 + circ_buf->tail = (tail + 1) & (size - 1);
919 +
920 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
921 +
922 + return 0;
923 +}
924 +
925 +/* Parse the PTP packets
926 + *
927 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
928 + * an IEEE802.3 ethernet frame. This function returns the position of
929 + * the PTP packet or NULL if no PTP found
930 + */
931 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
932 +{
933 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
934 + u8 *ptp_loc = NULL;
935 + u8 msg_type;
936 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
937 + struct iphdr *iph;
938 + struct udphdr *udph;
939 + struct ipv6hdr *ipv6h;
940 +
941 + /* when we can receive S/G frames we need to check the data we want to
942 + * access is in the linear skb buffer
943 + */
944 + if (!pskb_may_pull(skb, access_len))
945 + return NULL;
946 +
947 + *eth_type = *((u16 *)pos);
948 +
949 + /* Check if inner tag is here */
950 + if (*eth_type == ETH_P_8021Q) {
951 + access_len += DPA_VLAN_TAG_LEN;
952 +
953 + if (!pskb_may_pull(skb, access_len))
954 + return NULL;
955 +
956 + pos += DPA_VLAN_TAG_LEN;
957 + *eth_type = *((u16 *)pos);
958 + }
959 +
960 + pos += DPA_ETYPE_LEN;
961 +
962 + switch (*eth_type) {
963 + /* Transport of PTP over Ethernet */
964 + case ETH_P_1588:
965 + ptp_loc = pos;
966 +
967 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
968 + return NULL;
969 +
970 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
971 + if ((msg_type == PTP_MSGTYPE_SYNC)
972 + || (msg_type == PTP_MSGTYPE_DELREQ)
973 + || (msg_type == PTP_MSGTYPE_PDELREQ)
974 + || (msg_type == PTP_MSGTYPE_PDELRESP))
975 + return ptp_loc;
976 + break;
977 + /* Transport of PTP over IPv4 */
978 + case ETH_P_IP:
979 + iph = (struct iphdr *)pos;
980 + access_len += sizeof(struct iphdr);
981 +
982 + if (!pskb_may_pull(skb, access_len))
983 + return NULL;
984 +
985 + if (ntohs(iph->protocol) != IPPROTO_UDP)
986 + return NULL;
987 +
988 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
989 + sizeof(struct udphdr);
990 +
991 + if (!pskb_may_pull(skb, access_len))
992 + return NULL;
993 +
994 + pos += iph->ihl * 4;
995 + udph = (struct udphdr *)pos;
996 + if (ntohs(udph->dest) != 319)
997 + return NULL;
998 + ptp_loc = pos + sizeof(struct udphdr);
999 + break;
1000 + /* Transport of PTP over IPv6 */
1001 + case ETH_P_IPV6:
1002 + ipv6h = (struct ipv6hdr *)pos;
1003 +
1004 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
1005 +
1006 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
1007 + return NULL;
1008 +
1009 + pos += sizeof(struct ipv6hdr);
1010 + udph = (struct udphdr *)pos;
1011 + if (ntohs(udph->dest) != 319)
1012 + return NULL;
1013 + ptp_loc = pos + sizeof(struct udphdr);
1014 + break;
1015 + default:
1016 + break;
1017 + }
1018 +
1019 + return ptp_loc;
1020 +}
1021 +
1022 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
1023 + struct sk_buff *skb, void *data, enum port_type rx_tx,
1024 + struct dpa_ptp_data *ptp_data)
1025 +{
1026 + u64 nsec;
1027 + u32 mod;
1028 + u8 *ptp_loc;
1029 + u16 eth_type;
1030 +
1031 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
1032 + if (!ptp_loc)
1033 + return -EINVAL;
1034 +
1035 + switch (eth_type) {
1036 + case ETH_P_IP:
1037 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
1038 + break;
1039 + case ETH_P_IPV6:
1040 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
1041 + break;
1042 + case ETH_P_1588:
1043 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
1044 + break;
1045 + default:
1046 + return -EINVAL;
1047 + }
1048 +
1049 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
1050 + return -EINVAL;
1051 +
1052 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
1053 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
1054 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
1055 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
1056 + DPA_PTP_SOURCE_PORT_LENGTH);
1057 +
1058 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
1059 + mod = do_div(nsec, NANOSEC_PER_SECOND);
1060 + ptp_data->ts.sec = nsec;
1061 + ptp_data->ts.nsec = mod;
1062 +
1063 + return 0;
1064 +}
1065 +
1066 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1067 + struct sk_buff *skb, void *data)
1068 +{
1069 + struct dpa_ptp_tsu *tsu = priv->tsu;
1070 + struct dpa_ptp_data ptp_tx_data;
1071 +
1072 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
1073 + return;
1074 +
1075 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
1076 +}
1077 +
1078 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1079 + struct sk_buff *skb, void *data)
1080 +{
1081 + struct dpa_ptp_tsu *tsu = priv->tsu;
1082 + struct dpa_ptp_data ptp_rx_data;
1083 +
1084 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
1085 + return;
1086 +
1087 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
1088 +}
1089 +
1090 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1091 + struct dpa_ptp_ident *ident,
1092 + struct dpa_ptp_time *ts)
1093 +{
1094 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1095 + struct dpa_ptp_time tmp;
1096 + int flag;
1097 +
1098 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
1099 + if (!flag) {
1100 + ts->sec = tmp.sec;
1101 + ts->nsec = tmp.nsec;
1102 + return 0;
1103 + }
1104 +
1105 + return -1;
1106 +}
1107 +
1108 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1109 + struct dpa_ptp_ident *ident,
1110 + struct dpa_ptp_time *ts)
1111 +{
1112 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1113 + struct dpa_ptp_time tmp;
1114 + int flag;
1115 +
1116 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
1117 + if (!flag) {
1118 + ts->sec = tmp.sec;
1119 + ts->nsec = tmp.nsec;
1120 + return 0;
1121 + }
1122 +
1123 + return -1;
1124 +}
1125 +
1126 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
1127 + struct dpa_ptp_time *cnt_time)
1128 +{
1129 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1130 + u64 tmp, fiper;
1131 +
1132 + if (mac_dev->fm_rtc_disable)
1133 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
1134 +
1135 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
1136 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1137 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
1138 + if (mac_dev->fm_rtc_set_alarm)
1139 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
1140 + 0, tmp);
1141 + if (mac_dev->fm_rtc_set_fiper)
1142 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
1143 + 0, fiper);
1144 +
1145 + if (mac_dev->fm_rtc_enable)
1146 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
1147 +}
1148 +
1149 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
1150 + struct dpa_ptp_time *curr_time)
1151 +{
1152 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1153 + u64 tmp;
1154 + u32 mod;
1155 +
1156 + if (mac_dev->fm_rtc_get_cnt)
1157 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1158 + &tmp);
1159 +
1160 + mod = do_div(tmp, NANOSEC_PER_SECOND);
1161 + curr_time->sec = (u32)tmp;
1162 + curr_time->nsec = mod;
1163 +}
1164 +
1165 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
1166 + struct dpa_ptp_time *cnt_time)
1167 +{
1168 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1169 + u64 tmp;
1170 +
1171 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1172 +
1173 + if (mac_dev->fm_rtc_set_cnt)
1174 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1175 + tmp);
1176 +
1177 + /* Restart fiper two seconds later */
1178 + cnt_time->sec += 2;
1179 + cnt_time->nsec = 0;
1180 + dpa_set_fiper_alarm(tsu, cnt_time);
1181 +}
1182 +
1183 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
1184 +{
1185 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1186 + u32 drift;
1187 +
1188 + if (mac_dev->fm_rtc_get_drift)
1189 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1190 + &drift);
1191 +
1192 + *addend = drift;
1193 +}
1194 +
1195 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
1196 +{
1197 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1198 +
1199 + if (mac_dev->fm_rtc_set_drift)
1200 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1201 + addend);
1202 +}
1203 +
1204 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
1205 +{
1206 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1207 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1208 +}
1209 +
1210 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
1211 +{
1212 + struct dpa_priv_s *priv = netdev_priv(dev);
1213 + struct dpa_ptp_tsu *tsu = priv->tsu;
1214 + struct mac_device *mac_dev = priv->mac_dev;
1215 + struct dpa_ptp_data ptp_data;
1216 + struct dpa_ptp_data *ptp_data_user;
1217 + struct dpa_ptp_time act_time;
1218 + u32 addend;
1219 + int retval = 0;
1220 +
1221 + if (!tsu || !tsu->valid)
1222 + return -ENODEV;
1223 +
1224 + switch (cmd) {
1225 + case PTP_ENBL_TXTS_IOCTL:
1226 + tsu->hwts_tx_en_ioctl = 1;
1227 + if (mac_dev->fm_rtc_enable)
1228 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
1229 + if (mac_dev->ptp_enable)
1230 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
1231 + break;
1232 + case PTP_DSBL_TXTS_IOCTL:
1233 + tsu->hwts_tx_en_ioctl = 0;
1234 + if (mac_dev->fm_rtc_disable)
1235 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
1236 + if (mac_dev->ptp_disable)
1237 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
1238 + break;
1239 + case PTP_ENBL_RXTS_IOCTL:
1240 + tsu->hwts_rx_en_ioctl = 1;
1241 + break;
1242 + case PTP_DSBL_RXTS_IOCTL:
1243 + tsu->hwts_rx_en_ioctl = 0;
1244 + break;
1245 + case PTP_GET_RX_TIMESTAMP:
1246 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1247 + if (copy_from_user(&ptp_data.ident,
1248 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1249 + return -EINVAL;
1250 +
1251 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1252 + return -EAGAIN;
1253 +
1254 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1255 + &ptp_data.ts, sizeof(ptp_data.ts)))
1256 + return -EFAULT;
1257 + break;
1258 + case PTP_GET_TX_TIMESTAMP:
1259 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1260 + if (copy_from_user(&ptp_data.ident,
1261 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1262 + return -EINVAL;
1263 +
1264 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1265 + return -EAGAIN;
1266 +
1267 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1268 + &ptp_data.ts, sizeof(ptp_data.ts)))
1269 + return -EFAULT;
1270 + break;
1271 + case PTP_GET_TIME:
1272 + dpa_get_curr_cnt(tsu, &act_time);
1273 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
1274 + return -EFAULT;
1275 + break;
1276 + case PTP_SET_TIME:
1277 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1278 + return -EINVAL;
1279 + dpa_set_1588cnt(tsu, &act_time);
1280 + break;
1281 + case PTP_GET_ADJ:
1282 + dpa_get_drift(tsu, &addend);
1283 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
1284 + return -EFAULT;
1285 + break;
1286 + case PTP_SET_ADJ:
1287 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
1288 + return -EINVAL;
1289 + dpa_set_drift(tsu, addend);
1290 + break;
1291 + case PTP_SET_FIPER_ALARM:
1292 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1293 + return -EINVAL;
1294 + dpa_set_fiper_alarm(tsu, &act_time);
1295 + break;
1296 + case PTP_CLEANUP_TS:
1297 + dpa_flush_timestamp(tsu);
1298 + break;
1299 + default:
1300 + return -EINVAL;
1301 + }
1302 +
1303 + return retval;
1304 +}
1305 +
1306 +int dpa_ptp_init(struct dpa_priv_s *priv)
1307 +{
1308 + struct dpa_ptp_tsu *tsu;
1309 +
1310 + /* Allocate memory for PTP structure */
1311 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
1312 + if (!tsu)
1313 + return -ENOMEM;
1314 +
1315 + tsu->valid = TRUE;
1316 + tsu->dpa_priv = priv;
1317 +
1318 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1319 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1320 +
1321 + priv->tsu = tsu;
1322 +
1323 + return 0;
1324 +}
1325 +EXPORT_SYMBOL(dpa_ptp_init);
1326 +
1327 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
1328 +{
1329 + struct dpa_ptp_tsu *tsu = priv->tsu;
1330 +
1331 + tsu->valid = FALSE;
1332 + vfree(tsu->rx_timestamps.circ_buf.buf);
1333 + vfree(tsu->tx_timestamps.circ_buf.buf);
1334 +
1335 + kfree(tsu);
1336 +}
1337 +EXPORT_SYMBOL(dpa_ptp_cleanup);
1338 --- /dev/null
1339 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1340 @@ -0,0 +1,138 @@
1341 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
1342 + *
1343 + * This program is free software; you can redistribute it and/or modify
1344 + * it under the terms of the GNU General Public License as published by
1345 + * the Free Software Foundation; either version 2 of the License, or
1346 + * (at your option) any later version.
1347 + *
1348 + * This program is distributed in the hope that it will be useful,
1349 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1350 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1351 + * GNU General Public License for more details.
1352 + *
1353 + * You should have received a copy of the GNU General Public License along
1354 + * with this program; if not, write to the Free Software Foundation, Inc.,
1355 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1356 + *
1357 + */
1358 +#ifndef __DPAA_1588_H__
1359 +#define __DPAA_1588_H__
1360 +
1361 +#include <linux/netdevice.h>
1362 +#include <linux/etherdevice.h>
1363 +#include <linux/circ_buf.h>
1364 +#include <linux/fsl_qman.h>
1365 +
1366 +#define DEFAULT_PTP_RX_BUF_SZ 256
1367 +#define DEFAULT_PTP_TX_BUF_SZ 256
1368 +
1369 +/* 1588 private ioctl calls */
1370 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
1371 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
1372 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
1373 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
1374 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
1375 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
1376 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
1377 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
1378 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
1379 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
1380 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
1381 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
1382 +
1383 +/* PTP V2 message type */
1384 +enum {
1385 + PTP_MSGTYPE_SYNC = 0x0,
1386 + PTP_MSGTYPE_DELREQ = 0x1,
1387 + PTP_MSGTYPE_PDELREQ = 0x2,
1388 + PTP_MSGTYPE_PDELRESP = 0x3,
1389 + PTP_MSGTYPE_FLWUP = 0x8,
1390 + PTP_MSGTYPE_DELRESP = 0x9,
1391 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
1392 + PTP_MSGTYPE_ANNOUNCE = 0xB,
1393 + PTP_MSGTYPE_SGNLNG = 0xC,
1394 + PTP_MSGTYPE_MNGMNT = 0xD,
1395 +};
1396 +
1397 +/* Byte offset of data in the PTP V2 headers */
1398 +#define PTP_OFFS_MSG_TYPE 0
1399 +#define PTP_OFFS_VER_PTP 1
1400 +#define PTP_OFFS_MSG_LEN 2
1401 +#define PTP_OFFS_DOM_NMB 4
1402 +#define PTP_OFFS_FLAGS 6
1403 +#define PTP_OFFS_CORFIELD 8
1404 +#define PTP_OFFS_SRCPRTID 20
1405 +#define PTP_OFFS_SEQ_ID 30
1406 +#define PTP_OFFS_CTRL 32
1407 +#define PTP_OFFS_LOGMEAN 33
1408 +
1409 +#define PTP_IP_OFFS 14
1410 +#define PTP_UDP_OFFS 34
1411 +#define PTP_HEADER_OFFS 42
1412 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
1413 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
1414 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
1415 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
1416 +
1417 +/* 1588-2008 network protocol enumeration values */
1418 +#define DPA_PTP_PROT_IPV4 1
1419 +#define DPA_PTP_PROT_IPV6 2
1420 +#define DPA_PTP_PROT_802_3 3
1421 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
1422 +
1423 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
1424 +#define DPA_PTP_HEADER_SZE 34
1425 +#define DPA_ETYPE_LEN 2
1426 +#define DPA_VLAN_TAG_LEN 4
1427 +#define NANOSEC_PER_SECOND 1000000000
1428 +
1429 +/* The threshold between the current found one and the oldest one */
1430 +#define TS_ACCUMULATION_THRESHOLD 50
1431 +
1432 +/* Struct needed to identify a timestamp */
1433 +struct dpa_ptp_ident {
1434 + u8 version;
1435 + u8 msg_type;
1436 + u16 netw_prot;
1437 + u16 seq_id;
1438 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
1439 +};
1440 +
1441 +/* Timestamp format in 1588-2008 */
1442 +struct dpa_ptp_time {
1443 + u64 sec; /* just 48 bit used */
1444 + u32 nsec;
1445 +};
1446 +
1447 +/* needed for timestamp data over ioctl */
1448 +struct dpa_ptp_data {
1449 + struct dpa_ptp_ident ident;
1450 + struct dpa_ptp_time ts;
1451 +};
1452 +
1453 +struct dpa_ptp_circ_buf {
1454 + struct circ_buf circ_buf;
1455 + u32 size;
1456 + spinlock_t ptp_lock;
1457 +};
1458 +
1459 +/* PTP TSU control structure */
1460 +struct dpa_ptp_tsu {
1461 + struct dpa_priv_s *dpa_priv;
1462 + bool valid;
1463 + struct dpa_ptp_circ_buf rx_timestamps;
1464 + struct dpa_ptp_circ_buf tx_timestamps;
1465 +
1466 + /* HW timestamping over ioctl enabled flag */
1467 + int hwts_tx_en_ioctl;
1468 + int hwts_rx_en_ioctl;
1469 +};
1470 +
1471 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
1472 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
1473 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1474 + struct sk_buff *skb, void *data);
1475 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1476 + struct sk_buff *skb, void *data);
1477 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
1478 +#endif
1479 --- /dev/null
1480 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1481 @@ -0,0 +1,180 @@
1482 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1483 + *
1484 + * Redistribution and use in source and binary forms, with or without
1485 + * modification, are permitted provided that the following conditions are met:
1486 + * * Redistributions of source code must retain the above copyright
1487 + * notice, this list of conditions and the following disclaimer.
1488 + * * Redistributions in binary form must reproduce the above copyright
1489 + * notice, this list of conditions and the following disclaimer in the
1490 + * documentation and/or other materials provided with the distribution.
1491 + * * Neither the name of Freescale Semiconductor nor the
1492 + * names of its contributors may be used to endorse or promote products
1493 + * derived from this software without specific prior written permission.
1494 + *
1495 + *
1496 + * ALTERNATIVELY, this software may be distributed under the terms of the
1497 + * GNU General Public License ("GPL") as published by the Free Software
1498 + * Foundation, either version 2 of that License or (at your option) any
1499 + * later version.
1500 + *
1501 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1502 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1503 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1504 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1505 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1506 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1507 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1508 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1509 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1510 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1511 + */
1512 +
1513 +#include <linux/module.h>
1514 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
1515 +#include <linux/debugfs.h>
1516 +#include "dpaa_debugfs.h"
1517 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
1518 +
1519 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
1520 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
1521 +
1522 +static struct dentry *dpa_debugfs_root;
1523 +
1524 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
1525 +static ssize_t dpa_loop_write(struct file *f,
1526 + const char __user *buf, size_t count, loff_t *off);
1527 +
1528 +static const struct file_operations dpa_debugfs_lp_fops = {
1529 + .open = dpa_debugfs_loop_open,
1530 + .write = dpa_loop_write,
1531 + .read = seq_read,
1532 + .llseek = seq_lseek,
1533 + .release = single_release,
1534 +};
1535 +
1536 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
1537 +{
1538 + struct dpa_priv_s *priv;
1539 +
1540 + BUG_ON(offset == NULL);
1541 +
1542 + priv = netdev_priv((struct net_device *)file->private);
1543 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
1544 +
1545 + return 0;
1546 +}
1547 +
1548 +static int user_input_convert(const char __user *user_buf, size_t count,
1549 + long *val)
1550 +{
1551 + char buf[12];
1552 +
1553 + if (count > sizeof(buf) - 1)
1554 + return -EINVAL;
1555 + if (copy_from_user(buf, user_buf, count))
1556 + return -EFAULT;
1557 + buf[count] = '\0';
1558 + if (kstrtol(buf, 0, val))
1559 + return -EINVAL;
1560 + return 0;
1561 +}
1562 +
1563 +static ssize_t dpa_loop_write(struct file *f,
1564 + const char __user *buf, size_t count, loff_t *off)
1565 +{
1566 + struct dpa_priv_s *priv;
1567 + struct net_device *netdev;
1568 + struct seq_file *sf;
1569 + int ret;
1570 + long val;
1571 +
1572 + ret = user_input_convert(buf, count, &val);
1573 + if (ret)
1574 + return ret;
1575 +
1576 + sf = (struct seq_file *)f->private_data;
1577 + netdev = (struct net_device *)sf->private;
1578 + priv = netdev_priv(netdev);
1579 +
1580 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
1581 +
1582 + return count;
1583 +}
1584 +
1585 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
1586 +{
1587 + int _errno;
1588 + const struct net_device *net_dev;
1589 +
1590 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
1591 + if (unlikely(_errno < 0)) {
1592 + net_dev = (struct net_device *)inode->i_private;
1593 +
1594 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
1595 + netdev_err(net_dev, "single_open() = %d\n",
1596 + _errno);
1597 + }
1598 +
1599 + return _errno;
1600 +}
1601 +
1602 +
1603 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
1604 +{
1605 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1606 + static int cnt;
1607 + char loop_file_name[100];
1608 +
1609 + if (unlikely(dpa_debugfs_root == NULL)) {
1610 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
1611 + KBUILD_BASENAME".c", __LINE__, __func__,
1612 + "root debugfs missing, possible module ordering issue");
1613 + return -ENOMEM;
1614 + }
1615 +
1616 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
1617 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
1618 + S_IRUGO,
1619 + dpa_debugfs_root,
1620 + net_dev,
1621 + &dpa_debugfs_lp_fops);
1622 + if (unlikely(priv->debugfs_loop_file == NULL)) {
1623 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
1624 + dpa_debugfs_root->d_iname,
1625 + loop_file_name);
1626 +
1627 + return -ENOMEM;
1628 + }
1629 + return 0;
1630 +}
1631 +
1632 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
1633 +{
1634 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1635 +
1636 + debugfs_remove(priv->debugfs_loop_file);
1637 +}
1638 +
1639 +int __init dpa_debugfs_module_init(void)
1640 +{
1641 + int _errno = 0;
1642 +
1643 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
1644 +
1645 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
1646 +
1647 + if (unlikely(dpa_debugfs_root == NULL)) {
1648 + _errno = -ENOMEM;
1649 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
1650 + KBUILD_BASENAME".c", __LINE__, __func__);
1651 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
1652 + DPA_ETH_DEBUGFS_ROOT, _errno);
1653 + }
1654 +
1655 + return _errno;
1656 +}
1657 +
1658 +void __exit dpa_debugfs_module_exit(void)
1659 +{
1660 + debugfs_remove(dpa_debugfs_root);
1661 +}
1662 --- /dev/null
1663 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1664 @@ -0,0 +1,43 @@
1665 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1666 + *
1667 + * Redistribution and use in source and binary forms, with or without
1668 + * modification, are permitted provided that the following conditions are met:
1669 + * * Redistributions of source code must retain the above copyright
1670 + * notice, this list of conditions and the following disclaimer.
1671 + * * Redistributions in binary form must reproduce the above copyright
1672 + * notice, this list of conditions and the following disclaimer in the
1673 + * documentation and/or other materials provided with the distribution.
1674 + * * Neither the name of Freescale Semiconductor nor the
1675 + * names of its contributors may be used to endorse or promote products
1676 + * derived from this software without specific prior written permission.
1677 + *
1678 + *
1679 + * ALTERNATIVELY, this software may be distributed under the terms of the
1680 + * GNU General Public License ("GPL") as published by the Free Software
1681 + * Foundation, either version 2 of that License or (at your option) any
1682 + * later version.
1683 + *
1684 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1685 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1686 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1687 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1688 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1689 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1690 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1691 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1692 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1693 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1694 + */
1695 +
1696 +#ifndef DPAA_DEBUGFS_H_
1697 +#define DPAA_DEBUGFS_H_
1698 +
1699 +#include <linux/netdevice.h>
1700 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
1701 +
1702 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
1703 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
1704 +int __init dpa_debugfs_module_init(void);
1705 +void __exit dpa_debugfs_module_exit(void);
1706 +
1707 +#endif /* DPAA_DEBUGFS_H_ */
1708 --- /dev/null
1709 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1710 @@ -0,0 +1,1213 @@
1711 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1712 + *
1713 + * Redistribution and use in source and binary forms, with or without
1714 + * modification, are permitted provided that the following conditions are met:
1715 + * * Redistributions of source code must retain the above copyright
1716 + * notice, this list of conditions and the following disclaimer.
1717 + * * Redistributions in binary form must reproduce the above copyright
1718 + * notice, this list of conditions and the following disclaimer in the
1719 + * documentation and/or other materials provided with the distribution.
1720 + * * Neither the name of Freescale Semiconductor nor the
1721 + * names of its contributors may be used to endorse or promote products
1722 + * derived from this software without specific prior written permission.
1723 + *
1724 + *
1725 + * ALTERNATIVELY, this software may be distributed under the terms of the
1726 + * GNU General Public License ("GPL") as published by the Free Software
1727 + * Foundation, either version 2 of that License or (at your option) any
1728 + * later version.
1729 + *
1730 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1731 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1732 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1733 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1734 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1735 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1736 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1737 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1738 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1739 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1740 + */
1741 +
1742 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
1743 +#define pr_fmt(fmt) \
1744 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
1745 + KBUILD_BASENAME".c", __LINE__, __func__
1746 +#else
1747 +#define pr_fmt(fmt) \
1748 + KBUILD_MODNAME ": " fmt
1749 +#endif
1750 +
1751 +#include <linux/init.h>
1752 +#include <linux/module.h>
1753 +#include <linux/of_mdio.h>
1754 +#include <linux/of_net.h>
1755 +#include <linux/kthread.h>
1756 +#include <linux/io.h>
1757 +#include <linux/if_arp.h> /* arp_hdr_len() */
1758 +#include <linux/if_vlan.h> /* VLAN_HLEN */
1759 +#include <linux/icmp.h> /* struct icmphdr */
1760 +#include <linux/ip.h> /* struct iphdr */
1761 +#include <linux/ipv6.h> /* struct ipv6hdr */
1762 +#include <linux/udp.h> /* struct udphdr */
1763 +#include <linux/tcp.h> /* struct tcphdr */
1764 +#include <linux/net.h> /* net_ratelimit() */
1765 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
1766 +#include <linux/highmem.h>
1767 +#include <linux/percpu.h>
1768 +#include <linux/dma-mapping.h>
1769 +#include <linux/fsl_bman.h>
1770 +#ifdef CONFIG_SOC_BUS
1771 +#include <linux/sys_soc.h> /* soc_device_match */
1772 +#endif
1773 +
1774 +#include "fsl_fman.h"
1775 +#include "fm_ext.h"
1776 +#include "fm_port_ext.h"
1777 +
1778 +#include "mac.h"
1779 +#include "dpaa_eth.h"
1780 +#include "dpaa_eth_common.h"
1781 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1782 +#include "dpaa_debugfs.h"
1783 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
1784 +
1785 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
1786 + * using trace events only need to #include <trace/events/sched.h>
1787 + */
1788 +#define CREATE_TRACE_POINTS
1789 +#include "dpaa_eth_trace.h"
1790 +
1791 +#define DPA_NAPI_WEIGHT 64
1792 +
1793 +/* Valid checksum indication */
1794 +#define DPA_CSUM_VALID 0xFFFF
1795 +
1796 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
1797 +
1798 +MODULE_LICENSE("Dual BSD/GPL");
1799 +
1800 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
1801 +
1802 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
1803 +
1804 +static uint8_t debug = -1;
1805 +module_param(debug, byte, S_IRUGO);
1806 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
1807 +
1808 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
1809 +static uint16_t tx_timeout = 1000;
1810 +module_param(tx_timeout, ushort, S_IRUGO);
1811 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
1812 +
1813 +static const char rtx[][3] = {
1814 + [RX] = "RX",
1815 + [TX] = "TX"
1816 +};
1817 +
1818 +#ifndef CONFIG_PPC
1819 +bool dpaa_errata_a010022;
1820 +EXPORT_SYMBOL(dpaa_errata_a010022);
1821 +#endif
1822 +
1823 +/* BM */
1824 +
1825 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
1826 +
1827 +static uint8_t dpa_priv_common_bpid;
1828 +
1829 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1830 +struct net_device *dpa_loop_netdevs[20];
1831 +#endif
1832 +
1833 +#ifdef CONFIG_PM
1834 +
1835 +static int dpaa_suspend(struct device *dev)
1836 +{
1837 + struct net_device *net_dev;
1838 + struct dpa_priv_s *priv;
1839 + struct mac_device *mac_dev;
1840 + int err = 0;
1841 +
1842 + net_dev = dev_get_drvdata(dev);
1843 +
1844 + if (net_dev->flags & IFF_UP) {
1845 + priv = netdev_priv(net_dev);
1846 + mac_dev = priv->mac_dev;
1847 +
1848 + if (priv->wol & DPAA_WOL_MAGIC) {
1849 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1850 + priv->mac_dev->get_mac_handle(mac_dev), true);
1851 + if (err) {
1852 + netdev_err(net_dev, "set_wol() = %d\n", err);
1853 + goto set_wol_failed;
1854 + }
1855 + }
1856 +
1857 + err = fm_port_suspend(mac_dev->port_dev[RX]);
1858 + if (err) {
1859 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
1860 + goto rx_port_suspend_failed;
1861 + }
1862 +
1863 + err = fm_port_suspend(mac_dev->port_dev[TX]);
1864 + if (err) {
1865 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
1866 + goto tx_port_suspend_failed;
1867 + }
1868 + }
1869 +
1870 + return 0;
1871 +
1872 +tx_port_suspend_failed:
1873 + fm_port_resume(mac_dev->port_dev[RX]);
1874 +rx_port_suspend_failed:
1875 + if (priv->wol & DPAA_WOL_MAGIC) {
1876 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1877 + priv->mac_dev->get_mac_handle(mac_dev), false);
1878 + }
1879 +set_wol_failed:
1880 + return err;
1881 +}
1882 +
1883 +static int dpaa_resume(struct device *dev)
1884 +{
1885 + struct net_device *net_dev;
1886 + struct dpa_priv_s *priv;
1887 + struct mac_device *mac_dev;
1888 + int err = 0;
1889 +
1890 + net_dev = dev_get_drvdata(dev);
1891 +
1892 + if (net_dev->flags & IFF_UP) {
1893 + priv = netdev_priv(net_dev);
1894 + mac_dev = priv->mac_dev;
1895 +
1896 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
1897 + if (err) {
1898 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
1899 + goto resume_failed;
1900 + }
1901 +
1902 + err = fm_port_resume(mac_dev->port_dev[TX]);
1903 + if (err) {
1904 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
1905 + goto resume_failed;
1906 + }
1907 +
1908 + err = fm_port_resume(mac_dev->port_dev[RX]);
1909 + if (err) {
1910 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
1911 + goto resume_failed;
1912 + }
1913 +
1914 + if (priv->wol & DPAA_WOL_MAGIC) {
1915 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1916 + priv->mac_dev->get_mac_handle(mac_dev), false);
1917 + if (err) {
1918 + netdev_err(net_dev, "set_wol() = %d\n", err);
1919 + goto resume_failed;
1920 + }
1921 + }
1922 + }
1923 +
1924 + return 0;
1925 +
1926 +resume_failed:
1927 + return err;
1928 +}
1929 +
1930 +static const struct dev_pm_ops dpaa_pm_ops = {
1931 + .suspend = dpaa_suspend,
1932 + .resume = dpaa_resume,
1933 +};
1934 +
1935 +#define DPAA_PM_OPS (&dpaa_pm_ops)
1936 +
1937 +#else /* CONFIG_PM */
1938 +
1939 +#define DPAA_PM_OPS NULL
1940 +
1941 +#endif /* CONFIG_PM */
1942 +
1943 +/* Checks whether the checksum field in Parse Results array is valid
1944 + * (equals 0xFFFF) and increments the .cse counter otherwise
1945 + */
1946 +static inline void
1947 +dpa_csum_validation(const struct dpa_priv_s *priv,
1948 + struct dpa_percpu_priv_s *percpu_priv,
1949 + const struct qm_fd *fd)
1950 +{
1951 + dma_addr_t addr = qm_fd_addr(fd);
1952 + struct dpa_bp *dpa_bp = priv->dpa_bp;
1953 + void *frm = phys_to_virt(addr);
1954 + fm_prs_result_t *parse_result;
1955 +
1956 + if (unlikely(!frm))
1957 + return;
1958 +
1959 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
1960 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
1961 +
1962 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
1963 +
1964 + if (parse_result->cksum != DPA_CSUM_VALID)
1965 + percpu_priv->rx_errors.cse++;
1966 +}
1967 +
1968 +static void _dpa_rx_error(struct net_device *net_dev,
1969 + const struct dpa_priv_s *priv,
1970 + struct dpa_percpu_priv_s *percpu_priv,
1971 + const struct qm_fd *fd,
1972 + u32 fqid)
1973 +{
1974 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
1975 + * interference with zero-loss convergence benchmark results.
1976 + */
1977 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
1978 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
1979 + else
1980 + if (netif_msg_hw(priv) && net_ratelimit())
1981 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
1982 + fd->status & FM_FD_STAT_RX_ERRORS);
1983 +#ifdef CONFIG_FSL_DPAA_HOOKS
1984 + if (dpaa_eth_hooks.rx_error &&
1985 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
1986 + /* it's up to the hook to perform resource cleanup */
1987 + return;
1988 +#endif
1989 + percpu_priv->stats.rx_errors++;
1990 +
1991 + if (fd->status & FM_PORT_FRM_ERR_DMA)
1992 + percpu_priv->rx_errors.dme++;
1993 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
1994 + percpu_priv->rx_errors.fpe++;
1995 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
1996 + percpu_priv->rx_errors.fse++;
1997 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
1998 + percpu_priv->rx_errors.phe++;
1999 + if (fd->status & FM_FD_STAT_L4CV)
2000 + dpa_csum_validation(priv, percpu_priv, fd);
2001 +
2002 + dpa_fd_release(net_dev, fd);
2003 +}
2004 +
2005 +static void _dpa_tx_error(struct net_device *net_dev,
2006 + const struct dpa_priv_s *priv,
2007 + struct dpa_percpu_priv_s *percpu_priv,
2008 + const struct qm_fd *fd,
2009 + u32 fqid)
2010 +{
2011 + struct sk_buff *skb;
2012 +
2013 + if (netif_msg_hw(priv) && net_ratelimit())
2014 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2015 + fd->status & FM_FD_STAT_TX_ERRORS);
2016 +#ifdef CONFIG_FSL_DPAA_HOOKS
2017 + if (dpaa_eth_hooks.tx_error &&
2018 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2019 + /* now the hook must ensure proper cleanup */
2020 + return;
2021 +#endif
2022 + percpu_priv->stats.tx_errors++;
2023 +
2024 + /* If we intended the buffers from this frame to go into the bpools
2025 + * when the FMan transmit was done, we need to put it in manually.
2026 + */
2027 + if (fd->bpid != 0xff) {
2028 + dpa_fd_release(net_dev, fd);
2029 + return;
2030 + }
2031 +
2032 + skb = _dpa_cleanup_tx_fd(priv, fd);
2033 + dev_kfree_skb(skb);
2034 +}
2035 +
2036 +/* Helper function to factor out frame validation logic on all Rx paths. Its
2037 + * purpose is to extract from the Parse Results structure information about
2038 + * the integrity of the frame, its checksum, the length of the parsed headers
2039 + * and whether the frame is suitable for GRO.
2040 + *
2041 + * Assumes no parser errors, since any error frame is dropped before this
2042 + * function is called.
2043 + *
2044 + * @skb will have its ip_summed field overwritten;
2045 + * @use_gro will only be written with 0, if the frame is definitely not
2046 + * GRO-able; otherwise, it will be left unchanged;
2047 + * @hdr_size will be written with a safe value, at least the size of the
2048 + * headers' length.
2049 + */
2050 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
2051 + const struct qm_fd *fd,
2052 + struct sk_buff *skb, int *use_gro)
2053 +{
2054 + if (fd->status & FM_FD_STAT_L4CV) {
2055 + /* The parser has run and performed L4 checksum validation.
2056 + * We know there were no parser errors (and implicitly no
2057 + * L4 csum error), otherwise we wouldn't be here.
2058 + */
2059 + skb->ip_summed = CHECKSUM_UNNECESSARY;
2060 +
2061 + /* Don't go through GRO for certain types of traffic that
2062 + * we know are not GRO-able, such as dgram-based protocols.
2063 + * In the worst-case scenarios, such as small-pkt terminating
2064 + * UDP, the extra GRO processing would be overkill.
2065 + *
2066 + * The only protocol the Parser supports that is also GRO-able
2067 + * is currently TCP.
2068 + */
2069 + if (!fm_l4_frame_is_tcp(parse_results))
2070 + *use_gro = 0;
2071 +
2072 + return;
2073 + }
2074 +
2075 + /* We're here because either the parser didn't run or the L4 checksum
2076 + * was not verified. This may include the case of a UDP frame with
2077 + * checksum zero or an L4 proto other than TCP/UDP
2078 + */
2079 + skb->ip_summed = CHECKSUM_NONE;
2080 +
2081 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
2082 + *use_gro = 0;
2083 +}
2084 +
2085 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
2086 +{
2087 + struct dpa_napi_portal *np =
2088 + container_of(napi, struct dpa_napi_portal, napi);
2089 +
2090 + int cleaned = qman_p_poll_dqrr(np->p, budget);
2091 +
2092 + if (cleaned < budget) {
2093 + int tmp;
2094 + napi_complete(napi);
2095 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2096 + DPA_BUG_ON(tmp);
2097 + }
2098 +
2099 + return cleaned;
2100 +}
2101 +EXPORT_SYMBOL(dpaa_eth_poll);
2102 +
2103 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
2104 + const struct dpa_priv_s *priv,
2105 + struct dpa_percpu_priv_s *percpu_priv,
2106 + const struct qm_fd *fd,
2107 + u32 fqid)
2108 +{
2109 + struct sk_buff *skb;
2110 +
2111 + /* do we need the timestamp for the error frames? */
2112 +
2113 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
2114 + if (netif_msg_hw(priv) && net_ratelimit())
2115 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2116 + fd->status & FM_FD_STAT_TX_ERRORS);
2117 +
2118 + percpu_priv->stats.tx_errors++;
2119 + }
2120 +
2121 + /* hopefully we need not get the timestamp before the hook */
2122 +#ifdef CONFIG_FSL_DPAA_HOOKS
2123 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
2124 + fd, fqid) == DPAA_ETH_STOLEN)
2125 + /* it's the hook that must now perform cleanup */
2126 + return;
2127 +#endif
2128 + /* This might not perfectly reflect the reality, if the core dequeuing
2129 + * the Tx confirmation is different from the one that did the enqueue,
2130 + * but at least it'll show up in the total count.
2131 + */
2132 + percpu_priv->tx_confirm++;
2133 +
2134 + skb = _dpa_cleanup_tx_fd(priv, fd);
2135 +
2136 + dev_kfree_skb(skb);
2137 +}
2138 +
2139 +enum qman_cb_dqrr_result
2140 +priv_rx_error_dqrr(struct qman_portal *portal,
2141 + struct qman_fq *fq,
2142 + const struct qm_dqrr_entry *dq)
2143 +{
2144 + struct net_device *net_dev;
2145 + struct dpa_priv_s *priv;
2146 + struct dpa_percpu_priv_s *percpu_priv;
2147 + int *count_ptr;
2148 +
2149 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2150 + priv = netdev_priv(net_dev);
2151 +
2152 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2153 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
2154 +
2155 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2156 + return qman_cb_dqrr_stop;
2157 +
2158 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
2159 + /* Unable to refill the buffer pool due to insufficient
2160 + * system memory. Just release the frame back into the pool,
2161 + * otherwise we'll soon end up with an empty buffer pool.
2162 + */
2163 + dpa_fd_release(net_dev, &dq->fd);
2164 + else
2165 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2166 +
2167 + return qman_cb_dqrr_consume;
2168 +}
2169 +
2170 +
2171 +enum qman_cb_dqrr_result __hot
2172 +priv_rx_default_dqrr(struct qman_portal *portal,
2173 + struct qman_fq *fq,
2174 + const struct qm_dqrr_entry *dq)
2175 +{
2176 + struct net_device *net_dev;
2177 + struct dpa_priv_s *priv;
2178 + struct dpa_percpu_priv_s *percpu_priv;
2179 + int *count_ptr;
2180 + struct dpa_bp *dpa_bp;
2181 +
2182 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2183 + priv = netdev_priv(net_dev);
2184 + dpa_bp = priv->dpa_bp;
2185 +
2186 + /* Trace the Rx fd */
2187 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
2188 +
2189 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
2190 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2191 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
2192 +
2193 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
2194 + return qman_cb_dqrr_stop;
2195 +
2196 + /* Vale of plenty: make sure we didn't run out of buffers */
2197 +
2198 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
2199 + /* Unable to refill the buffer pool due to insufficient
2200 + * system memory. Just release the frame back into the pool,
2201 + * otherwise we'll soon end up with an empty buffer pool.
2202 + */
2203 + dpa_fd_release(net_dev, &dq->fd);
2204 + else
2205 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
2206 + count_ptr);
2207 +
2208 + return qman_cb_dqrr_consume;
2209 +}
2210 +
2211 +enum qman_cb_dqrr_result
2212 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
2213 + struct qman_fq *fq,
2214 + const struct qm_dqrr_entry *dq)
2215 +{
2216 + struct net_device *net_dev;
2217 + struct dpa_priv_s *priv;
2218 + struct dpa_percpu_priv_s *percpu_priv;
2219 +
2220 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2221 + priv = netdev_priv(net_dev);
2222 +
2223 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2224 +
2225 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2226 + return qman_cb_dqrr_stop;
2227 +
2228 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2229 +
2230 + return qman_cb_dqrr_consume;
2231 +}
2232 +
2233 +enum qman_cb_dqrr_result __hot
2234 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
2235 + struct qman_fq *fq,
2236 + const struct qm_dqrr_entry *dq)
2237 +{
2238 + struct net_device *net_dev;
2239 + struct dpa_priv_s *priv;
2240 + struct dpa_percpu_priv_s *percpu_priv;
2241 +
2242 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2243 + priv = netdev_priv(net_dev);
2244 +
2245 + /* Trace the fd */
2246 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
2247 +
2248 + /* Non-migratable context, safe to use raw_cpu_ptr */
2249 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2250 +
2251 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2252 + return qman_cb_dqrr_stop;
2253 +
2254 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2255 +
2256 + return qman_cb_dqrr_consume;
2257 +}
2258 +
2259 +void priv_ern(struct qman_portal *portal,
2260 + struct qman_fq *fq,
2261 + const struct qm_mr_entry *msg)
2262 +{
2263 + struct net_device *net_dev;
2264 + const struct dpa_priv_s *priv;
2265 + struct sk_buff *skb;
2266 + struct dpa_percpu_priv_s *percpu_priv;
2267 + struct qm_fd fd = msg->ern.fd;
2268 +
2269 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2270 + priv = netdev_priv(net_dev);
2271 + /* Non-migratable context, safe to use raw_cpu_ptr */
2272 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2273 +
2274 + percpu_priv->stats.tx_dropped++;
2275 + percpu_priv->stats.tx_fifo_errors++;
2276 + count_ern(percpu_priv, msg);
2277 +
2278 + /* If we intended this buffer to go into the pool
2279 + * when the FM was done, we need to put it in
2280 + * manually.
2281 + */
2282 + if (msg->ern.fd.bpid != 0xff) {
2283 + dpa_fd_release(net_dev, &fd);
2284 + return;
2285 + }
2286 +
2287 + skb = _dpa_cleanup_tx_fd(priv, &fd);
2288 + dev_kfree_skb_any(skb);
2289 +}
2290 +
2291 +const struct dpa_fq_cbs_t private_fq_cbs = {
2292 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
2293 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
2294 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
2295 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
2296 + .egress_ern = { .cb = { .ern = priv_ern } }
2297 +};
2298 +EXPORT_SYMBOL(private_fq_cbs);
2299 +
2300 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
2301 +{
2302 + struct dpa_percpu_priv_s *percpu_priv;
2303 + int i, j;
2304 +
2305 + for_each_possible_cpu(i) {
2306 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2307 +
2308 + for (j = 0; j < qman_portal_max; j++)
2309 + napi_enable(&percpu_priv->np[j].napi);
2310 + }
2311 +}
2312 +
2313 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
2314 +{
2315 + struct dpa_percpu_priv_s *percpu_priv;
2316 + int i, j;
2317 +
2318 + for_each_possible_cpu(i) {
2319 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2320 +
2321 + for (j = 0; j < qman_portal_max; j++)
2322 + napi_disable(&percpu_priv->np[j].napi);
2323 + }
2324 +}
2325 +
2326 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
2327 +{
2328 + int err;
2329 + struct dpa_priv_s *priv;
2330 +
2331 + priv = netdev_priv(net_dev);
2332 +
2333 + dpaa_eth_napi_enable(priv);
2334 +
2335 + err = dpa_start(net_dev);
2336 + if (err < 0)
2337 + dpaa_eth_napi_disable(priv);
2338 +
2339 + return err;
2340 +}
2341 +
2342 +
2343 +
2344 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
2345 +{
2346 + int _errno;
2347 + struct dpa_priv_s *priv;
2348 +
2349 + _errno = dpa_stop(net_dev);
2350 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
2351 + * ingress queues. This is to avoid a race between the current
2352 + * context and ksoftirqd which could leave NAPI disabled while
2353 + * in fact there's still Rx traffic to be processed.
2354 + */
2355 + usleep_range(5000, 10000);
2356 +
2357 + priv = netdev_priv(net_dev);
2358 + dpaa_eth_napi_disable(priv);
2359 +
2360 + return _errno;
2361 +}
2362 +
2363 +#ifdef CONFIG_NET_POLL_CONTROLLER
2364 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
2365 +{
2366 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2367 + struct dpa_percpu_priv_s *percpu_priv =
2368 + raw_cpu_ptr(priv->percpu_priv);
2369 + struct qman_portal *p;
2370 + const struct qman_portal_config *pc;
2371 + struct dpa_napi_portal *np;
2372 +
2373 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
2374 + pc = qman_p_get_portal_config(p);
2375 + np = &percpu_priv->np[pc->index];
2376 +
2377 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
2378 + qman_p_poll_dqrr(np->p, np->napi.weight);
2379 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2380 +}
2381 +#endif
2382 +
2383 +static const struct net_device_ops dpa_private_ops = {
2384 + .ndo_open = dpa_eth_priv_start,
2385 + .ndo_start_xmit = dpa_tx,
2386 + .ndo_stop = dpa_eth_priv_stop,
2387 + .ndo_tx_timeout = dpa_timeout,
2388 + .ndo_get_stats64 = dpa_get_stats64,
2389 + .ndo_set_mac_address = dpa_set_mac_address,
2390 + .ndo_validate_addr = eth_validate_addr,
2391 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2392 + .ndo_select_queue = dpa_select_queue,
2393 +#endif
2394 + .ndo_change_mtu = dpa_change_mtu,
2395 + .ndo_set_rx_mode = dpa_set_rx_mode,
2396 + .ndo_init = dpa_ndo_init,
2397 + .ndo_set_features = dpa_set_features,
2398 + .ndo_fix_features = dpa_fix_features,
2399 + .ndo_do_ioctl = dpa_ioctl,
2400 +#ifdef CONFIG_NET_POLL_CONTROLLER
2401 + .ndo_poll_controller = dpaa_eth_poll_controller,
2402 +#endif
2403 +};
2404 +
2405 +static int dpa_private_napi_add(struct net_device *net_dev)
2406 +{
2407 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2408 + struct dpa_percpu_priv_s *percpu_priv;
2409 + int i, cpu;
2410 +
2411 + for_each_possible_cpu(cpu) {
2412 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2413 +
2414 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
2415 + qman_portal_max * sizeof(struct dpa_napi_portal),
2416 + GFP_KERNEL);
2417 +
2418 + if (unlikely(percpu_priv->np == NULL)) {
2419 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
2420 + return -ENOMEM;
2421 + }
2422 +
2423 + for (i = 0; i < qman_portal_max; i++)
2424 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
2425 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
2426 + }
2427 +
2428 + return 0;
2429 +}
2430 +
2431 +void dpa_private_napi_del(struct net_device *net_dev)
2432 +{
2433 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2434 + struct dpa_percpu_priv_s *percpu_priv;
2435 + int i, cpu;
2436 +
2437 + for_each_possible_cpu(cpu) {
2438 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2439 +
2440 + if (percpu_priv->np) {
2441 + for (i = 0; i < qman_portal_max; i++)
2442 + netif_napi_del(&percpu_priv->np[i].napi);
2443 +
2444 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
2445 + }
2446 + }
2447 +}
2448 +EXPORT_SYMBOL(dpa_private_napi_del);
2449 +
2450 +static int dpa_private_netdev_init(struct net_device *net_dev)
2451 +{
2452 + int i;
2453 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2454 + struct dpa_percpu_priv_s *percpu_priv;
2455 + const uint8_t *mac_addr;
2456 +
2457 + /* Although we access another CPU's private data here
2458 + * we do it at initialization so it is safe
2459 + */
2460 + for_each_possible_cpu(i) {
2461 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2462 + percpu_priv->net_dev = net_dev;
2463 + }
2464 +
2465 + net_dev->netdev_ops = &dpa_private_ops;
2466 + mac_addr = priv->mac_dev->addr;
2467 +
2468 + net_dev->mem_start = priv->mac_dev->res->start;
2469 + net_dev->mem_end = priv->mac_dev->res->end;
2470 +
2471 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2472 + NETIF_F_LLTX);
2473 +
2474 + /* Advertise S/G and HIGHDMA support for private interfaces */
2475 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
2476 + /* Recent kernels enable GSO automatically, if
2477 + * we declare NETIF_F_SG. For conformity, we'll
2478 + * still declare GSO explicitly.
2479 + */
2480 + net_dev->features |= NETIF_F_GSO;
2481 +
2482 + /* Advertise GRO support */
2483 + net_dev->features |= NETIF_F_GRO;
2484 +
2485 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
2486 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
2487 +
2488 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
2489 +}
2490 +
2491 +static struct dpa_bp * __cold
2492 +dpa_priv_bp_probe(struct device *dev)
2493 +{
2494 + struct dpa_bp *dpa_bp;
2495 +
2496 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
2497 + if (unlikely(dpa_bp == NULL)) {
2498 + dev_err(dev, "devm_kzalloc() failed\n");
2499 + return ERR_PTR(-ENOMEM);
2500 + }
2501 +
2502 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
2503 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
2504 +
2505 + dpa_bp->seed_cb = dpa_bp_priv_seed;
2506 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
2507 +
2508 + return dpa_bp;
2509 +}
2510 +
2511 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
2512 + * We won't be sending congestion notifications to FMan; for now, we just use
2513 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
2514 + * before they reach our ingress queues and eat up memory.
2515 + */
2516 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
2517 +{
2518 + struct qm_mcc_initcgr initcgr;
2519 + u32 cs_th;
2520 + int err;
2521 +
2522 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
2523 + if (err < 0) {
2524 + pr_err("Error %d allocating CGR ID\n", err);
2525 + goto out_error;
2526 + }
2527 +
2528 + /* Enable CS TD, but disable Congestion State Change Notifications. */
2529 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
2530 + initcgr.cgr.cscn_en = QM_CGR_EN;
2531 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
2532 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
2533 +
2534 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
2535 + initcgr.cgr.cstd_en = QM_CGR_EN;
2536 +
2537 + /* This is actually a hack, because this CGR will be associated with
2538 + * our affine SWP. However, we'll place our ingress FQs in it.
2539 + */
2540 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
2541 + &initcgr);
2542 + if (err < 0) {
2543 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
2544 + priv->ingress_cgr.cgrid);
2545 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2546 + goto out_error;
2547 + }
2548 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
2549 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
2550 +
2551 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
2552 + * range), but we have no common initialization path between the
2553 + * different variants of the DPAA Eth driver, so we do it here rather
2554 + * than modifying every other variant than "private Eth".
2555 + */
2556 + priv->use_ingress_cgr = true;
2557 +
2558 +out_error:
2559 + return err;
2560 +}
2561 +
2562 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
2563 + size_t count)
2564 +{
2565 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2566 + int i;
2567 +
2568 + if (netif_msg_probe(priv))
2569 + dev_dbg(net_dev->dev.parent,
2570 + "Using private BM buffer pools\n");
2571 +
2572 + priv->bp_count = count;
2573 +
2574 + for (i = 0; i < count; i++) {
2575 + int err;
2576 + err = dpa_bp_alloc(&dpa_bp[i]);
2577 + if (err < 0) {
2578 + dpa_bp_free(priv);
2579 + priv->dpa_bp = NULL;
2580 + return err;
2581 + }
2582 +
2583 + priv->dpa_bp = &dpa_bp[i];
2584 + }
2585 +
2586 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
2587 + return 0;
2588 +}
2589 +
2590 +static const struct of_device_id dpa_match[];
2591 +
2592 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2593 +static int dpa_new_loop_id(void)
2594 +{
2595 + static int if_id;
2596 +
2597 + return if_id++;
2598 +}
2599 +#endif
2600 +
2601 +static int
2602 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
2603 +{
2604 + int err = 0, i, channel;
2605 + struct device *dev;
2606 + struct device_node *dpa_node;
2607 + struct dpa_bp *dpa_bp;
2608 + size_t count = 1;
2609 + struct net_device *net_dev = NULL;
2610 + struct dpa_priv_s *priv = NULL;
2611 + struct dpa_percpu_priv_s *percpu_priv;
2612 + struct fm_port_fqs port_fqs;
2613 + struct dpa_buffer_layout_s *buf_layout = NULL;
2614 + struct mac_device *mac_dev;
2615 +
2616 + dev = &_of_dev->dev;
2617 +
2618 + dpa_node = dev->of_node;
2619 +
2620 + if (!of_device_is_available(dpa_node))
2621 + return -ENODEV;
2622 +
2623 + /* Get the buffer pools assigned to this interface;
2624 + * run only once the default pool probing code
2625 + */
2626 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
2627 + dpa_priv_bp_probe(dev);
2628 + if (IS_ERR(dpa_bp))
2629 + return PTR_ERR(dpa_bp);
2630 +
2631 + /* Allocate this early, so we can store relevant information in
2632 + * the private area (needed by 1588 code in dpa_mac_probe)
2633 + */
2634 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
2635 + if (!net_dev) {
2636 + dev_err(dev, "alloc_etherdev_mq() failed\n");
2637 + goto alloc_etherdev_mq_failed;
2638 + }
2639 +
2640 + /* Do this here, so we can be verbose early */
2641 + SET_NETDEV_DEV(net_dev, dev);
2642 + dev_set_drvdata(dev, net_dev);
2643 +
2644 + priv = netdev_priv(net_dev);
2645 + priv->net_dev = net_dev;
2646 + strcpy(priv->if_type, "private");
2647 +
2648 + priv->msg_enable = netif_msg_init(debug, -1);
2649 +
2650 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2651 + priv->loop_id = dpa_new_loop_id();
2652 + priv->loop_to = -1; /* disabled by default */
2653 + dpa_loop_netdevs[priv->loop_id] = net_dev;
2654 +#endif
2655 +
2656 + mac_dev = dpa_mac_probe(_of_dev);
2657 + if (IS_ERR(mac_dev) || !mac_dev) {
2658 + err = PTR_ERR(mac_dev);
2659 + goto mac_probe_failed;
2660 + }
2661 +
2662 + /* We have physical ports, so we need to establish
2663 + * the buffer layout.
2664 + */
2665 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
2666 + GFP_KERNEL);
2667 + if (!buf_layout) {
2668 + dev_err(dev, "devm_kzalloc() failed\n");
2669 + goto alloc_failed;
2670 + }
2671 + dpa_set_buffers_layout(mac_dev, buf_layout);
2672 +
2673 + /* For private ports, need to compute the size of the default
2674 + * buffer pool, based on FMan port buffer layout;also update
2675 + * the maximum buffer size for private ports if necessary
2676 + */
2677 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
2678 +
2679 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
2680 + /* We only want to use jumbo frame optimization if we actually have
2681 + * L2 MAX FRM set for jumbo frames as well.
2682 + */
2683 +#ifndef CONFIG_PPC
2684 + if (likely(!dpaa_errata_a010022))
2685 +#endif
2686 + if(fm_get_max_frm() < 9600)
2687 + dev_warn(dev,
2688 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
2689 +#endif
2690 +
2691 + INIT_LIST_HEAD(&priv->dpa_fq_list);
2692 +
2693 + memset(&port_fqs, 0, sizeof(port_fqs));
2694 +
2695 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
2696 + if (!err)
2697 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
2698 + &port_fqs, true, TX);
2699 +
2700 + if (err < 0)
2701 + goto fq_probe_failed;
2702 +
2703 + /* bp init */
2704 +
2705 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
2706 +
2707 + if (err < 0)
2708 + goto bp_create_failed;
2709 +
2710 + priv->mac_dev = mac_dev;
2711 +
2712 + channel = dpa_get_channel();
2713 +
2714 + if (channel < 0) {
2715 + err = channel;
2716 + goto get_channel_failed;
2717 + }
2718 +
2719 + priv->channel = (uint16_t)channel;
2720 + dpaa_eth_add_channel(priv->channel);
2721 +
2722 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
2723 +
2724 + /* Create a congestion group for this netdev, with
2725 + * dynamically-allocated CGR ID.
2726 + * Must be executed after probing the MAC, but before
2727 + * assigning the egress FQs to the CGRs.
2728 + */
2729 + err = dpaa_eth_cgr_init(priv);
2730 + if (err < 0) {
2731 + dev_err(dev, "Error initializing CGR\n");
2732 + goto tx_cgr_init_failed;
2733 + }
2734 + err = dpaa_eth_priv_ingress_cgr_init(priv);
2735 + if (err < 0) {
2736 + dev_err(dev, "Error initializing ingress CGR\n");
2737 + goto rx_cgr_init_failed;
2738 + }
2739 +
2740 + /* Add the FQs to the interface, and make them active */
2741 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
2742 + if (err < 0)
2743 + goto fq_alloc_failed;
2744 +
2745 + priv->buf_layout = buf_layout;
2746 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
2747 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
2748 +
2749 + /* All real interfaces need their ports initialized */
2750 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
2751 + buf_layout, dev);
2752 +
2753 +#ifdef CONFIG_FMAN_PFC
2754 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
2755 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
2756 + mac_dev->port_dev[TX], i, i);
2757 + if (unlikely(err != 0)) {
2758 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
2759 + goto pfc_mapping_failed;
2760 + }
2761 + }
2762 +#endif
2763 +
2764 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
2765 +
2766 + if (priv->percpu_priv == NULL) {
2767 + dev_err(dev, "devm_alloc_percpu() failed\n");
2768 + err = -ENOMEM;
2769 + goto alloc_percpu_failed;
2770 + }
2771 + for_each_possible_cpu(i) {
2772 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2773 + memset(percpu_priv, 0, sizeof(*percpu_priv));
2774 + }
2775 +
2776 + /* Initialize NAPI */
2777 + err = dpa_private_napi_add(net_dev);
2778 +
2779 + if (err < 0)
2780 + goto napi_add_failed;
2781 +
2782 + err = dpa_private_netdev_init(net_dev);
2783 +
2784 + if (err < 0)
2785 + goto netdev_init_failed;
2786 +
2787 + dpaa_eth_sysfs_init(&net_dev->dev);
2788 +
2789 +#ifdef CONFIG_PM
2790 + device_set_wakeup_capable(dev, true);
2791 +#endif
2792 +
2793 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
2794 +
2795 + return 0;
2796 +
2797 +netdev_init_failed:
2798 +napi_add_failed:
2799 + dpa_private_napi_del(net_dev);
2800 +alloc_percpu_failed:
2801 +#ifdef CONFIG_FMAN_PFC
2802 +pfc_mapping_failed:
2803 +#endif
2804 + dpa_fq_free(dev, &priv->dpa_fq_list);
2805 +fq_alloc_failed:
2806 + qman_delete_cgr_safe(&priv->ingress_cgr);
2807 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2808 +rx_cgr_init_failed:
2809 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
2810 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
2811 +tx_cgr_init_failed:
2812 +get_channel_failed:
2813 + dpa_bp_free(priv);
2814 +bp_create_failed:
2815 +fq_probe_failed:
2816 +alloc_failed:
2817 +mac_probe_failed:
2818 + dev_set_drvdata(dev, NULL);
2819 + free_netdev(net_dev);
2820 +alloc_etherdev_mq_failed:
2821 + if (atomic_read(&dpa_bp->refs) == 0)
2822 + devm_kfree(dev, dpa_bp);
2823 +
2824 + return err;
2825 +}
2826 +
2827 +static const struct of_device_id dpa_match[] = {
2828 + {
2829 + .compatible = "fsl,dpa-ethernet"
2830 + },
2831 + {}
2832 +};
2833 +MODULE_DEVICE_TABLE(of, dpa_match);
2834 +
2835 +static struct platform_driver dpa_driver = {
2836 + .driver = {
2837 + .name = KBUILD_MODNAME,
2838 + .of_match_table = dpa_match,
2839 + .owner = THIS_MODULE,
2840 + .pm = DPAA_PM_OPS,
2841 + },
2842 + .probe = dpaa_eth_priv_probe,
2843 + .remove = dpa_remove
2844 +};
2845 +
2846 +#ifndef CONFIG_PPC
2847 +static bool __init __cold soc_has_errata_a010022(void)
2848 +{
2849 +#ifdef CONFIG_SOC_BUS
2850 + const struct soc_device_attribute soc_msi_matches[] = {
2851 + { .family = "QorIQ LS1043A",
2852 + .data = NULL },
2853 + { },
2854 + };
2855 +
2856 + if (soc_device_match(soc_msi_matches))
2857 + return true;
2858 +
2859 + return false;
2860 +#else
2861 + return true; /* cannot identify SoC */
2862 +#endif
2863 +}
2864 +#endif
2865 +
2866 +static int __init __cold dpa_load(void)
2867 +{
2868 + int _errno;
2869 +
2870 + pr_info(DPA_DESCRIPTION "\n");
2871 +
2872 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2873 + dpa_debugfs_module_init();
2874 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2875 +
2876 + /* initialise dpaa_eth mirror values */
2877 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
2878 + dpa_max_frm = fm_get_max_frm();
2879 + dpa_num_cpus = num_possible_cpus();
2880 +
2881 +#ifndef CONFIG_PPC
2882 + /* Detect if the current SoC requires the 4K alignment workaround */
2883 + dpaa_errata_a010022 = soc_has_errata_a010022();
2884 +#endif
2885 +
2886 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2887 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
2888 +#endif
2889 +
2890 + _errno = platform_driver_register(&dpa_driver);
2891 + if (unlikely(_errno < 0)) {
2892 + pr_err(KBUILD_MODNAME
2893 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
2894 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
2895 + }
2896 +
2897 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2898 + KBUILD_BASENAME".c", __func__);
2899 +
2900 + return _errno;
2901 +}
2902 +module_init(dpa_load);
2903 +
2904 +static void __exit __cold dpa_unload(void)
2905 +{
2906 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
2907 + KBUILD_BASENAME".c", __func__);
2908 +
2909 + platform_driver_unregister(&dpa_driver);
2910 +
2911 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2912 + dpa_debugfs_module_exit();
2913 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2914 +
2915 + /* Only one channel is used and needs to be relased after all
2916 + * interfaces are removed
2917 + */
2918 + dpa_release_channel();
2919 +
2920 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2921 + KBUILD_BASENAME".c", __func__);
2922 +}
2923 +module_exit(dpa_unload);
2924 --- /dev/null
2925 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2926 @@ -0,0 +1,698 @@
2927 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
2928 + *
2929 + * Redistribution and use in source and binary forms, with or without
2930 + * modification, are permitted provided that the following conditions are met:
2931 + * * Redistributions of source code must retain the above copyright
2932 + * notice, this list of conditions and the following disclaimer.
2933 + * * Redistributions in binary form must reproduce the above copyright
2934 + * notice, this list of conditions and the following disclaimer in the
2935 + * documentation and/or other materials provided with the distribution.
2936 + * * Neither the name of Freescale Semiconductor nor the
2937 + * names of its contributors may be used to endorse or promote products
2938 + * derived from this software without specific prior written permission.
2939 + *
2940 + *
2941 + * ALTERNATIVELY, this software may be distributed under the terms of the
2942 + * GNU General Public License ("GPL") as published by the Free Software
2943 + * Foundation, either version 2 of that License or (at your option) any
2944 + * later version.
2945 + *
2946 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2947 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2948 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2949 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2950 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2951 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2952 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2953 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2954 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2955 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2956 + */
2957 +
2958 +#ifndef __DPA_H
2959 +#define __DPA_H
2960 +
2961 +#include <linux/netdevice.h>
2962 +#include <linux/fsl_qman.h> /* struct qman_fq */
2963 +
2964 +#include "fm_ext.h"
2965 +#include "dpaa_eth_trace.h"
2966 +
2967 +extern int dpa_rx_extra_headroom;
2968 +extern int dpa_max_frm;
2969 +extern int dpa_num_cpus;
2970 +
2971 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
2972 +#define dpa_get_max_frm() dpa_max_frm
2973 +
2974 +#define dpa_get_max_mtu() \
2975 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
2976 +
2977 +#define __hot
2978 +
2979 +/* Simple enum of FQ types - used for array indexing */
2980 +enum port_type {RX, TX};
2981 +
2982 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
2983 +struct dpa_buffer_layout_s {
2984 + uint16_t priv_data_size;
2985 + bool parse_results;
2986 + bool time_stamp;
2987 + bool hash_results;
2988 + uint8_t manip_extra_space;
2989 + uint16_t data_align;
2990 +};
2991 +
2992 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
2993 +#define DPA_BUG_ON(cond) BUG_ON(cond)
2994 +#else
2995 +#define DPA_BUG_ON(cond)
2996 +#endif
2997 +
2998 +#define DPA_TX_PRIV_DATA_SIZE 16
2999 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
3000 +#define DPA_TIME_STAMP_SIZE 8
3001 +#define DPA_HASH_RESULTS_SIZE 8
3002 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
3003 + dpa_get_rx_extra_headroom())
3004 +
3005 +#define FM_FD_STAT_RX_ERRORS \
3006 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
3007 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
3008 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
3009 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
3010 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
3011 +
3012 +#define FM_FD_STAT_TX_ERRORS \
3013 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
3014 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
3015 +
3016 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
3017 +/* The raw buffer size must be cacheline aligned.
3018 + * Normally we use 2K buffers.
3019 + */
3020 +#define DPA_BP_RAW_SIZE 2048
3021 +#else
3022 +/* For jumbo frame optimizations, use buffers large enough to accommodate
3023 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
3024 + * space to account for further alignments.
3025 + */
3026 +#define DPA_MAX_FRM_SIZE 9600
3027 +#ifdef CONFIG_PPC
3028 +#define DPA_BP_RAW_SIZE \
3029 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3030 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
3031 +#else /* CONFIG_PPC */
3032 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
3033 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3034 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
3035 +#endif /* CONFIG_PPC */
3036 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
3037 +
3038 +/* This is what FMan is ever allowed to use.
3039 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
3040 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
3041 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
3042 + * half-page-aligned buffers (can we?), so we reserve some more space
3043 + * for start-of-buffer alignment.
3044 + */
3045 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
3046 + SMP_CACHE_BYTES)
3047 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
3048 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
3049 +
3050 +/* Maximum size of a buffer for which recycling is allowed.
3051 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
3052 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
3053 + * that skbs allocated by us will not fail to be recycled due to their size.
3054 + *
3055 + * For a requested size, the kernel allocator provides the next power of two
3056 + * sized block, which the stack will use as is, regardless of the actual size
3057 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
3058 + * supported frame size), set the recycling upper limit to 16K.
3059 + */
3060 +#define DPA_RECYCLE_MAX_SIZE 16384
3061 +
3062 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3063 +/*TODO: temporary for fman pcd testing */
3064 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
3065 +#endif
3066 +
3067 +#define DPAA_ETH_FQ_DELTA 0x10000
3068 +
3069 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
3070 + (((device_addr) & 0x1fffff) >> 6)
3071 +
3072 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
3073 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
3074 +
3075 +/* Largest value that the FQD's OAL field can hold.
3076 + * This is DPAA-1.x specific.
3077 + * TODO: This rather belongs in fsl_qman.h
3078 + */
3079 +#define FSL_QMAN_MAX_OAL 127
3080 +
3081 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
3082 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
3083 +
3084 +/* Default alignment for start of data in an Rx FD */
3085 +#define DPA_FD_DATA_ALIGNMENT 16
3086 +
3087 +/* Values for the L3R field of the FM Parse Results
3088 + */
3089 +/* L3 Type field: First IP Present IPv4 */
3090 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
3091 +/* L3 Type field: First IP Present IPv6 */
3092 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
3093 +
3094 +/* Values for the L4R field of the FM Parse Results
3095 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
3096 + */
3097 +/* L4 Type field: UDP */
3098 +#define FM_L4_PARSE_RESULT_UDP 0x40
3099 +/* L4 Type field: TCP */
3100 +#define FM_L4_PARSE_RESULT_TCP 0x20
3101 +/* FD status field indicating whether the FM Parser has attempted to validate
3102 + * the L4 csum of the frame.
3103 + * Note that having this bit set doesn't necessarily imply that the checksum
3104 + * is valid. One would have to check the parse results to find that out.
3105 + */
3106 +#define FM_FD_STAT_L4CV 0x00000004
3107 +
3108 +
3109 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
3110 +
3111 +/* Check if the parsed frame was found to be a TCP segment.
3112 + *
3113 + * @parse_result_ptr must be of type (fm_prs_result_t *).
3114 + */
3115 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
3116 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
3117 +
3118 +/* number of Tx queues to FMan */
3119 +#ifdef CONFIG_FMAN_PFC
3120 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
3121 +#else
3122 +#define DPAA_ETH_TX_QUEUES NR_CPUS
3123 +#endif
3124 +
3125 +#define DPAA_ETH_RX_QUEUES 128
3126 +
3127 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
3128 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
3129 + * was allocated by ourselves, respectively by the stack. In the former case,
3130 + * we could store the skb at negative offset; in the latter case, we can't,
3131 + * so we'll use 0 as offset.
3132 + *
3133 + * NB: @off is an offset from a (struct sk_buff **) pointer!
3134 + */
3135 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
3136 +{ \
3137 + skbh = (struct sk_buff **)addr; \
3138 + *(skbh + (off)) = skb; \
3139 +}
3140 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
3141 +{ \
3142 + skbh = (struct sk_buff **)addr; \
3143 + skb = *(skbh + (off)); \
3144 +}
3145 +
3146 +#ifdef CONFIG_PM
3147 +/* Magic Packet wakeup */
3148 +#define DPAA_WOL_MAGIC 0x00000001
3149 +#endif
3150 +
3151 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3152 +struct pcd_range {
3153 + uint32_t base;
3154 + uint32_t count;
3155 +};
3156 +#endif
3157 +
3158 +/* More detailed FQ types - used for fine-grained WQ assignments */
3159 +enum dpa_fq_type {
3160 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
3161 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
3162 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
3163 + FQ_TYPE_TX, /* "Real" Tx FQs */
3164 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
3165 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
3166 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
3167 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
3168 +};
3169 +
3170 +struct dpa_fq {
3171 + struct qman_fq fq_base;
3172 + struct list_head list;
3173 + struct net_device *net_dev;
3174 + bool init;
3175 + uint32_t fqid;
3176 + uint32_t flags;
3177 + uint16_t channel;
3178 + uint8_t wq;
3179 + enum dpa_fq_type fq_type;
3180 +};
3181 +
3182 +struct dpa_fq_cbs_t {
3183 + struct qman_fq rx_defq;
3184 + struct qman_fq tx_defq;
3185 + struct qman_fq rx_errq;
3186 + struct qman_fq tx_errq;
3187 + struct qman_fq egress_ern;
3188 +};
3189 +
3190 +struct fqid_cell {
3191 + uint32_t start;
3192 + uint32_t count;
3193 +};
3194 +
3195 +struct dpa_bp {
3196 + struct bman_pool *pool;
3197 + uint8_t bpid;
3198 + struct device *dev;
3199 + union {
3200 + /* The buffer pools used for the private ports are initialized
3201 + * with target_count buffers for each CPU; at runtime the
3202 + * number of buffers per CPU is constantly brought back to this
3203 + * level
3204 + */
3205 + int target_count;
3206 + /* The configured value for the number of buffers in the pool,
3207 + * used for shared port buffer pools
3208 + */
3209 + int config_count;
3210 + };
3211 + size_t size;
3212 + bool seed_pool;
3213 + /* physical address of the contiguous memory used by the pool to store
3214 + * the buffers
3215 + */
3216 + dma_addr_t paddr;
3217 + /* virtual address of the contiguous memory used by the pool to store
3218 + * the buffers
3219 + */
3220 + void __iomem *vaddr;
3221 + /* current number of buffers in the bpool alloted to this CPU */
3222 + int __percpu *percpu_count;
3223 + atomic_t refs;
3224 + /* some bpools need to be seeded before use by this cb */
3225 + int (*seed_cb)(struct dpa_bp *);
3226 + /* some bpools need to be emptied before freeing; this cb is used
3227 + * for freeing of individual buffers taken from the pool
3228 + */
3229 + void (*free_buf_cb)(void *addr);
3230 +};
3231 +
3232 +struct dpa_rx_errors {
3233 + u64 dme; /* DMA Error */
3234 + u64 fpe; /* Frame Physical Error */
3235 + u64 fse; /* Frame Size Error */
3236 + u64 phe; /* Header Error */
3237 + u64 cse; /* Checksum Validation Error */
3238 +};
3239 +
3240 +/* Counters for QMan ERN frames - one counter per rejection code */
3241 +struct dpa_ern_cnt {
3242 + u64 cg_tdrop; /* Congestion group taildrop */
3243 + u64 wred; /* WRED congestion */
3244 + u64 err_cond; /* Error condition */
3245 + u64 early_window; /* Order restoration, frame too early */
3246 + u64 late_window; /* Order restoration, frame too late */
3247 + u64 fq_tdrop; /* FQ taildrop */
3248 + u64 fq_retired; /* FQ is retired */
3249 + u64 orp_zero; /* ORP disabled */
3250 +};
3251 +
3252 +struct dpa_napi_portal {
3253 + struct napi_struct napi;
3254 + struct qman_portal *p;
3255 +};
3256 +
3257 +struct dpa_percpu_priv_s {
3258 + struct net_device *net_dev;
3259 + struct dpa_napi_portal *np;
3260 + u64 in_interrupt;
3261 + u64 tx_returned;
3262 + u64 tx_confirm;
3263 + /* fragmented (non-linear) skbuffs received from the stack */
3264 + u64 tx_frag_skbuffs;
3265 + /* number of S/G frames received */
3266 + u64 rx_sg;
3267 +
3268 + struct rtnl_link_stats64 stats;
3269 + struct dpa_rx_errors rx_errors;
3270 + struct dpa_ern_cnt ern_cnt;
3271 +};
3272 +
3273 +struct dpa_priv_s {
3274 + struct dpa_percpu_priv_s __percpu *percpu_priv;
3275 + struct dpa_bp *dpa_bp;
3276 + /* Store here the needed Tx headroom for convenience and speed
3277 + * (even though it can be computed based on the fields of buf_layout)
3278 + */
3279 + uint16_t tx_headroom;
3280 + struct net_device *net_dev;
3281 + struct mac_device *mac_dev;
3282 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
3283 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
3284 +
3285 + size_t bp_count;
3286 +
3287 + uint16_t channel; /* "fsl,qman-channel-id" */
3288 + struct list_head dpa_fq_list;
3289 +
3290 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3291 + struct dentry *debugfs_loop_file;
3292 +#endif
3293 +
3294 + uint32_t msg_enable; /* net_device message level */
3295 +#ifdef CONFIG_FSL_DPAA_1588
3296 + struct dpa_ptp_tsu *tsu;
3297 +#endif
3298 +
3299 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3300 +/* TODO: this is temporary until pcd support is implemented in dpaa */
3301 + int priv_pcd_num_ranges;
3302 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
3303 +#endif
3304 +
3305 + struct {
3306 + /**
3307 + * All egress queues to a given net device belong to one
3308 + * (and the same) congestion group.
3309 + */
3310 + struct qman_cgr cgr;
3311 + /* If congested, when it began. Used for performance stats. */
3312 + u32 congestion_start_jiffies;
3313 + /* Number of jiffies the Tx port was congested. */
3314 + u32 congested_jiffies;
3315 + /**
3316 + * Counter for the number of times the CGR
3317 + * entered congestion state
3318 + */
3319 + u32 cgr_congested_count;
3320 + } cgr_data;
3321 + /* Use a per-port CGR for ingress traffic. */
3322 + bool use_ingress_cgr;
3323 + struct qman_cgr ingress_cgr;
3324 +
3325 +#ifdef CONFIG_FSL_DPAA_TS
3326 + bool ts_tx_en; /* Tx timestamping enabled */
3327 + bool ts_rx_en; /* Rx timestamping enabled */
3328 +#endif /* CONFIG_FSL_DPAA_TS */
3329 +
3330 + struct dpa_buffer_layout_s *buf_layout;
3331 + uint16_t rx_headroom;
3332 + char if_type[30];
3333 +
3334 + void *peer;
3335 +#ifdef CONFIG_PM
3336 + u32 wol;
3337 +#endif
3338 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3339 + int loop_id;
3340 + int loop_to;
3341 +#endif
3342 +#ifdef CONFIG_FSL_DPAA_CEETM
3343 + bool ceetm_en; /* CEETM QoS enabled */
3344 +#endif
3345 +};
3346 +
3347 +struct fm_port_fqs {
3348 + struct dpa_fq *tx_defq;
3349 + struct dpa_fq *tx_errq;
3350 + struct dpa_fq *rx_defq;
3351 + struct dpa_fq *rx_errq;
3352 +};
3353 +
3354 +
3355 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3356 +extern struct net_device *dpa_loop_netdevs[20];
3357 +#endif
3358 +
3359 +/* functions with different implementation for SG and non-SG: */
3360 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
3361 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
3362 +void __hot _dpa_rx(struct net_device *net_dev,
3363 + struct qman_portal *portal,
3364 + const struct dpa_priv_s *priv,
3365 + struct dpa_percpu_priv_s *percpu_priv,
3366 + const struct qm_fd *fd,
3367 + u32 fqid,
3368 + int *count_ptr);
3369 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
3370 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
3371 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
3372 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
3373 + const struct qm_fd *fd);
3374 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3375 + const struct qm_fd *fd,
3376 + struct sk_buff *skb,
3377 + int *use_gro);
3378 +#ifndef CONFIG_FSL_DPAA_TS
3379 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
3380 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
3381 + uint32_t min_size,
3382 + uint16_t min_offset,
3383 + unsigned char **new_buf_start);
3384 +#endif
3385 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
3386 + struct sk_buff *skb, struct qm_fd *fd,
3387 + int *count_ptr, int *offset);
3388 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
3389 + struct sk_buff *skb, struct qm_fd *fd);
3390 +int __cold __attribute__((nonnull))
3391 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
3392 +
3393 +/* Turn on HW checksum computation for this outgoing frame.
3394 + * If the current protocol is not something we support in this regard
3395 + * (or if the stack has already computed the SW checksum), we do nothing.
3396 + *
3397 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
3398 + * otherwise.
3399 + *
3400 + * Note that this function may modify the fd->cmd field and the skb data buffer
3401 + * (the Parse Results area).
3402 + */
3403 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
3404 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
3405 +
3406 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
3407 + struct qman_portal *portal)
3408 +{
3409 + /* In case of threaded ISR for RT enable kernel,
3410 + * in_irq() does not return appropriate value, so use
3411 + * in_serving_softirq to distinguish softirq or irq context.
3412 + */
3413 + if (unlikely(in_irq() || !in_serving_softirq())) {
3414 + /* Disable QMan IRQ and invoke NAPI */
3415 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
3416 + if (likely(!ret)) {
3417 + const struct qman_portal_config *pc =
3418 + qman_p_get_portal_config(portal);
3419 + struct dpa_napi_portal *np =
3420 + &percpu_priv->np[pc->index];
3421 +
3422 + np->p = portal;
3423 + napi_schedule(&np->napi);
3424 + percpu_priv->in_interrupt++;
3425 + return 1;
3426 + }
3427 + }
3428 + return 0;
3429 +}
3430 +
3431 +static inline ssize_t __const __must_check __attribute__((nonnull))
3432 +dpa_fd_length(const struct qm_fd *fd)
3433 +{
3434 + return fd->length20;
3435 +}
3436 +
3437 +static inline ssize_t __const __must_check __attribute__((nonnull))
3438 +dpa_fd_offset(const struct qm_fd *fd)
3439 +{
3440 + return fd->offset;
3441 +}
3442 +
3443 +/* Verifies if the skb length is below the interface MTU */
3444 +static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu)
3445 +{
3446 + if (unlikely(skb->len > mtu))
3447 + if ((skb->protocol != htons(ETH_P_8021Q))
3448 + || (skb->len > mtu + 4))
3449 + return -1;
3450 +
3451 + return 0;
3452 +}
3453 +
3454 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
3455 +{
3456 + uint16_t headroom;
3457 + /* The frame headroom must accommodate:
3458 + * - the driver private data area
3459 + * - parse results, hash results, timestamp if selected
3460 + * - manip extra space
3461 + * If either hash results or time stamp are selected, both will
3462 + * be copied to/from the frame headroom, as TS is located between PR and
3463 + * HR in the IC and IC copy size has a granularity of 16bytes
3464 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
3465 + *
3466 + * Also make sure the headroom is a multiple of data_align bytes
3467 + */
3468 + headroom = (uint16_t)(bl->priv_data_size +
3469 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
3470 + (bl->hash_results || bl->time_stamp ?
3471 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
3472 + bl->manip_extra_space);
3473 +
3474 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
3475 +}
3476 +
3477 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
3478 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
3479 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
3480 +
3481 +void dpaa_eth_sysfs_remove(struct device *dev);
3482 +void dpaa_eth_sysfs_init(struct device *dev);
3483 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
3484 +
3485 +void dpa_private_napi_del(struct net_device *net_dev);
3486 +
3487 +/* Equivalent to a memset(0), but works faster */
3488 +static inline void clear_fd(struct qm_fd *fd)
3489 +{
3490 + fd->opaque_addr = 0;
3491 + fd->opaque = 0;
3492 + fd->cmd = 0;
3493 +}
3494 +
3495 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
3496 + struct qman_fq *tx_fq)
3497 +{
3498 + int i;
3499 +
3500 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
3501 + if (priv->egress_fqs[i] == tx_fq)
3502 + return i;
3503 +
3504 + return -EINVAL;
3505 +}
3506 +
3507 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
3508 + struct rtnl_link_stats64 *percpu_stats,
3509 + struct qm_fd *fd, struct qman_fq *egress_fq,
3510 + struct qman_fq *conf_fq)
3511 +{
3512 + int err, i;
3513 +
3514 + if (fd->bpid == 0xff)
3515 + fd->cmd |= qman_fq_fqid(conf_fq);
3516 +
3517 + /* Trace this Tx fd */
3518 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
3519 +
3520 + for (i = 0; i < 100000; i++) {
3521 + err = qman_enqueue(egress_fq, fd, 0);
3522 + if (err != -EBUSY)
3523 + break;
3524 + }
3525 +
3526 + if (unlikely(err < 0)) {
3527 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
3528 + percpu_stats->tx_errors++;
3529 + percpu_stats->tx_fifo_errors++;
3530 + return err;
3531 + }
3532 +
3533 + percpu_stats->tx_packets++;
3534 + percpu_stats->tx_bytes += dpa_fd_length(fd);
3535 +
3536 + return 0;
3537 +}
3538 +
3539 +/* Use multiple WQs for FQ assignment:
3540 + * - Tx Confirmation queues go to WQ1.
3541 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
3542 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
3543 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
3544 + * to be scheduled, in case there are many more FQs in WQ3).
3545 + * This ensures that Tx-confirmed buffers are timely released. In particular,
3546 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
3547 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
3548 + * dequeue scheduling is round-robin.
3549 + */
3550 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
3551 +{
3552 + switch (fq->fq_type) {
3553 + case FQ_TYPE_TX_CONFIRM:
3554 + case FQ_TYPE_TX_CONF_MQ:
3555 + fq->wq = 1;
3556 + break;
3557 + case FQ_TYPE_RX_DEFAULT:
3558 + case FQ_TYPE_TX:
3559 + fq->wq = 3;
3560 + break;
3561 + case FQ_TYPE_RX_ERROR:
3562 + case FQ_TYPE_TX_ERROR:
3563 + case FQ_TYPE_RX_PCD_HI_PRIO:
3564 + fq->wq = 2;
3565 + break;
3566 + case FQ_TYPE_RX_PCD:
3567 + fq->wq = 5;
3568 + break;
3569 + default:
3570 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
3571 + fq->fq_type, fq->fqid);
3572 + }
3573 +}
3574 +
3575 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
3576 +/* Use in lieu of skb_get_queue_mapping() */
3577 +#ifdef CONFIG_FMAN_PFC
3578 +#define dpa_get_queue_mapping(skb) \
3579 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
3580 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
3581 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
3582 + dpa_num_cpus + smp_processor_id()));
3583 +
3584 +#else
3585 +#define dpa_get_queue_mapping(skb) \
3586 + raw_smp_processor_id()
3587 +#endif
3588 +#else
3589 +/* Use the queue selected by XPS */
3590 +#define dpa_get_queue_mapping(skb) \
3591 + skb_get_queue_mapping(skb)
3592 +#endif
3593 +
3594 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
3595 +struct ptp_priv_s {
3596 + struct device_node *node;
3597 + struct platform_device *of_dev;
3598 + struct ptp_clock *clock;
3599 + struct mac_device *mac_dev;
3600 +};
3601 +extern struct ptp_priv_s ptp_priv;
3602 +#endif
3603 +
3604 +static inline void _dpa_bp_free_pf(void *addr)
3605 +{
3606 + put_page(virt_to_head_page(addr));
3607 +}
3608 +
3609 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
3610 + * manifests itself at high traffic rates when frames cross 4K memory
3611 + * boundaries or when they are not aligned to 16 bytes; For the moment, we
3612 + * use a SW workaround to avoid frames larger than 4K or that exceed 4K
3613 + * alignments and to realign the frames to 16 bytes.
3614 + */
3615 +
3616 +#ifndef CONFIG_PPC
3617 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
3618 +#define NONREC_MARK 0x01
3619 +#define HAS_DMA_ISSUE(start, size) \
3620 + (((uintptr_t)(start) + (size)) > \
3621 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
3622 +#endif /* !CONFIG_PPC */
3623 +
3624 +#endif /* __DPA_H */
3625 --- /dev/null
3626 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3627 @@ -0,0 +1,205 @@
3628 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3629 + *
3630 + * Redistribution and use in source and binary forms, with or without
3631 + * modification, are permitted provided that the following conditions are met:
3632 + * * Redistributions of source code must retain the above copyright
3633 + * notice, this list of conditions and the following disclaimer.
3634 + * * Redistributions in binary form must reproduce the above copyright
3635 + * notice, this list of conditions and the following disclaimer in the
3636 + * documentation and/or other materials provided with the distribution.
3637 + * * Neither the name of Freescale Semiconductor nor the
3638 + * names of its contributors may be used to endorse or promote products
3639 + * derived from this software without specific prior written permission.
3640 + *
3641 + *
3642 + * ALTERNATIVELY, this software may be distributed under the terms of the
3643 + * GNU General Public License ("GPL") as published by the Free Software
3644 + * Foundation, either version 2 of that License or (at your option) any
3645 + * later version.
3646 + *
3647 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3648 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3649 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3650 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3651 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3652 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3653 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3654 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3655 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3656 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3657 + */
3658 +
3659 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3660 +#define pr_fmt(fmt) \
3661 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3662 + KBUILD_BASENAME".c", __LINE__, __func__
3663 +#else
3664 +#define pr_fmt(fmt) \
3665 + KBUILD_MODNAME ": " fmt
3666 +#endif
3667 +
3668 +#include <linux/init.h>
3669 +#include <linux/module.h>
3670 +#include <linux/io.h>
3671 +#include <linux/of_platform.h>
3672 +#include <linux/of_net.h>
3673 +#include <linux/etherdevice.h>
3674 +#include <linux/kthread.h>
3675 +#include <linux/percpu.h>
3676 +#include <linux/highmem.h>
3677 +#include <linux/sort.h>
3678 +#include <linux/fsl_qman.h>
3679 +#include "dpaa_eth.h"
3680 +#include "dpaa_eth_common.h"
3681 +#include "dpaa_eth_base.h"
3682 +
3683 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
3684 +
3685 +MODULE_LICENSE("Dual BSD/GPL");
3686 +
3687 +uint8_t advanced_debug = -1;
3688 +module_param(advanced_debug, byte, S_IRUGO);
3689 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
3690 +EXPORT_SYMBOL(advanced_debug);
3691 +
3692 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
3693 +{
3694 + return ((struct dpa_bp *)dpa_bp0)->size -
3695 + ((struct dpa_bp *)dpa_bp1)->size;
3696 +}
3697 +
3698 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3699 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
3700 +{
3701 + int i, lenp, na, ns, err;
3702 + struct device *dev;
3703 + struct device_node *dev_node;
3704 + const __be32 *bpool_cfg;
3705 + struct dpa_bp *dpa_bp;
3706 + u32 bpid;
3707 +
3708 + dev = &_of_dev->dev;
3709 +
3710 + *count = of_count_phandle_with_args(dev->of_node,
3711 + "fsl,bman-buffer-pools", NULL);
3712 + if (*count < 1) {
3713 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
3714 + return ERR_PTR(-EINVAL);
3715 + }
3716 +
3717 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
3718 + if (dpa_bp == NULL) {
3719 + dev_err(dev, "devm_kzalloc() failed\n");
3720 + return ERR_PTR(-ENOMEM);
3721 + }
3722 +
3723 + dev_node = of_find_node_by_path("/");
3724 + if (unlikely(dev_node == NULL)) {
3725 + dev_err(dev, "of_find_node_by_path(/) failed\n");
3726 + return ERR_PTR(-EINVAL);
3727 + }
3728 +
3729 + na = of_n_addr_cells(dev_node);
3730 + ns = of_n_size_cells(dev_node);
3731 +
3732 + for (i = 0; i < *count; i++) {
3733 + of_node_put(dev_node);
3734 +
3735 + dev_node = of_parse_phandle(dev->of_node,
3736 + "fsl,bman-buffer-pools", i);
3737 + if (dev_node == NULL) {
3738 + dev_err(dev, "of_find_node_by_phandle() failed\n");
3739 + return ERR_PTR(-EFAULT);
3740 + }
3741 +
3742 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
3743 + dev_err(dev,
3744 + "!of_device_is_compatible(%s, fsl,bpool)\n",
3745 + dev_node->full_name);
3746 + dpa_bp = ERR_PTR(-EINVAL);
3747 + goto _return_of_node_put;
3748 + }
3749 +
3750 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
3751 + if (err) {
3752 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
3753 + dpa_bp = ERR_PTR(-EINVAL);
3754 + goto _return_of_node_put;
3755 + }
3756 + dpa_bp[i].bpid = (uint8_t)bpid;
3757 +
3758 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
3759 + &lenp);
3760 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
3761 + const uint32_t *seed_pool;
3762 +
3763 + dpa_bp[i].config_count =
3764 + (int)of_read_number(bpool_cfg, ns);
3765 + dpa_bp[i].size =
3766 + (size_t)of_read_number(bpool_cfg + ns, ns);
3767 + dpa_bp[i].paddr =
3768 + of_read_number(bpool_cfg + 2 * ns, na);
3769 +
3770 + seed_pool = of_get_property(dev_node,
3771 + "fsl,bpool-ethernet-seeds", &lenp);
3772 + dpa_bp[i].seed_pool = !!seed_pool;
3773 +
3774 + } else {
3775 + dev_err(dev,
3776 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
3777 + dev_node->full_name);
3778 + dpa_bp = ERR_PTR(-EINVAL);
3779 + goto _return_of_node_put;
3780 + }
3781 + }
3782 +
3783 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
3784 +
3785 + return dpa_bp;
3786 +
3787 +_return_of_node_put:
3788 + if (dev_node)
3789 + of_node_put(dev_node);
3790 +
3791 + return dpa_bp;
3792 +}
3793 +EXPORT_SYMBOL(dpa_bp_probe);
3794 +
3795 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3796 + size_t count)
3797 +{
3798 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3799 + int i;
3800 +
3801 + priv->dpa_bp = dpa_bp;
3802 + priv->bp_count = count;
3803 +
3804 + for (i = 0; i < count; i++) {
3805 + int err;
3806 + err = dpa_bp_alloc(&dpa_bp[i]);
3807 + if (err < 0) {
3808 + dpa_bp_free(priv);
3809 + priv->dpa_bp = NULL;
3810 + return err;
3811 + }
3812 + }
3813 +
3814 + return 0;
3815 +}
3816 +EXPORT_SYMBOL(dpa_bp_create);
3817 +
3818 +static int __init __cold dpa_advanced_load(void)
3819 +{
3820 + pr_info(DPA_DESCRIPTION "\n");
3821 +
3822 + return 0;
3823 +}
3824 +module_init(dpa_advanced_load);
3825 +
3826 +static void __exit __cold dpa_advanced_unload(void)
3827 +{
3828 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
3829 + KBUILD_BASENAME".c", __func__);
3830 +
3831 +}
3832 +module_exit(dpa_advanced_unload);
3833 --- /dev/null
3834 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3835 @@ -0,0 +1,49 @@
3836 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3837 + *
3838 + * Redistribution and use in source and binary forms, with or without
3839 + * modification, are permitted provided that the following conditions are met:
3840 + * * Redistributions of source code must retain the above copyright
3841 + * notice, this list of conditions and the following disclaimer.
3842 + * * Redistributions in binary form must reproduce the above copyright
3843 + * notice, this list of conditions and the following disclaimer in the
3844 + * documentation and/or other materials provided with the distribution.
3845 + * * Neither the name of Freescale Semiconductor nor the
3846 + * names of its contributors may be used to endorse or promote products
3847 + * derived from this software without specific prior written permission.
3848 + *
3849 + *
3850 + * ALTERNATIVELY, this software may be distributed under the terms of the
3851 + * GNU General Public License ("GPL") as published by the Free Software
3852 + * Foundation, either version 2 of that License or (at your option) any
3853 + * later version.
3854 + *
3855 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3856 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3857 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3858 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3859 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3860 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3861 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3862 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3863 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3864 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3865 + */
3866 +
3867 +#ifndef __DPAA_ETH_BASE_H
3868 +#define __DPAA_ETH_BASE_H
3869 +
3870 +#include <linux/etherdevice.h> /* struct net_device */
3871 +#include <linux/fsl_bman.h> /* struct bm_buffer */
3872 +#include <linux/of_platform.h> /* struct platform_device */
3873 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
3874 +
3875 +extern uint8_t advanced_debug;
3876 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
3877 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
3878 +
3879 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3880 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
3881 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3882 + size_t count);
3883 +
3884 +#endif /* __DPAA_ETH_BASE_H */
3885 --- /dev/null
3886 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3887 @@ -0,0 +1,1992 @@
3888 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
3889 + *
3890 + * Redistribution and use in source and binary forms, with or without
3891 + * modification, are permitted provided that the following conditions are met:
3892 + * * Redistributions of source code must retain the above copyright
3893 + * notice, this list of conditions and the following disclaimer.
3894 + * * Redistributions in binary form must reproduce the above copyright
3895 + * notice, this list of conditions and the following disclaimer in the
3896 + * documentation and/or other materials provided with the distribution.
3897 + * * Neither the name of Freescale Semiconductor nor the
3898 + * names of its contributors may be used to endorse or promote products
3899 + * derived from this software without specific prior written permission.
3900 + *
3901 + *
3902 + * ALTERNATIVELY, this software may be distributed under the terms of the
3903 + * GNU General Public License ("GPL") as published by the Free Software
3904 + * Foundation, either version 2 of that License or (at your option) any
3905 + * later version.
3906 + *
3907 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3908 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3909 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3910 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3911 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3912 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3913 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3914 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3915 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3916 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3917 + */
3918 +
3919 +#include <linux/init.h>
3920 +#include "dpaa_eth_ceetm.h"
3921 +
3922 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
3923 +
3924 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
3925 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
3926 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
3927 +};
3928 +
3929 +struct Qdisc_ops ceetm_qdisc_ops;
3930 +
3931 +/* Obtain the DCP and the SP ids from the FMan port */
3932 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
3933 + unsigned int *sp_id)
3934 +{
3935 + uint32_t channel;
3936 + t_LnxWrpFmPortDev *port_dev;
3937 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
3938 + struct mac_device *mac_dev = dpa_priv->mac_dev;
3939 +
3940 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
3941 + channel = port_dev->txCh;
3942 +
3943 + *sp_id = channel & CHANNEL_SP_MASK;
3944 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
3945 +
3946 + if (channel < DCP0_MAX_CHANNEL) {
3947 + *dcp_id = qm_dc_portal_fman0;
3948 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
3949 + } else {
3950 + *dcp_id = qm_dc_portal_fman1;
3951 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
3952 + }
3953 +}
3954 +
3955 +/* Enqueue Rejection Notification callback */
3956 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
3957 + const struct qm_mr_entry *msg)
3958 +{
3959 + struct net_device *net_dev;
3960 + struct ceetm_class *cls;
3961 + struct ceetm_class_stats *cstats = NULL;
3962 + const struct dpa_priv_s *dpa_priv;
3963 + struct dpa_percpu_priv_s *dpa_percpu_priv;
3964 + struct sk_buff *skb;
3965 + struct qm_fd fd = msg->ern.fd;
3966 +
3967 + net_dev = ((struct ceetm_fq *)fq)->net_dev;
3968 + dpa_priv = netdev_priv(net_dev);
3969 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
3970 +
3971 + /* Increment DPA counters */
3972 + dpa_percpu_priv->stats.tx_dropped++;
3973 + dpa_percpu_priv->stats.tx_fifo_errors++;
3974 +
3975 + /* Increment CEETM counters */
3976 + cls = ((struct ceetm_fq *)fq)->ceetm_cls;
3977 + switch (cls->type) {
3978 + case CEETM_PRIO:
3979 + cstats = this_cpu_ptr(cls->prio.cstats);
3980 + break;
3981 + case CEETM_WBFS:
3982 + cstats = this_cpu_ptr(cls->wbfs.cstats);
3983 + break;
3984 + }
3985 +
3986 + if (cstats)
3987 + cstats->ern_drop_count++;
3988 +
3989 + if (fd.bpid != 0xff) {
3990 + dpa_fd_release(net_dev, &fd);
3991 + return;
3992 + }
3993 +
3994 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
3995 + dev_kfree_skb_any(skb);
3996 +}
3997 +
3998 +/* Congestion State Change Notification callback */
3999 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
4000 +{
4001 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
4002 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
4003 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
4004 + struct ceetm_class_stats *cstats = NULL;
4005 +
4006 + switch (cls->type) {
4007 + case CEETM_PRIO:
4008 + cstats = this_cpu_ptr(cls->prio.cstats);
4009 + break;
4010 + case CEETM_WBFS:
4011 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4012 + break;
4013 + }
4014 +
4015 + if (congested) {
4016 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
4017 + netif_tx_stop_all_queues(dpa_priv->net_dev);
4018 + dpa_priv->cgr_data.cgr_congested_count++;
4019 + if (cstats)
4020 + cstats->congested_count++;
4021 + } else {
4022 + dpa_priv->cgr_data.congested_jiffies +=
4023 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
4024 + netif_tx_wake_all_queues(dpa_priv->net_dev);
4025 + }
4026 +}
4027 +
4028 +/* Allocate a ceetm fq */
4029 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
4030 + struct ceetm_class *cls)
4031 +{
4032 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
4033 + if (!*fq)
4034 + return -ENOMEM;
4035 +
4036 + (*fq)->net_dev = dev;
4037 + (*fq)->ceetm_cls = cls;
4038 + return 0;
4039 +}
4040 +
4041 +/* Configure a ceetm Class Congestion Group */
4042 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
4043 + struct qm_ceetm_channel *channel, unsigned int id,
4044 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
4045 +{
4046 + int err;
4047 + u32 cs_th;
4048 + u16 ccg_mask;
4049 + struct qm_ceetm_ccg_params ccg_params;
4050 +
4051 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
4052 + if (err)
4053 + return err;
4054 +
4055 + /* Configure the count mode (frames/bytes), enable congestion state
4056 + * notifications, configure the congestion entry and exit thresholds,
4057 + * enable tail-drop, configure the tail-drop mode, and set the
4058 + * overhead accounting limit
4059 + */
4060 + ccg_mask = QM_CCGR_WE_MODE |
4061 + QM_CCGR_WE_CSCN_EN |
4062 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
4063 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
4064 + QM_CCGR_WE_OAL;
4065 +
4066 + ccg_params.mode = 0; /* count bytes */
4067 + ccg_params.cscn_en = 1; /* generate notifications */
4068 + ccg_params.td_en = 1; /* enable tail-drop */
4069 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
4070 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
4071 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
4072 +
4073 + /* Set the congestion state thresholds according to the link speed */
4074 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
4075 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
4076 + else
4077 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
4078 +
4079 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
4080 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
4081 + cs_th * CEETM_CCGR_RATIO, 1);
4082 +
4083 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
4084 + if (err)
4085 + return err;
4086 +
4087 + return 0;
4088 +}
4089 +
4090 +/* Configure a ceetm Logical Frame Queue */
4091 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
4092 + struct qm_ceetm_lfq **lfq)
4093 +{
4094 + int err;
4095 + u64 context_a;
4096 + u32 context_b;
4097 +
4098 + err = qman_ceetm_lfq_claim(lfq, cq);
4099 + if (err)
4100 + return err;
4101 +
4102 + /* Get the former contexts in order to preserve context B */
4103 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
4104 + if (err)
4105 + return err;
4106 +
4107 + context_a = CEETM_CONTEXT_A;
4108 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
4109 + if (err)
4110 + return err;
4111 +
4112 + (*lfq)->ern = ceetm_ern;
4113 +
4114 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
4115 + if (err)
4116 + return err;
4117 +
4118 + return 0;
4119 +}
4120 +
4121 +/* Configure a prio ceetm class */
4122 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
4123 + struct net_device *dev,
4124 + struct qm_ceetm_channel *channel,
4125 + unsigned int id)
4126 +{
4127 + int err;
4128 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4129 +
4130 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
4131 + if (err)
4132 + return err;
4133 +
4134 + /* Claim and configure the CCG */
4135 + err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq,
4136 + dpa_priv);
4137 + if (err)
4138 + return err;
4139 +
4140 + /* Claim and configure the CQ */
4141 + err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg);
4142 + if (err)
4143 + return err;
4144 +
4145 + if (cls->shaped) {
4146 + err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1);
4147 + if (err)
4148 + return err;
4149 +
4150 + err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1);
4151 + if (err)
4152 + return err;
4153 + }
4154 +
4155 + /* Claim and configure a LFQ */
4156 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
4157 + if (err)
4158 + return err;
4159 +
4160 + return 0;
4161 +}
4162 +
4163 +/* Configure a wbfs ceetm class */
4164 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
4165 + struct net_device *dev,
4166 + struct qm_ceetm_channel *channel,
4167 + unsigned int id, int type)
4168 +{
4169 + int err;
4170 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4171 +
4172 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
4173 + if (err)
4174 + return err;
4175 +
4176 + /* Claim and configure the CCG */
4177 + err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq,
4178 + dpa_priv);
4179 + if (err)
4180 + return err;
4181 +
4182 + /* Claim and configure the CQ */
4183 + if (type == WBFS_GRP_B)
4184 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id,
4185 + cls->wbfs.ccg);
4186 + else
4187 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id,
4188 + cls->wbfs.ccg);
4189 + if (err)
4190 + return err;
4191 +
4192 + /* Configure the CQ weight: real number multiplied by 100 to get rid
4193 + * of the fraction
4194 + */
4195 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
4196 + cls->wbfs.weight * 100);
4197 + if (err)
4198 + return err;
4199 +
4200 + /* Claim and configure a LFQ */
4201 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
4202 + if (err)
4203 + return err;
4204 +
4205 + return 0;
4206 +}
4207 +
4208 +/* Find class in qdisc hash table using given handle */
4209 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
4210 +{
4211 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4212 + struct Qdisc_class_common *clc;
4213 +
4214 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
4215 + __func__, handle, sch->handle);
4216 +
4217 + clc = qdisc_class_find(&priv->clhash, handle);
4218 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
4219 +}
4220 +
4221 +/* Insert a class in the qdisc's class hash */
4222 +static void ceetm_link_class(struct Qdisc *sch,
4223 + struct Qdisc_class_hash *clhash,
4224 + struct Qdisc_class_common *common)
4225 +{
4226 + sch_tree_lock(sch);
4227 + qdisc_class_hash_insert(clhash, common);
4228 + sch_tree_unlock(sch);
4229 + qdisc_class_hash_grow(sch, clhash);
4230 +}
4231 +
4232 +/* Destroy a ceetm class */
4233 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
4234 +{
4235 + if (!cl)
4236 + return;
4237 +
4238 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
4239 + __func__, cl->common.classid, sch->handle);
4240 +
4241 + switch (cl->type) {
4242 + case CEETM_ROOT:
4243 + if (cl->root.child) {
4244 + qdisc_destroy(cl->root.child);
4245 + cl->root.child = NULL;
4246 + }
4247 +
4248 + if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch))
4249 + pr_err(KBUILD_BASENAME
4250 + " : %s : error releasing the channel %d\n",
4251 + __func__, cl->root.ch->idx);
4252 +
4253 + break;
4254 +
4255 + case CEETM_PRIO:
4256 + if (cl->prio.child) {
4257 + qdisc_destroy(cl->prio.child);
4258 + cl->prio.child = NULL;
4259 + }
4260 +
4261 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
4262 + pr_err(KBUILD_BASENAME
4263 + " : %s : error releasing the LFQ %d\n",
4264 + __func__, cl->prio.lfq->idx);
4265 +
4266 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
4267 + pr_err(KBUILD_BASENAME
4268 + " : %s : error releasing the CQ %d\n",
4269 + __func__, cl->prio.cq->idx);
4270 +
4271 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
4272 + pr_err(KBUILD_BASENAME
4273 + " : %s : error releasing the CCG %d\n",
4274 + __func__, cl->prio.ccg->idx);
4275 +
4276 + kfree(cl->prio.fq);
4277 +
4278 + if (cl->prio.cstats)
4279 + free_percpu(cl->prio.cstats);
4280 +
4281 + break;
4282 +
4283 + case CEETM_WBFS:
4284 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
4285 + pr_err(KBUILD_BASENAME
4286 + " : %s : error releasing the LFQ %d\n",
4287 + __func__, cl->wbfs.lfq->idx);
4288 +
4289 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
4290 + pr_err(KBUILD_BASENAME
4291 + " : %s : error releasing the CQ %d\n",
4292 + __func__, cl->wbfs.cq->idx);
4293 +
4294 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
4295 + pr_err(KBUILD_BASENAME
4296 + " : %s : error releasing the CCG %d\n",
4297 + __func__, cl->wbfs.ccg->idx);
4298 +
4299 + kfree(cl->wbfs.fq);
4300 +
4301 + if (cl->wbfs.cstats)
4302 + free_percpu(cl->wbfs.cstats);
4303 + }
4304 +
4305 + tcf_destroy_chain(&cl->filter_list);
4306 + kfree(cl);
4307 +}
4308 +
4309 +/* Destroy a ceetm qdisc */
4310 +static void ceetm_destroy(struct Qdisc *sch)
4311 +{
4312 + unsigned int ntx, i;
4313 + struct hlist_node *next;
4314 + struct ceetm_class *cl;
4315 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4316 + struct net_device *dev = qdisc_dev(sch);
4317 +
4318 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
4319 + __func__, sch->handle);
4320 +
4321 + /* All filters need to be removed before destroying the classes */
4322 + tcf_destroy_chain(&priv->filter_list);
4323 +
4324 + for (i = 0; i < priv->clhash.hashsize; i++) {
4325 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode)
4326 + tcf_destroy_chain(&cl->filter_list);
4327 + }
4328 +
4329 + for (i = 0; i < priv->clhash.hashsize; i++) {
4330 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
4331 + common.hnode)
4332 + ceetm_cls_destroy(sch, cl);
4333 + }
4334 +
4335 + qdisc_class_hash_destroy(&priv->clhash);
4336 +
4337 + switch (priv->type) {
4338 + case CEETM_ROOT:
4339 + dpa_disable_ceetm(dev);
4340 +
4341 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
4342 + pr_err(KBUILD_BASENAME
4343 + " : %s : error releasing the LNI %d\n",
4344 + __func__, priv->root.lni->idx);
4345 +
4346 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
4347 + pr_err(KBUILD_BASENAME
4348 + " : %s : error releasing the SP %d\n",
4349 + __func__, priv->root.sp->idx);
4350 +
4351 + if (priv->root.qstats)
4352 + free_percpu(priv->root.qstats);
4353 +
4354 + if (!priv->root.qdiscs)
4355 + break;
4356 +
4357 + /* Remove the pfifo qdiscs */
4358 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
4359 + if (priv->root.qdiscs[ntx])
4360 + qdisc_destroy(priv->root.qdiscs[ntx]);
4361 +
4362 + kfree(priv->root.qdiscs);
4363 + break;
4364 +
4365 + case CEETM_PRIO:
4366 + if (priv->prio.parent)
4367 + priv->prio.parent->root.child = NULL;
4368 + break;
4369 +
4370 + case CEETM_WBFS:
4371 + if (priv->wbfs.parent)
4372 + priv->wbfs.parent->prio.child = NULL;
4373 + break;
4374 + }
4375 +}
4376 +
4377 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
4378 +{
4379 + struct Qdisc *qdisc;
4380 + unsigned int ntx, i;
4381 + struct nlattr *nest;
4382 + struct tc_ceetm_qopt qopt;
4383 + struct ceetm_qdisc_stats *qstats;
4384 + struct net_device *dev = qdisc_dev(sch);
4385 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4386 +
4387 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4388 +
4389 + sch_tree_lock(sch);
4390 + memset(&qopt, 0, sizeof(qopt));
4391 + qopt.type = priv->type;
4392 + qopt.shaped = priv->shaped;
4393 +
4394 + switch (priv->type) {
4395 + case CEETM_ROOT:
4396 + /* Gather statistics from the underlying pfifo qdiscs */
4397 + sch->q.qlen = 0;
4398 + memset(&sch->bstats, 0, sizeof(sch->bstats));
4399 + memset(&sch->qstats, 0, sizeof(sch->qstats));
4400 +
4401 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
4402 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
4403 + sch->q.qlen += qdisc->q.qlen;
4404 + sch->bstats.bytes += qdisc->bstats.bytes;
4405 + sch->bstats.packets += qdisc->bstats.packets;
4406 + sch->qstats.qlen += qdisc->qstats.qlen;
4407 + sch->qstats.backlog += qdisc->qstats.backlog;
4408 + sch->qstats.drops += qdisc->qstats.drops;
4409 + sch->qstats.requeues += qdisc->qstats.requeues;
4410 + sch->qstats.overlimits += qdisc->qstats.overlimits;
4411 + }
4412 +
4413 + for_each_online_cpu(i) {
4414 + qstats = per_cpu_ptr(priv->root.qstats, i);
4415 + sch->qstats.drops += qstats->drops;
4416 + }
4417 +
4418 + qopt.rate = priv->root.rate;
4419 + qopt.ceil = priv->root.ceil;
4420 + qopt.overhead = priv->root.overhead;
4421 + break;
4422 +
4423 + case CEETM_PRIO:
4424 + qopt.qcount = priv->prio.qcount;
4425 + break;
4426 +
4427 + case CEETM_WBFS:
4428 + qopt.qcount = priv->wbfs.qcount;
4429 + qopt.cr = priv->wbfs.cr;
4430 + qopt.er = priv->wbfs.er;
4431 + break;
4432 +
4433 + default:
4434 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4435 + sch_tree_unlock(sch);
4436 + return -EINVAL;
4437 + }
4438 +
4439 + nest = nla_nest_start(skb, TCA_OPTIONS);
4440 + if (!nest)
4441 + goto nla_put_failure;
4442 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
4443 + goto nla_put_failure;
4444 + nla_nest_end(skb, nest);
4445 +
4446 + sch_tree_unlock(sch);
4447 + return skb->len;
4448 +
4449 +nla_put_failure:
4450 + sch_tree_unlock(sch);
4451 + nla_nest_cancel(skb, nest);
4452 + return -EMSGSIZE;
4453 +}
4454 +
4455 +/* Configure a root ceetm qdisc */
4456 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4457 + struct tc_ceetm_qopt *qopt)
4458 +{
4459 + struct netdev_queue *dev_queue;
4460 + struct Qdisc *qdisc;
4461 + enum qm_dc_portal dcp_id;
4462 + unsigned int i, sp_id, parent_id;
4463 + int err;
4464 + u64 bps;
4465 + struct qm_ceetm_sp *sp;
4466 + struct qm_ceetm_lni *lni;
4467 + struct net_device *dev = qdisc_dev(sch);
4468 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4469 + struct mac_device *mac_dev = dpa_priv->mac_dev;
4470 +
4471 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4472 +
4473 + /* Validate inputs */
4474 + if (sch->parent != TC_H_ROOT) {
4475 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
4476 + tcf_destroy_chain(&priv->filter_list);
4477 + qdisc_class_hash_destroy(&priv->clhash);
4478 + return -EINVAL;
4479 + }
4480 +
4481 + if (!mac_dev) {
4482 + pr_err("CEETM: the interface is lacking a mac\n");
4483 + err = -EINVAL;
4484 + goto err_init_root;
4485 + }
4486 +
4487 + /* pre-allocate underlying pfifo qdiscs */
4488 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
4489 + sizeof(priv->root.qdiscs[0]),
4490 + GFP_KERNEL);
4491 + if (!priv->root.qdiscs) {
4492 + err = -ENOMEM;
4493 + goto err_init_root;
4494 + }
4495 +
4496 + for (i = 0; i < dev->num_tx_queues; i++) {
4497 + dev_queue = netdev_get_tx_queue(dev, i);
4498 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
4499 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
4500 +
4501 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
4502 + parent_id);
4503 + if (!qdisc) {
4504 + err = -ENOMEM;
4505 + goto err_init_root;
4506 + }
4507 +
4508 + priv->root.qdiscs[i] = qdisc;
4509 + qdisc->flags |= TCQ_F_ONETXQUEUE;
4510 + }
4511 +
4512 + sch->flags |= TCQ_F_MQROOT;
4513 +
4514 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
4515 + if (!priv->root.qstats) {
4516 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4517 + __func__);
4518 + err = -ENOMEM;
4519 + goto err_init_root;
4520 + }
4521 +
4522 + priv->shaped = qopt->shaped;
4523 + priv->root.rate = qopt->rate;
4524 + priv->root.ceil = qopt->ceil;
4525 + priv->root.overhead = qopt->overhead;
4526 +
4527 + /* Claim the SP */
4528 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
4529 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
4530 + if (err) {
4531 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
4532 + __func__);
4533 + goto err_init_root;
4534 + }
4535 +
4536 + priv->root.sp = sp;
4537 +
4538 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
4539 + * are connected to the TX FMan ports
4540 + */
4541 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
4542 + if (err) {
4543 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
4544 + __func__);
4545 + goto err_init_root;
4546 + }
4547 +
4548 + priv->root.lni = lni;
4549 +
4550 + err = qman_ceetm_sp_set_lni(sp, lni);
4551 + if (err) {
4552 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
4553 + __func__);
4554 + goto err_init_root;
4555 + }
4556 +
4557 + lni->sp = sp;
4558 +
4559 + /* Configure the LNI shaper */
4560 + if (priv->shaped) {
4561 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
4562 + if (err) {
4563 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4564 + __func__);
4565 + goto err_init_root;
4566 + }
4567 +
4568 + bps = priv->root.rate << 3; /* Bps -> bps */
4569 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
4570 + if (err) {
4571 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4572 + __func__);
4573 + goto err_init_root;
4574 + }
4575 +
4576 + bps = priv->root.ceil << 3; /* Bps -> bps */
4577 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
4578 + if (err) {
4579 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4580 + __func__);
4581 + goto err_init_root;
4582 + }
4583 + }
4584 +
4585 + /* TODO default configuration */
4586 +
4587 + dpa_enable_ceetm(dev);
4588 + return 0;
4589 +
4590 +err_init_root:
4591 + ceetm_destroy(sch);
4592 + return err;
4593 +}
4594 +
4595 +/* Configure a prio ceetm qdisc */
4596 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
4597 + struct tc_ceetm_qopt *qopt)
4598 +{
4599 + int err;
4600 + unsigned int i;
4601 + struct ceetm_class *parent_cl, *child_cl;
4602 + struct Qdisc *parent_qdisc;
4603 + struct net_device *dev = qdisc_dev(sch);
4604 +
4605 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4606 +
4607 + if (sch->parent == TC_H_ROOT) {
4608 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
4609 + err = -EINVAL;
4610 + goto err_init_prio;
4611 + }
4612 +
4613 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4614 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4615 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4616 + err = -EINVAL;
4617 + goto err_init_prio;
4618 + }
4619 +
4620 + /* Obtain the parent root ceetm_class */
4621 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4622 +
4623 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
4624 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
4625 + err = -EINVAL;
4626 + goto err_init_prio;
4627 + }
4628 +
4629 + priv->prio.parent = parent_cl;
4630 + parent_cl->root.child = sch;
4631 +
4632 + priv->shaped = parent_cl->shaped;
4633 + priv->prio.qcount = qopt->qcount;
4634 +
4635 + /* Create and configure qcount child classes */
4636 + for (i = 0; i < priv->prio.qcount; i++) {
4637 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4638 + if (!child_cl) {
4639 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4640 + __func__);
4641 + err = -ENOMEM;
4642 + goto err_init_prio;
4643 + }
4644 +
4645 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
4646 + if (!child_cl->prio.cstats) {
4647 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4648 + __func__);
4649 + err = -ENOMEM;
4650 + goto err_init_prio_cls;
4651 + }
4652 +
4653 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4654 + child_cl->refcnt = 1;
4655 + child_cl->parent = sch;
4656 + child_cl->type = CEETM_PRIO;
4657 + child_cl->shaped = priv->shaped;
4658 + child_cl->prio.child = NULL;
4659 +
4660 + /* All shaped CQs have CR and ER enabled by default */
4661 + child_cl->prio.cr = child_cl->shaped;
4662 + child_cl->prio.er = child_cl->shaped;
4663 + child_cl->prio.fq = NULL;
4664 + child_cl->prio.cq = NULL;
4665 +
4666 + /* Configure the corresponding hardware CQ */
4667 + err = ceetm_config_prio_cls(child_cl, dev,
4668 + parent_cl->root.ch, i);
4669 + if (err) {
4670 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
4671 + __func__, child_cl->common.classid);
4672 + goto err_init_prio_cls;
4673 + }
4674 +
4675 + /* Add class handle in Qdisc */
4676 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4677 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
4678 + __func__, child_cl->common.classid,
4679 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
4680 + }
4681 +
4682 + return 0;
4683 +
4684 +err_init_prio_cls:
4685 + ceetm_cls_destroy(sch, child_cl);
4686 +err_init_prio:
4687 + ceetm_destroy(sch);
4688 + return err;
4689 +}
4690 +
4691 +/* Configure a wbfs ceetm qdisc */
4692 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
4693 + struct tc_ceetm_qopt *qopt)
4694 +{
4695 + int err, group_b, small_group;
4696 + unsigned int i, id, prio_a, prio_b;
4697 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
4698 + struct Qdisc *parent_qdisc;
4699 + struct ceetm_qdisc *parent_priv;
4700 + struct qm_ceetm_channel *channel;
4701 + struct net_device *dev = qdisc_dev(sch);
4702 +
4703 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4704 +
4705 + /* Validate inputs */
4706 + if (sch->parent == TC_H_ROOT) {
4707 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
4708 + err = -EINVAL;
4709 + goto err_init_wbfs;
4710 + }
4711 +
4712 + /* Obtain the parent prio ceetm qdisc */
4713 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4714 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4715 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4716 + err = -EINVAL;
4717 + goto err_init_wbfs;
4718 + }
4719 +
4720 + /* Obtain the parent prio ceetm class */
4721 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4722 + parent_priv = qdisc_priv(parent_qdisc);
4723 +
4724 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
4725 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
4726 + err = -EINVAL;
4727 + goto err_init_wbfs;
4728 + }
4729 +
4730 + if (!qopt->qcount || !qopt->qweight[0]) {
4731 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
4732 + err = -EINVAL;
4733 + goto err_init_wbfs;
4734 + }
4735 +
4736 + priv->shaped = parent_cl->shaped;
4737 +
4738 + if (!priv->shaped && (qopt->cr || qopt->er)) {
4739 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
4740 + err = -EINVAL;
4741 + goto err_init_wbfs;
4742 + }
4743 +
4744 + if (priv->shaped && !(qopt->cr || qopt->er)) {
4745 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
4746 + err = -EINVAL;
4747 + goto err_init_wbfs;
4748 + }
4749 +
4750 + /* Obtain the parent root ceetm class */
4751 + root_cl = parent_priv->prio.parent;
4752 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
4753 + root_cl->root.wbfs_grp_large) {
4754 + pr_err("CEETM: no more wbfs classes are available\n");
4755 + err = -EINVAL;
4756 + goto err_init_wbfs;
4757 + }
4758 +
4759 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
4760 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
4761 + pr_err("CEETM: only %d wbfs classes are available\n",
4762 + CEETM_MIN_WBFS_QCOUNT);
4763 + err = -EINVAL;
4764 + goto err_init_wbfs;
4765 + }
4766 +
4767 + priv->wbfs.parent = parent_cl;
4768 + parent_cl->prio.child = sch;
4769 +
4770 + priv->wbfs.qcount = qopt->qcount;
4771 + priv->wbfs.cr = qopt->cr;
4772 + priv->wbfs.er = qopt->er;
4773 +
4774 + channel = root_cl->root.ch;
4775 +
4776 + /* Configure the hardware wbfs channel groups */
4777 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
4778 + /* Configure the large group A */
4779 + priv->wbfs.group_type = WBFS_GRP_LARGE;
4780 + small_group = false;
4781 + group_b = false;
4782 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4783 + prio_b = prio_a;
4784 +
4785 + } else if (root_cl->root.wbfs_grp_a) {
4786 + /* Configure the group B */
4787 + priv->wbfs.group_type = WBFS_GRP_B;
4788 +
4789 + err = qman_ceetm_channel_get_group(channel, &small_group,
4790 + &prio_a, &prio_b);
4791 + if (err) {
4792 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4793 + __func__);
4794 + goto err_init_wbfs;
4795 + }
4796 +
4797 + small_group = true;
4798 + group_b = true;
4799 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
4800 + /* If group A isn't configured, configure it as group B */
4801 + prio_a = prio_a ? : prio_b;
4802 +
4803 + } else {
4804 + /* Configure the small group A */
4805 + priv->wbfs.group_type = WBFS_GRP_A;
4806 +
4807 + err = qman_ceetm_channel_get_group(channel, &small_group,
4808 + &prio_a, &prio_b);
4809 + if (err) {
4810 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4811 + __func__);
4812 + goto err_init_wbfs;
4813 + }
4814 +
4815 + small_group = true;
4816 + group_b = false;
4817 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4818 + /* If group B isn't configured, configure it as group A */
4819 + prio_b = prio_b ? : prio_a;
4820 + }
4821 +
4822 + err = qman_ceetm_channel_set_group(channel, small_group, prio_a,
4823 + prio_b);
4824 + if (err)
4825 + goto err_init_wbfs;
4826 +
4827 + if (priv->shaped) {
4828 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
4829 + group_b,
4830 + priv->wbfs.cr);
4831 + if (err) {
4832 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
4833 + __func__);
4834 + goto err_init_wbfs;
4835 + }
4836 +
4837 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
4838 + group_b,
4839 + priv->wbfs.er);
4840 + if (err) {
4841 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
4842 + __func__);
4843 + goto err_init_wbfs;
4844 + }
4845 + }
4846 +
4847 + /* Create qcount child classes */
4848 + for (i = 0; i < priv->wbfs.qcount; i++) {
4849 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4850 + if (!child_cl) {
4851 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4852 + __func__);
4853 + err = -ENOMEM;
4854 + goto err_init_wbfs;
4855 + }
4856 +
4857 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
4858 + if (!child_cl->wbfs.cstats) {
4859 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4860 + __func__);
4861 + err = -ENOMEM;
4862 + goto err_init_wbfs_cls;
4863 + }
4864 +
4865 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4866 + child_cl->refcnt = 1;
4867 + child_cl->parent = sch;
4868 + child_cl->type = CEETM_WBFS;
4869 + child_cl->shaped = priv->shaped;
4870 + child_cl->wbfs.fq = NULL;
4871 + child_cl->wbfs.cq = NULL;
4872 + child_cl->wbfs.weight = qopt->qweight[i];
4873 +
4874 + if (priv->wbfs.group_type == WBFS_GRP_B)
4875 + id = WBFS_GRP_B_OFFSET + i;
4876 + else
4877 + id = WBFS_GRP_A_OFFSET + i;
4878 +
4879 + err = ceetm_config_wbfs_cls(child_cl, dev, channel, id,
4880 + priv->wbfs.group_type);
4881 + if (err) {
4882 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
4883 + __func__, child_cl->common.classid);
4884 + goto err_init_wbfs_cls;
4885 + }
4886 +
4887 + /* Add class handle in Qdisc */
4888 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4889 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
4890 + __func__, child_cl->common.classid,
4891 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
4892 + }
4893 +
4894 + /* Signal the root class that a group has been configured */
4895 + switch (priv->wbfs.group_type) {
4896 + case WBFS_GRP_LARGE:
4897 + root_cl->root.wbfs_grp_large = true;
4898 + break;
4899 + case WBFS_GRP_A:
4900 + root_cl->root.wbfs_grp_a = true;
4901 + break;
4902 + case WBFS_GRP_B:
4903 + root_cl->root.wbfs_grp_b = true;
4904 + break;
4905 + }
4906 +
4907 + return 0;
4908 +
4909 +err_init_wbfs_cls:
4910 + ceetm_cls_destroy(sch, child_cl);
4911 +err_init_wbfs:
4912 + ceetm_destroy(sch);
4913 + return err;
4914 +}
4915 +
4916 +/* Configure a generic ceetm qdisc */
4917 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
4918 +{
4919 + struct tc_ceetm_qopt *qopt;
4920 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
4921 + int ret;
4922 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4923 + struct net_device *dev = qdisc_dev(sch);
4924 +
4925 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4926 +
4927 + if (!netif_is_multiqueue(dev))
4928 + return -EOPNOTSUPP;
4929 +
4930 + if (!opt) {
4931 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4932 + return -EINVAL;
4933 + }
4934 +
4935 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
4936 + if (ret < 0) {
4937 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4938 + return ret;
4939 + }
4940 +
4941 + if (!tb[TCA_CEETM_QOPS]) {
4942 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
4943 + return -EINVAL;
4944 + }
4945 +
4946 + if (TC_H_MIN(sch->handle)) {
4947 + pr_err("CEETM: a qdisc should not have a minor\n");
4948 + return -EINVAL;
4949 + }
4950 +
4951 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
4952 +
4953 + /* Initialize the class hash list. Each qdisc has its own class hash */
4954 + ret = qdisc_class_hash_init(&priv->clhash);
4955 + if (ret < 0) {
4956 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
4957 + __func__);
4958 + return ret;
4959 + }
4960 +
4961 + priv->type = qopt->type;
4962 +
4963 + switch (priv->type) {
4964 + case CEETM_ROOT:
4965 + ret = ceetm_init_root(sch, priv, qopt);
4966 + break;
4967 + case CEETM_PRIO:
4968 + ret = ceetm_init_prio(sch, priv, qopt);
4969 + break;
4970 + case CEETM_WBFS:
4971 + ret = ceetm_init_wbfs(sch, priv, qopt);
4972 + break;
4973 + default:
4974 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4975 + ceetm_destroy(sch);
4976 + ret = -EINVAL;
4977 + }
4978 +
4979 + return ret;
4980 +}
4981 +
4982 +/* Edit a root ceetm qdisc */
4983 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4984 + struct net_device *dev,
4985 + struct tc_ceetm_qopt *qopt)
4986 +{
4987 + int err = 0;
4988 + u64 bps;
4989 +
4990 + if (priv->shaped != (bool)qopt->shaped) {
4991 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
4992 + priv->shaped ? "shaped" : "unshaped");
4993 + return -EINVAL;
4994 + }
4995 +
4996 + /* Nothing to modify for unshaped qdiscs */
4997 + if (!priv->shaped)
4998 + return 0;
4999 +
5000 + /* Configure the LNI shaper */
5001 + if (priv->root.overhead != qopt->overhead) {
5002 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
5003 + qopt->overhead);
5004 + if (err)
5005 + goto change_err;
5006 + priv->root.overhead = qopt->overhead;
5007 + }
5008 +
5009 + if (priv->root.rate != qopt->rate) {
5010 + bps = qopt->rate << 3; /* Bps -> bps */
5011 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
5012 + dev->mtu);
5013 + if (err)
5014 + goto change_err;
5015 + priv->root.rate = qopt->rate;
5016 + }
5017 +
5018 + if (priv->root.ceil != qopt->ceil) {
5019 + bps = qopt->ceil << 3; /* Bps -> bps */
5020 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
5021 + dev->mtu);
5022 + if (err)
5023 + goto change_err;
5024 + priv->root.ceil = qopt->ceil;
5025 + }
5026 +
5027 + return 0;
5028 +
5029 +change_err:
5030 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
5031 + __func__, sch->handle);
5032 + return err;
5033 +}
5034 +
5035 +/* Edit a wbfs ceetm qdisc */
5036 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
5037 + struct tc_ceetm_qopt *qopt)
5038 +{
5039 + int err;
5040 + bool group_b;
5041 + struct qm_ceetm_channel *channel;
5042 + struct ceetm_class *prio_class, *root_class;
5043 + struct ceetm_qdisc *prio_qdisc;
5044 +
5045 + if (qopt->qcount) {
5046 + pr_err("CEETM: the qcount can not be modified\n");
5047 + return -EINVAL;
5048 + }
5049 +
5050 + if (qopt->qweight[0]) {
5051 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
5052 + return -EINVAL;
5053 + }
5054 +
5055 + if (!priv->shaped && (qopt->cr || qopt->er)) {
5056 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
5057 + return -EINVAL;
5058 + }
5059 +
5060 + if (priv->shaped && !(qopt->cr || qopt->er)) {
5061 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
5062 + return -EINVAL;
5063 + }
5064 +
5065 + /* Nothing to modify for unshaped qdiscs */
5066 + if (!priv->shaped)
5067 + return 0;
5068 +
5069 + prio_class = priv->wbfs.parent;
5070 + prio_qdisc = qdisc_priv(prio_class->parent);
5071 + root_class = prio_qdisc->prio.parent;
5072 + channel = root_class->root.ch;
5073 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
5074 +
5075 + if (qopt->cr != priv->wbfs.cr) {
5076 + err = qman_ceetm_channel_set_group_cr_eligibility(channel,
5077 + group_b,
5078 + qopt->cr);
5079 + if (err)
5080 + goto change_err;
5081 + priv->wbfs.cr = qopt->cr;
5082 + }
5083 +
5084 + if (qopt->er != priv->wbfs.er) {
5085 + err = qman_ceetm_channel_set_group_er_eligibility(channel,
5086 + group_b,
5087 + qopt->er);
5088 + if (err)
5089 + goto change_err;
5090 + priv->wbfs.er = qopt->er;
5091 + }
5092 +
5093 + return 0;
5094 +
5095 +change_err:
5096 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
5097 + __func__, sch->handle);
5098 + return err;
5099 +}
5100 +
5101 +/* Edit a ceetm qdisc */
5102 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
5103 +{
5104 + struct tc_ceetm_qopt *qopt;
5105 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5106 + int ret;
5107 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5108 + struct net_device *dev = qdisc_dev(sch);
5109 +
5110 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5111 +
5112 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5113 + if (ret < 0) {
5114 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5115 + return ret;
5116 + }
5117 +
5118 + if (!tb[TCA_CEETM_QOPS]) {
5119 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5120 + return -EINVAL;
5121 + }
5122 +
5123 + if (TC_H_MIN(sch->handle)) {
5124 + pr_err("CEETM: a qdisc should not have a minor\n");
5125 + return -EINVAL;
5126 + }
5127 +
5128 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5129 +
5130 + if (priv->type != qopt->type) {
5131 + pr_err("CEETM: qdisc %X is not of the provided type\n",
5132 + sch->handle);
5133 + return -EINVAL;
5134 + }
5135 +
5136 + switch (priv->type) {
5137 + case CEETM_ROOT:
5138 + ret = ceetm_change_root(sch, priv, dev, qopt);
5139 + break;
5140 + case CEETM_PRIO:
5141 + pr_err("CEETM: prio qdiscs can not be modified\n");
5142 + ret = -EINVAL;
5143 + break;
5144 + case CEETM_WBFS:
5145 + ret = ceetm_change_wbfs(sch, priv, qopt);
5146 + break;
5147 + default:
5148 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5149 + ret = -EINVAL;
5150 + }
5151 +
5152 + return ret;
5153 +}
5154 +
5155 +/* Attach the underlying pfifo qdiscs */
5156 +static void ceetm_attach(struct Qdisc *sch)
5157 +{
5158 + struct net_device *dev = qdisc_dev(sch);
5159 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5160 + struct Qdisc *qdisc, *old_qdisc;
5161 + unsigned int i;
5162 +
5163 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5164 +
5165 + for (i = 0; i < dev->num_tx_queues; i++) {
5166 + qdisc = priv->root.qdiscs[i];
5167 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
5168 + if (old_qdisc)
5169 + qdisc_destroy(old_qdisc);
5170 + }
5171 +}
5172 +
5173 +static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid)
5174 +{
5175 + struct ceetm_class *cl;
5176 +
5177 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5178 + __func__, classid, sch->handle);
5179 + cl = ceetm_find(classid, sch);
5180 +
5181 + if (cl)
5182 + cl->refcnt++; /* Will decrement in put() */
5183 + return (unsigned long)cl;
5184 +}
5185 +
5186 +static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg)
5187 +{
5188 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5189 +
5190 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5191 + __func__, cl->common.classid, sch->handle);
5192 + cl->refcnt--;
5193 +
5194 + if (cl->refcnt == 0)
5195 + ceetm_cls_destroy(sch, cl);
5196 +}
5197 +
5198 +static int ceetm_cls_change_root(struct ceetm_class *cl,
5199 + struct tc_ceetm_copt *copt,
5200 + struct net_device *dev)
5201 +{
5202 + int err;
5203 + u64 bps;
5204 +
5205 + if ((bool)copt->shaped != cl->shaped) {
5206 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
5207 + cl->shaped ? "shaped" : "unshaped");
5208 + return -EINVAL;
5209 + }
5210 +
5211 + if (cl->shaped && cl->root.rate != copt->rate) {
5212 + bps = copt->rate << 3; /* Bps -> bps */
5213 + err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps,
5214 + dev->mtu);
5215 + if (err)
5216 + goto change_cls_err;
5217 + cl->root.rate = copt->rate;
5218 + }
5219 +
5220 + if (cl->shaped && cl->root.ceil != copt->ceil) {
5221 + bps = copt->ceil << 3; /* Bps -> bps */
5222 + err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps,
5223 + dev->mtu);
5224 + if (err)
5225 + goto change_cls_err;
5226 + cl->root.ceil = copt->ceil;
5227 + }
5228 +
5229 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
5230 + err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl);
5231 + if (err)
5232 + goto change_cls_err;
5233 + cl->root.tbl = copt->tbl;
5234 + }
5235 +
5236 + return 0;
5237 +
5238 +change_cls_err:
5239 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
5240 + __func__, cl->common.classid);
5241 + return err;
5242 +}
5243 +
5244 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
5245 + struct tc_ceetm_copt *copt)
5246 +{
5247 + int err;
5248 +
5249 + if (!cl->shaped && (copt->cr || copt->er)) {
5250 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
5251 + return -EINVAL;
5252 + }
5253 +
5254 + if (cl->prio.cr != (bool)copt->cr) {
5255 + err = qman_ceetm_channel_set_cq_cr_eligibility(
5256 + cl->prio.cq->parent,
5257 + cl->prio.cq->idx,
5258 + copt->cr);
5259 + if (err)
5260 + goto change_cls_err;
5261 + cl->prio.cr = copt->cr;
5262 + }
5263 +
5264 + if (cl->prio.er != (bool)copt->er) {
5265 + err = qman_ceetm_channel_set_cq_er_eligibility(
5266 + cl->prio.cq->parent,
5267 + cl->prio.cq->idx,
5268 + copt->er);
5269 + if (err)
5270 + goto change_cls_err;
5271 + cl->prio.er = copt->er;
5272 + }
5273 +
5274 + return 0;
5275 +
5276 +change_cls_err:
5277 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
5278 + __func__, cl->common.classid);
5279 + return err;
5280 +}
5281 +
5282 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
5283 + struct tc_ceetm_copt *copt)
5284 +{
5285 + int err;
5286 +
5287 + if (copt->weight != cl->wbfs.weight) {
5288 + /* Configure the CQ weight: real number multiplied by 100 to
5289 + * get rid of the fraction
5290 + */
5291 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
5292 + copt->weight * 100);
5293 +
5294 + if (err) {
5295 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5296 + __func__, cl->common.classid);
5297 + return err;
5298 + }
5299 +
5300 + cl->wbfs.weight = copt->weight;
5301 + }
5302 +
5303 + return 0;
5304 +}
5305 +
5306 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
5307 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
5308 + struct nlattr **tca, unsigned long *arg)
5309 +{
5310 + int err;
5311 + u64 bps;
5312 + struct ceetm_qdisc *priv;
5313 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
5314 + struct nlattr *opt = tca[TCA_OPTIONS];
5315 + struct nlattr *tb[__TCA_CEETM_MAX];
5316 + struct tc_ceetm_copt *copt;
5317 + struct qm_ceetm_channel *channel;
5318 + struct net_device *dev = qdisc_dev(sch);
5319 +
5320 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
5321 + __func__, classid, sch->handle);
5322 +
5323 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
5324 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
5325 + return -EINVAL;
5326 + }
5327 +
5328 + priv = qdisc_priv(sch);
5329 +
5330 + if (!opt) {
5331 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5332 + return -EINVAL;
5333 + }
5334 +
5335 + if (!cl && sch->handle != parentid) {
5336 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
5337 + return -EINVAL;
5338 + }
5339 +
5340 + if (!cl && priv->type != CEETM_ROOT) {
5341 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5342 + return -EINVAL;
5343 + }
5344 +
5345 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy);
5346 + if (err < 0) {
5347 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5348 + return -EINVAL;
5349 + }
5350 +
5351 + if (!tb[TCA_CEETM_COPT]) {
5352 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5353 + return -EINVAL;
5354 + }
5355 +
5356 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
5357 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
5358 + return -EINVAL;
5359 + }
5360 +
5361 + copt = nla_data(tb[TCA_CEETM_COPT]);
5362 +
5363 + /* Configure an existing ceetm class */
5364 + if (cl) {
5365 + if (copt->type != cl->type) {
5366 + pr_err("CEETM: class %X is not of the provided type\n",
5367 + cl->common.classid);
5368 + return -EINVAL;
5369 + }
5370 +
5371 + switch (copt->type) {
5372 + case CEETM_ROOT:
5373 + return ceetm_cls_change_root(cl, copt, dev);
5374 +
5375 + case CEETM_PRIO:
5376 + return ceetm_cls_change_prio(cl, copt);
5377 +
5378 + case CEETM_WBFS:
5379 + return ceetm_cls_change_wbfs(cl, copt);
5380 +
5381 + default:
5382 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
5383 + __func__);
5384 + return -EINVAL;
5385 + }
5386 + }
5387 +
5388 + /* Add a new root ceetm class */
5389 + if (copt->type != CEETM_ROOT) {
5390 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5391 + return -EINVAL;
5392 + }
5393 +
5394 + if (copt->shaped && !priv->shaped) {
5395 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
5396 + return -EINVAL;
5397 + }
5398 +
5399 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
5400 + if (!cl)
5401 + return -ENOMEM;
5402 +
5403 + cl->type = copt->type;
5404 + cl->shaped = copt->shaped;
5405 + cl->root.rate = copt->rate;
5406 + cl->root.ceil = copt->ceil;
5407 + cl->root.tbl = copt->tbl;
5408 +
5409 + cl->common.classid = classid;
5410 + cl->refcnt = 1;
5411 + cl->parent = sch;
5412 + cl->root.child = NULL;
5413 + cl->root.wbfs_grp_a = false;
5414 + cl->root.wbfs_grp_b = false;
5415 + cl->root.wbfs_grp_large = false;
5416 +
5417 + /* Claim a CEETM channel */
5418 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
5419 + if (err) {
5420 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
5421 + __func__);
5422 + goto claim_err;
5423 + }
5424 +
5425 + cl->root.ch = channel;
5426 +
5427 + if (cl->shaped) {
5428 + /* Configure the channel shaper */
5429 + err = qman_ceetm_channel_enable_shaper(channel, 1);
5430 + if (err)
5431 + goto channel_err;
5432 +
5433 + bps = cl->root.rate << 3; /* Bps -> bps */
5434 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
5435 + dev->mtu);
5436 + if (err)
5437 + goto channel_err;
5438 +
5439 + bps = cl->root.ceil << 3; /* Bps -> bps */
5440 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
5441 + dev->mtu);
5442 + if (err)
5443 + goto channel_err;
5444 +
5445 + } else {
5446 + /* Configure the uFQ algorithm */
5447 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
5448 + if (err)
5449 + goto channel_err;
5450 + }
5451 +
5452 + /* Add class handle in Qdisc */
5453 + ceetm_link_class(sch, &priv->clhash, &cl->common);
5454 +
5455 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
5456 + __func__, classid, channel->idx);
5457 + *arg = (unsigned long)cl;
5458 + return 0;
5459 +
5460 +channel_err:
5461 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
5462 + __func__, channel->idx);
5463 + if (qman_ceetm_channel_release(channel))
5464 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
5465 + __func__, channel->idx);
5466 +claim_err:
5467 + kfree(cl);
5468 + return err;
5469 +}
5470 +
5471 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
5472 +{
5473 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5474 + struct ceetm_class *cl;
5475 + unsigned int i;
5476 +
5477 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5478 +
5479 + if (arg->stop)
5480 + return;
5481 +
5482 + for (i = 0; i < priv->clhash.hashsize; i++) {
5483 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5484 + if (arg->count < arg->skip) {
5485 + arg->count++;
5486 + continue;
5487 + }
5488 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
5489 + arg->stop = 1;
5490 + return;
5491 + }
5492 + arg->count++;
5493 + }
5494 + }
5495 +}
5496 +
5497 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
5498 + struct sk_buff *skb, struct tcmsg *tcm)
5499 +{
5500 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5501 + struct nlattr *nest;
5502 + struct tc_ceetm_copt copt;
5503 +
5504 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5505 + __func__, cl->common.classid, sch->handle);
5506 +
5507 + sch_tree_lock(sch);
5508 +
5509 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
5510 + tcm->tcm_handle = cl->common.classid;
5511 +
5512 + memset(&copt, 0, sizeof(copt));
5513 +
5514 + copt.shaped = cl->shaped;
5515 + copt.type = cl->type;
5516 +
5517 + switch (cl->type) {
5518 + case CEETM_ROOT:
5519 + if (cl->root.child)
5520 + tcm->tcm_info = cl->root.child->handle;
5521 +
5522 + copt.rate = cl->root.rate;
5523 + copt.ceil = cl->root.ceil;
5524 + copt.tbl = cl->root.tbl;
5525 + break;
5526 +
5527 + case CEETM_PRIO:
5528 + if (cl->prio.child)
5529 + tcm->tcm_info = cl->prio.child->handle;
5530 +
5531 + copt.cr = cl->prio.cr;
5532 + copt.er = cl->prio.er;
5533 + break;
5534 +
5535 + case CEETM_WBFS:
5536 + copt.weight = cl->wbfs.weight;
5537 + break;
5538 + }
5539 +
5540 + nest = nla_nest_start(skb, TCA_OPTIONS);
5541 + if (!nest)
5542 + goto nla_put_failure;
5543 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
5544 + goto nla_put_failure;
5545 + nla_nest_end(skb, nest);
5546 + sch_tree_unlock(sch);
5547 + return skb->len;
5548 +
5549 +nla_put_failure:
5550 + sch_tree_unlock(sch);
5551 + nla_nest_cancel(skb, nest);
5552 + return -EMSGSIZE;
5553 +}
5554 +
5555 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
5556 +{
5557 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5558 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5559 +
5560 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5561 + __func__, cl->common.classid, sch->handle);
5562 +
5563 + sch_tree_lock(sch);
5564 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
5565 + cl->refcnt--;
5566 +
5567 + /* The refcnt should be at least 1 since we have incremented it in
5568 + * get(). Will decrement again in put() where we will call destroy()
5569 + * to actually free the memory if it reaches 0.
5570 + */
5571 + WARN_ON(cl->refcnt == 0);
5572 +
5573 + sch_tree_unlock(sch);
5574 + return 0;
5575 +}
5576 +
5577 +/* Get the class' child qdisc, if any */
5578 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
5579 +{
5580 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5581 +
5582 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5583 + __func__, cl->common.classid, sch->handle);
5584 +
5585 + switch (cl->type) {
5586 + case CEETM_ROOT:
5587 + return cl->root.child;
5588 +
5589 + case CEETM_PRIO:
5590 + return cl->prio.child;
5591 + }
5592 +
5593 + return NULL;
5594 +}
5595 +
5596 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
5597 + struct Qdisc *new, struct Qdisc **old)
5598 +{
5599 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
5600 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
5601 + return -EOPNOTSUPP;
5602 + }
5603 +
5604 + return 0;
5605 +}
5606 +
5607 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
5608 + struct gnet_dump *d)
5609 +{
5610 + unsigned int i;
5611 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5612 + struct gnet_stats_basic_packed tmp_bstats;
5613 + struct ceetm_class_stats *cstats = NULL;
5614 + struct qm_ceetm_cq *cq = NULL;
5615 + struct tc_ceetm_xstats xstats;
5616 +
5617 + memset(&xstats, 0, sizeof(xstats));
5618 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
5619 +
5620 + switch (cl->type) {
5621 + case CEETM_ROOT:
5622 + return 0;
5623 + case CEETM_PRIO:
5624 + cq = cl->prio.cq;
5625 + break;
5626 + case CEETM_WBFS:
5627 + cq = cl->wbfs.cq;
5628 + break;
5629 + }
5630 +
5631 + for_each_online_cpu(i) {
5632 + switch (cl->type) {
5633 + case CEETM_PRIO:
5634 + cstats = per_cpu_ptr(cl->prio.cstats, i);
5635 + break;
5636 + case CEETM_WBFS:
5637 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
5638 + break;
5639 + }
5640 +
5641 + if (cstats) {
5642 + xstats.ern_drop_count += cstats->ern_drop_count;
5643 + xstats.congested_count += cstats->congested_count;
5644 + tmp_bstats.bytes += cstats->bstats.bytes;
5645 + tmp_bstats.packets += cstats->bstats.packets;
5646 + }
5647 + }
5648 +
5649 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
5650 + d, NULL, &tmp_bstats) < 0)
5651 + return -1;
5652 +
5653 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
5654 + &xstats.frame_count,
5655 + &xstats.byte_count))
5656 + return -1;
5657 +
5658 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
5659 +}
5660 +
5661 +static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg)
5662 +{
5663 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5664 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5665 + struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list;
5666 +
5667 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5668 + cl ? cl->common.classid : 0, sch->handle);
5669 + return fl;
5670 +}
5671 +
5672 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
5673 + u32 classid)
5674 +{
5675 + struct ceetm_class *cl = ceetm_find(classid, sch);
5676 +
5677 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5678 + cl ? cl->common.classid : 0, sch->handle);
5679 + return (unsigned long)cl;
5680 +}
5681 +
5682 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
5683 +{
5684 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5685 +
5686 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5687 + cl ? cl->common.classid : 0, sch->handle);
5688 +}
5689 +
5690 +const struct Qdisc_class_ops ceetm_cls_ops = {
5691 + .graft = ceetm_cls_graft,
5692 + .leaf = ceetm_cls_leaf,
5693 + .get = ceetm_cls_get,
5694 + .put = ceetm_cls_put,
5695 + .change = ceetm_cls_change,
5696 + .delete = ceetm_cls_delete,
5697 + .walk = ceetm_cls_walk,
5698 + .tcf_chain = ceetm_tcf_chain,
5699 + .bind_tcf = ceetm_tcf_bind,
5700 + .unbind_tcf = ceetm_tcf_unbind,
5701 + .dump = ceetm_cls_dump,
5702 + .dump_stats = ceetm_cls_dump_stats,
5703 +};
5704 +
5705 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
5706 + .id = "ceetm",
5707 + .priv_size = sizeof(struct ceetm_qdisc),
5708 + .cl_ops = &ceetm_cls_ops,
5709 + .init = ceetm_init,
5710 + .destroy = ceetm_destroy,
5711 + .change = ceetm_change,
5712 + .dump = ceetm_dump,
5713 + .attach = ceetm_attach,
5714 + .owner = THIS_MODULE,
5715 +};
5716 +
5717 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
5718 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
5719 + struct Qdisc *sch, int *qerr,
5720 + bool *act_drop)
5721 +{
5722 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5723 + struct ceetm_class *cl = NULL, *wbfs_cl;
5724 + struct tcf_result res;
5725 + struct tcf_proto *tcf;
5726 + int result;
5727 +
5728 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
5729 + tcf = priv->filter_list;
5730 + while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
5731 +#ifdef CONFIG_NET_CLS_ACT
5732 + switch (result) {
5733 + case TC_ACT_QUEUED:
5734 + case TC_ACT_STOLEN:
5735 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
5736 + case TC_ACT_SHOT:
5737 + /* No valid class found due to action */
5738 + *act_drop = true;
5739 + return NULL;
5740 + }
5741 +#endif
5742 + cl = (void *)res.class;
5743 + if (!cl) {
5744 + if (res.classid == sch->handle) {
5745 + /* The filter leads to the qdisc */
5746 + /* TODO default qdisc */
5747 + return NULL;
5748 + }
5749 +
5750 + cl = ceetm_find(res.classid, sch);
5751 + if (!cl)
5752 + /* The filter leads to an invalid class */
5753 + break;
5754 + }
5755 +
5756 + /* The class might have its own filters attached */
5757 + tcf = cl->filter_list;
5758 + }
5759 +
5760 + if (!cl) {
5761 + /* No valid class found */
5762 + /* TODO default qdisc */
5763 + return NULL;
5764 + }
5765 +
5766 + switch (cl->type) {
5767 + case CEETM_ROOT:
5768 + if (cl->root.child) {
5769 + /* Run the prio qdisc classifiers */
5770 + return ceetm_classify(skb, cl->root.child, qerr,
5771 + act_drop);
5772 + } else {
5773 + /* The root class does not have a child prio qdisc */
5774 + /* TODO default qdisc */
5775 + return NULL;
5776 + }
5777 + case CEETM_PRIO:
5778 + if (cl->prio.child) {
5779 + /* If filters lead to a wbfs class, return it.
5780 + * Otherwise, return the prio class
5781 + */
5782 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
5783 + act_drop);
5784 + /* A NULL result might indicate either an erroneous
5785 + * filter, or no filters at all. We will assume the
5786 + * latter
5787 + */
5788 + return wbfs_cl ? : cl;
5789 + }
5790 + }
5791 +
5792 + /* For wbfs and childless prio classes, return the class directly */
5793 + return cl;
5794 +}
5795 +
5796 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
5797 +{
5798 + int ret;
5799 + bool act_drop = false;
5800 + struct Qdisc *sch = net_dev->qdisc;
5801 + struct ceetm_class *cl;
5802 + struct dpa_priv_s *priv_dpa;
5803 + struct qman_fq *egress_fq, *conf_fq;
5804 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5805 + struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats);
5806 + struct ceetm_class_stats *cstats;
5807 + const int queue_mapping = dpa_get_queue_mapping(skb);
5808 + spinlock_t *root_lock = qdisc_lock(sch);
5809 +
5810 + spin_lock(root_lock);
5811 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
5812 + spin_unlock(root_lock);
5813 +
5814 +#ifdef CONFIG_NET_CLS_ACT
5815 + if (act_drop) {
5816 + if (ret & __NET_XMIT_BYPASS)
5817 + qstats->drops++;
5818 + goto drop;
5819 + }
5820 +#endif
5821 + /* TODO default class */
5822 + if (unlikely(!cl)) {
5823 + qstats->drops++;
5824 + goto drop;
5825 + }
5826 +
5827 + priv_dpa = netdev_priv(net_dev);
5828 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
5829 +
5830 + /* Choose the proper tx fq and update the basic stats (bytes and
5831 + * packets sent by the class)
5832 + */
5833 + switch (cl->type) {
5834 + case CEETM_PRIO:
5835 + egress_fq = &cl->prio.fq->fq;
5836 + cstats = this_cpu_ptr(cl->prio.cstats);
5837 + break;
5838 + case CEETM_WBFS:
5839 + egress_fq = &cl->wbfs.fq->fq;
5840 + cstats = this_cpu_ptr(cl->wbfs.cstats);
5841 + break;
5842 + default:
5843 + qstats->drops++;
5844 + goto drop;
5845 + }
5846 +
5847 + bstats_update(&cstats->bstats, skb);
5848 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
5849 +
5850 +drop:
5851 + dev_kfree_skb_any(skb);
5852 + return NET_XMIT_SUCCESS;
5853 +}
5854 +
5855 +static int __init ceetm_register(void)
5856 +{
5857 + int _errno = 0;
5858 +
5859 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
5860 +
5861 + _errno = register_qdisc(&ceetm_qdisc_ops);
5862 + if (unlikely(_errno))
5863 + pr_err(KBUILD_MODNAME
5864 + ": %s:%hu:%s(): register_qdisc() = %d\n",
5865 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
5866 +
5867 + return _errno;
5868 +}
5869 +
5870 +static void __exit ceetm_unregister(void)
5871 +{
5872 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
5873 + KBUILD_BASENAME ".c", __func__);
5874 +
5875 + unregister_qdisc(&ceetm_qdisc_ops);
5876 +}
5877 +
5878 +module_init(ceetm_register);
5879 +module_exit(ceetm_unregister);
5880 --- /dev/null
5881 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
5882 @@ -0,0 +1,237 @@
5883 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5884 + *
5885 + * Redistribution and use in source and binary forms, with or without
5886 + * modification, are permitted provided that the following conditions are met:
5887 + * * Redistributions of source code must retain the above copyright
5888 + * notice, this list of conditions and the following disclaimer.
5889 + * * Redistributions in binary form must reproduce the above copyright
5890 + * notice, this list of conditions and the following disclaimer in the
5891 + * documentation and/or other materials provided with the distribution.
5892 + * * Neither the name of Freescale Semiconductor nor the
5893 + * names of its contributors may be used to endorse or promote products
5894 + * derived from this software without specific prior written permission.
5895 + *
5896 + *
5897 + * ALTERNATIVELY, this software may be distributed under the terms of the
5898 + * GNU General Public License ("GPL") as published by the Free Software
5899 + * Foundation, either version 2 of that License or (at your option) any
5900 + * later version.
5901 + *
5902 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5903 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5904 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5905 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5906 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5907 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5908 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5909 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5910 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5911 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5912 + */
5913 +
5914 +#ifndef __DPAA_ETH_CEETM_H
5915 +#define __DPAA_ETH_CEETM_H
5916 +
5917 +#include <net/pkt_sched.h>
5918 +#include <net/pkt_cls.h>
5919 +#include <net/netlink.h>
5920 +#include <lnxwrp_fm.h>
5921 +
5922 +#include "mac.h"
5923 +#include "dpaa_eth_common.h"
5924 +
5925 +/* Mask to determine the sub-portal id from a channel number */
5926 +#define CHANNEL_SP_MASK 0x1f
5927 +/* The number of the last channel that services DCP0, connected to FMan 0.
5928 + * Value validated for B4 and T series platforms.
5929 + */
5930 +#define DCP0_MAX_CHANNEL 0x80f
5931 +/* A2V=1 - field A2 is valid
5932 + * A0V=1 - field A0 is valid - enables frame confirmation
5933 + * OVOM=1 - override operation mode bits with values from A2
5934 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
5935 + * NL=0 - the BMI releases all the internal buffers
5936 + */
5937 +#define CEETM_CONTEXT_A 0x1a00000080000000
5938 +/* The ratio between the superior and inferior congestion state thresholds. The
5939 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
5940 + * scheduling).
5941 + */
5942 +#define CEETM_CCGR_RATIO 0.875
5943 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
5944 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
5945 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
5946 + * hex).
5947 + */
5948 +#define PFIFO_MIN_OFFSET 0x21
5949 +
5950 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
5951 +#define CEETM_MAX_PRIO_QCOUNT 8
5952 +#define CEETM_MAX_WBFS_QCOUNT 8
5953 +#define CEETM_MIN_WBFS_QCOUNT 4
5954 +
5955 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
5956 + * and/or 12-15 for group B).
5957 + */
5958 +#define WBFS_GRP_A_OFFSET 8
5959 +#define WBFS_GRP_B_OFFSET 12
5960 +
5961 +#define WBFS_GRP_A 1
5962 +#define WBFS_GRP_B 2
5963 +#define WBFS_GRP_LARGE 3
5964 +
5965 +enum {
5966 + TCA_CEETM_UNSPEC,
5967 + TCA_CEETM_COPT,
5968 + TCA_CEETM_QOPS,
5969 + __TCA_CEETM_MAX,
5970 +};
5971 +
5972 +/* CEETM configuration types */
5973 +enum {
5974 + CEETM_ROOT = 1,
5975 + CEETM_PRIO,
5976 + CEETM_WBFS
5977 +};
5978 +
5979 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
5980 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
5981 +
5982 +struct ceetm_class;
5983 +struct ceetm_qdisc_stats;
5984 +struct ceetm_class_stats;
5985 +
5986 +struct ceetm_fq {
5987 + struct qman_fq fq;
5988 + struct net_device *net_dev;
5989 + struct ceetm_class *ceetm_cls;
5990 +};
5991 +
5992 +struct root_q {
5993 + struct Qdisc **qdiscs;
5994 + __u16 overhead;
5995 + __u32 rate;
5996 + __u32 ceil;
5997 + struct qm_ceetm_sp *sp;
5998 + struct qm_ceetm_lni *lni;
5999 + struct ceetm_qdisc_stats __percpu *qstats;
6000 +};
6001 +
6002 +struct prio_q {
6003 + __u16 qcount;
6004 + struct ceetm_class *parent;
6005 +};
6006 +
6007 +struct wbfs_q {
6008 + __u16 qcount;
6009 + int group_type;
6010 + struct ceetm_class *parent;
6011 + __u16 cr;
6012 + __u16 er;
6013 +};
6014 +
6015 +struct ceetm_qdisc {
6016 + int type; /* LNI/CHNL/WBFS */
6017 + bool shaped;
6018 + union {
6019 + struct root_q root;
6020 + struct prio_q prio;
6021 + struct wbfs_q wbfs;
6022 + };
6023 + struct Qdisc_class_hash clhash;
6024 + struct tcf_proto *filter_list; /* qdisc attached filters */
6025 +};
6026 +
6027 +/* CEETM Qdisc configuration parameters */
6028 +struct tc_ceetm_qopt {
6029 + __u32 type;
6030 + __u16 shaped;
6031 + __u16 qcount;
6032 + __u16 overhead;
6033 + __u32 rate;
6034 + __u32 ceil;
6035 + __u16 cr;
6036 + __u16 er;
6037 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
6038 +};
6039 +
6040 +struct root_c {
6041 + unsigned int rate;
6042 + unsigned int ceil;
6043 + unsigned int tbl;
6044 + bool wbfs_grp_a;
6045 + bool wbfs_grp_b;
6046 + bool wbfs_grp_large;
6047 + struct Qdisc *child;
6048 + struct qm_ceetm_channel *ch;
6049 +};
6050 +
6051 +struct prio_c {
6052 + bool cr;
6053 + bool er;
6054 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6055 + struct qm_ceetm_lfq *lfq;
6056 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6057 + struct qm_ceetm_ccg *ccg;
6058 + /* only one wbfs can be linked to one priority CQ */
6059 + struct Qdisc *child;
6060 + struct ceetm_class_stats __percpu *cstats;
6061 +};
6062 +
6063 +struct wbfs_c {
6064 + __u8 weight; /* The weight of the class between 1 and 248 */
6065 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6066 + struct qm_ceetm_lfq *lfq;
6067 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6068 + struct qm_ceetm_ccg *ccg;
6069 + struct ceetm_class_stats __percpu *cstats;
6070 +};
6071 +
6072 +struct ceetm_class {
6073 + struct Qdisc_class_common common;
6074 + int refcnt; /* usage count of this class */
6075 + struct tcf_proto *filter_list; /* class attached filters */
6076 + struct Qdisc *parent;
6077 + bool shaped;
6078 + int type; /* ROOT/PRIO/WBFS */
6079 + union {
6080 + struct root_c root;
6081 + struct prio_c prio;
6082 + struct wbfs_c wbfs;
6083 + };
6084 +};
6085 +
6086 +/* CEETM Class configuration parameters */
6087 +struct tc_ceetm_copt {
6088 + __u32 type;
6089 + __u16 shaped;
6090 + __u32 rate;
6091 + __u32 ceil;
6092 + __u16 tbl;
6093 + __u16 cr;
6094 + __u16 er;
6095 + __u8 weight;
6096 +};
6097 +
6098 +/* CEETM stats */
6099 +struct ceetm_qdisc_stats {
6100 + __u32 drops;
6101 +};
6102 +
6103 +struct ceetm_class_stats {
6104 + /* Software counters */
6105 + struct gnet_stats_basic_packed bstats;
6106 + __u32 ern_drop_count;
6107 + __u32 congested_count;
6108 +};
6109 +
6110 +struct tc_ceetm_xstats {
6111 + __u32 ern_drop_count;
6112 + __u32 congested_count;
6113 + /* Hardware counters */
6114 + __u64 frame_count;
6115 + __u64 byte_count;
6116 +};
6117 +
6118 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
6119 +#endif
6120 --- /dev/null
6121 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6122 @@ -0,0 +1,1811 @@
6123 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
6124 + *
6125 + * Redistribution and use in source and binary forms, with or without
6126 + * modification, are permitted provided that the following conditions are met:
6127 + * * Redistributions of source code must retain the above copyright
6128 + * notice, this list of conditions and the following disclaimer.
6129 + * * Redistributions in binary form must reproduce the above copyright
6130 + * notice, this list of conditions and the following disclaimer in the
6131 + * documentation and/or other materials provided with the distribution.
6132 + * * Neither the name of Freescale Semiconductor nor the
6133 + * names of its contributors may be used to endorse or promote products
6134 + * derived from this software without specific prior written permission.
6135 + *
6136 + *
6137 + * ALTERNATIVELY, this software may be distributed under the terms of the
6138 + * GNU General Public License ("GPL") as published by the Free Software
6139 + * Foundation, either version 2 of that License or (at your option) any
6140 + * later version.
6141 + *
6142 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6143 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6144 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6145 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6146 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6147 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6148 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6149 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6150 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6151 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6152 + */
6153 +
6154 +#include <linux/init.h>
6155 +#include <linux/module.h>
6156 +#include <linux/of_platform.h>
6157 +#include <linux/of_net.h>
6158 +#include <linux/etherdevice.h>
6159 +#include <linux/kthread.h>
6160 +#include <linux/percpu.h>
6161 +#include <linux/highmem.h>
6162 +#include <linux/sort.h>
6163 +#include <linux/fsl_qman.h>
6164 +#include <linux/ip.h>
6165 +#include <linux/ipv6.h>
6166 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
6167 +#include "dpaa_eth.h"
6168 +#include "dpaa_eth_common.h"
6169 +#ifdef CONFIG_FSL_DPAA_1588
6170 +#include "dpaa_1588.h"
6171 +#endif
6172 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6173 +#include "dpaa_debugfs.h"
6174 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6175 +#include "mac.h"
6176 +
6177 +/* Size in bytes of the FQ taildrop threshold */
6178 +#define DPA_FQ_TD 0x200000
6179 +
6180 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6181 +struct ptp_priv_s ptp_priv;
6182 +#endif
6183 +
6184 +static struct dpa_bp *dpa_bp_array[64];
6185 +
6186 +int dpa_max_frm;
6187 +EXPORT_SYMBOL(dpa_max_frm);
6188 +
6189 +int dpa_rx_extra_headroom;
6190 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
6191 +
6192 +int dpa_num_cpus = NR_CPUS;
6193 +
6194 +static const struct fqid_cell tx_confirm_fqids[] = {
6195 + {0, DPAA_ETH_TX_QUEUES}
6196 +};
6197 +
6198 +static struct fqid_cell default_fqids[][3] = {
6199 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
6200 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
6201 +};
6202 +
6203 +static const char fsl_qman_frame_queues[][25] = {
6204 + [RX] = "fsl,qman-frame-queues-rx",
6205 + [TX] = "fsl,qman-frame-queues-tx"
6206 +};
6207 +#ifdef CONFIG_FSL_DPAA_HOOKS
6208 +/* A set of callbacks for hooking into the fastpath at different points. */
6209 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
6210 +EXPORT_SYMBOL(dpaa_eth_hooks);
6211 +/* This function should only be called on the probe paths, since it makes no
6212 + * effort to guarantee consistency of the destination hooks structure.
6213 + */
6214 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
6215 +{
6216 + if (hooks)
6217 + dpaa_eth_hooks = *hooks;
6218 + else
6219 + pr_err("NULL pointer to hooks!\n");
6220 +}
6221 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
6222 +#endif
6223 +
6224 +int dpa_netdev_init(struct net_device *net_dev,
6225 + const uint8_t *mac_addr,
6226 + uint16_t tx_timeout)
6227 +{
6228 + int err;
6229 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6230 + struct device *dev = net_dev->dev.parent;
6231 +
6232 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
6233 +
6234 + net_dev->features |= net_dev->hw_features;
6235 + net_dev->vlan_features = net_dev->features;
6236 +
6237 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
6238 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
6239 +
6240 + net_dev->ethtool_ops = &dpa_ethtool_ops;
6241 +
6242 + net_dev->needed_headroom = priv->tx_headroom;
6243 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
6244 +
6245 + err = register_netdev(net_dev);
6246 + if (err < 0) {
6247 + dev_err(dev, "register_netdev() = %d\n", err);
6248 + return err;
6249 + }
6250 +
6251 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6252 + /* create debugfs entry for this net_device */
6253 + err = dpa_netdev_debugfs_create(net_dev);
6254 + if (err) {
6255 + unregister_netdev(net_dev);
6256 + return err;
6257 + }
6258 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6259 +
6260 + return 0;
6261 +}
6262 +EXPORT_SYMBOL(dpa_netdev_init);
6263 +
6264 +int __cold dpa_start(struct net_device *net_dev)
6265 +{
6266 + int err, i;
6267 + struct dpa_priv_s *priv;
6268 + struct mac_device *mac_dev;
6269 +
6270 + priv = netdev_priv(net_dev);
6271 + mac_dev = priv->mac_dev;
6272 +
6273 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
6274 + if (err < 0) {
6275 + if (netif_msg_ifup(priv))
6276 + netdev_err(net_dev, "init_phy() = %d\n", err);
6277 + return err;
6278 + }
6279 +
6280 + for_each_port_device(i, mac_dev->port_dev) {
6281 + err = fm_port_enable(mac_dev->port_dev[i]);
6282 + if (err)
6283 + goto mac_start_failed;
6284 + }
6285 +
6286 + err = priv->mac_dev->start(mac_dev);
6287 + if (err < 0) {
6288 + if (netif_msg_ifup(priv))
6289 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
6290 + goto mac_start_failed;
6291 + }
6292 +
6293 + netif_tx_start_all_queues(net_dev);
6294 +
6295 + return 0;
6296 +
6297 +mac_start_failed:
6298 + for_each_port_device(i, mac_dev->port_dev)
6299 + fm_port_disable(mac_dev->port_dev[i]);
6300 +
6301 + return err;
6302 +}
6303 +EXPORT_SYMBOL(dpa_start);
6304 +
6305 +int __cold dpa_stop(struct net_device *net_dev)
6306 +{
6307 + int _errno, i, err;
6308 + struct dpa_priv_s *priv;
6309 + struct mac_device *mac_dev;
6310 +
6311 + priv = netdev_priv(net_dev);
6312 + mac_dev = priv->mac_dev;
6313 +
6314 + netif_tx_stop_all_queues(net_dev);
6315 + /* Allow the Fman (Tx) port to process in-flight frames before we
6316 + * try switching it off.
6317 + */
6318 + usleep_range(5000, 10000);
6319 +
6320 + _errno = mac_dev->stop(mac_dev);
6321 + if (unlikely(_errno < 0))
6322 + if (netif_msg_ifdown(priv))
6323 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
6324 + _errno);
6325 +
6326 + for_each_port_device(i, mac_dev->port_dev) {
6327 + err = fm_port_disable(mac_dev->port_dev[i]);
6328 + _errno = err ? err : _errno;
6329 + }
6330 +
6331 + if (mac_dev->phy_dev)
6332 + phy_disconnect(mac_dev->phy_dev);
6333 + mac_dev->phy_dev = NULL;
6334 +
6335 + return _errno;
6336 +}
6337 +EXPORT_SYMBOL(dpa_stop);
6338 +
6339 +void __cold dpa_timeout(struct net_device *net_dev)
6340 +{
6341 + const struct dpa_priv_s *priv;
6342 + struct dpa_percpu_priv_s *percpu_priv;
6343 +
6344 + priv = netdev_priv(net_dev);
6345 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
6346 +
6347 + if (netif_msg_timer(priv))
6348 + netdev_crit(net_dev, "Transmit timeout!\n");
6349 +
6350 + percpu_priv->stats.tx_errors++;
6351 +}
6352 +EXPORT_SYMBOL(dpa_timeout);
6353 +
6354 +/* net_device */
6355 +
6356 +/**
6357 + * @param net_dev the device for which statistics are calculated
6358 + * @param stats the function fills this structure with the device's statistics
6359 + * @return the address of the structure containing the statistics
6360 + *
6361 + * Calculates the statistics for the given device by adding the statistics
6362 + * collected by each CPU.
6363 + */
6364 +void __cold
6365 +dpa_get_stats64(struct net_device *net_dev,
6366 + struct rtnl_link_stats64 *stats)
6367 +{
6368 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6369 + u64 *cpustats;
6370 + u64 *netstats = (u64 *)stats;
6371 + int i, j;
6372 + struct dpa_percpu_priv_s *percpu_priv;
6373 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
6374 +
6375 + for_each_possible_cpu(i) {
6376 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
6377 +
6378 + cpustats = (u64 *)&percpu_priv->stats;
6379 +
6380 + for (j = 0; j < numstats; j++)
6381 + netstats[j] += cpustats[j];
6382 + }
6383 +}
6384 +EXPORT_SYMBOL(dpa_get_stats64);
6385 +
6386 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
6387 +{
6388 + const int max_mtu = dpa_get_max_mtu();
6389 +
6390 + /* Make sure we don't exceed the Ethernet controller's MAXFRM */
6391 + if (new_mtu < 68 || new_mtu > max_mtu) {
6392 + netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n",
6393 + new_mtu, 68, max_mtu);
6394 + return -EINVAL;
6395 + }
6396 + net_dev->mtu = new_mtu;
6397 +
6398 + return 0;
6399 +}
6400 +EXPORT_SYMBOL(dpa_change_mtu);
6401 +
6402 +/* .ndo_init callback */
6403 +int dpa_ndo_init(struct net_device *net_dev)
6404 +{
6405 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
6406 + * we choose conservatively and let the user explicitly set a higher
6407 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
6408 + * in the same LAN.
6409 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
6410 + * start with the maximum allowed.
6411 + */
6412 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
6413 +
6414 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
6415 + net_dev->mtu = init_mtu;
6416 +
6417 + return 0;
6418 +}
6419 +EXPORT_SYMBOL(dpa_ndo_init);
6420 +
6421 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
6422 +{
6423 + /* Not much to do here for now */
6424 + dev->features = features;
6425 + return 0;
6426 +}
6427 +EXPORT_SYMBOL(dpa_set_features);
6428 +
6429 +netdev_features_t dpa_fix_features(struct net_device *dev,
6430 + netdev_features_t features)
6431 +{
6432 + netdev_features_t unsupported_features = 0;
6433 +
6434 + /* In theory we should never be requested to enable features that
6435 + * we didn't set in netdev->features and netdev->hw_features at probe
6436 + * time, but double check just to be on the safe side.
6437 + * We don't support enabling Rx csum through ethtool yet
6438 + */
6439 + unsupported_features |= NETIF_F_RXCSUM;
6440 +
6441 + features &= ~unsupported_features;
6442 +
6443 + return features;
6444 +}
6445 +EXPORT_SYMBOL(dpa_fix_features);
6446 +
6447 +#ifdef CONFIG_FSL_DPAA_TS
6448 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
6449 + const void *data)
6450 +{
6451 + u64 *ts, ns;
6452 +
6453 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
6454 + data);
6455 +
6456 + if (!ts || *ts == 0)
6457 + return 0;
6458 +
6459 + be64_to_cpus(ts);
6460 +
6461 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
6462 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
6463 +
6464 + return ns;
6465 +}
6466 +
6467 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
6468 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
6469 +{
6470 + u64 ns;
6471 +
6472 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
6473 +
6474 + if (ns == 0)
6475 + return -EINVAL;
6476 +
6477 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
6478 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
6479 +
6480 + return 0;
6481 +}
6482 +
6483 +static void dpa_ts_tx_enable(struct net_device *dev)
6484 +{
6485 + struct dpa_priv_s *priv = netdev_priv(dev);
6486 + struct mac_device *mac_dev = priv->mac_dev;
6487 +
6488 + if (mac_dev->fm_rtc_enable)
6489 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6490 + if (mac_dev->ptp_enable)
6491 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6492 +
6493 + priv->ts_tx_en = true;
6494 +}
6495 +
6496 +static void dpa_ts_tx_disable(struct net_device *dev)
6497 +{
6498 + struct dpa_priv_s *priv = netdev_priv(dev);
6499 +
6500 +#if 0
6501 +/* the RTC might be needed by the Rx Ts, cannot disable here
6502 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6503 + */
6504 + struct mac_device *mac_dev = priv->mac_dev;
6505 +
6506 + if (mac_dev->fm_rtc_disable)
6507 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6508 +
6509 + if (mac_dev->ptp_disable)
6510 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6511 +#endif
6512 +
6513 + priv->ts_tx_en = false;
6514 +}
6515 +
6516 +static void dpa_ts_rx_enable(struct net_device *dev)
6517 +{
6518 + struct dpa_priv_s *priv = netdev_priv(dev);
6519 + struct mac_device *mac_dev = priv->mac_dev;
6520 +
6521 + if (mac_dev->fm_rtc_enable)
6522 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6523 + if (mac_dev->ptp_enable)
6524 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6525 +
6526 + priv->ts_rx_en = true;
6527 +}
6528 +
6529 +static void dpa_ts_rx_disable(struct net_device *dev)
6530 +{
6531 + struct dpa_priv_s *priv = netdev_priv(dev);
6532 +
6533 +#if 0
6534 +/* the RTC might be needed by the Tx Ts, cannot disable here
6535 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6536 + */
6537 + struct mac_device *mac_dev = priv->mac_dev;
6538 +
6539 + if (mac_dev->fm_rtc_disable)
6540 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6541 +
6542 + if (mac_dev->ptp_disable)
6543 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6544 +#endif
6545 +
6546 + priv->ts_rx_en = false;
6547 +}
6548 +
6549 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6550 +{
6551 + struct hwtstamp_config config;
6552 +
6553 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
6554 + return -EFAULT;
6555 +
6556 + switch (config.tx_type) {
6557 + case HWTSTAMP_TX_OFF:
6558 + dpa_ts_tx_disable(dev);
6559 + break;
6560 + case HWTSTAMP_TX_ON:
6561 + dpa_ts_tx_enable(dev);
6562 + break;
6563 + default:
6564 + return -ERANGE;
6565 + }
6566 +
6567 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
6568 + dpa_ts_rx_disable(dev);
6569 + else {
6570 + dpa_ts_rx_enable(dev);
6571 + /* TS is set for all frame types, not only those requested */
6572 + config.rx_filter = HWTSTAMP_FILTER_ALL;
6573 + }
6574 +
6575 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
6576 + -EFAULT : 0;
6577 +}
6578 +#endif /* CONFIG_FSL_DPAA_TS */
6579 +
6580 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6581 +{
6582 +#ifdef CONFIG_FSL_DPAA_1588
6583 + struct dpa_priv_s *priv = netdev_priv(dev);
6584 +#endif
6585 + int ret = 0;
6586 +
6587 + /* at least one timestamping feature must be enabled */
6588 +#ifdef CONFIG_FSL_DPAA_TS
6589 + if (!netif_running(dev))
6590 +#endif
6591 + return -EINVAL;
6592 +
6593 +#ifdef CONFIG_FSL_DPAA_TS
6594 + if (cmd == SIOCSHWTSTAMP)
6595 + return dpa_ts_ioctl(dev, rq, cmd);
6596 +#endif /* CONFIG_FSL_DPAA_TS */
6597 +
6598 +#ifdef CONFIG_FSL_DPAA_1588
6599 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
6600 + if (priv->tsu && priv->tsu->valid)
6601 + ret = dpa_ioctl_1588(dev, rq, cmd);
6602 + else
6603 + ret = -ENODEV;
6604 + }
6605 +#endif
6606 +
6607 + return ret;
6608 +}
6609 +EXPORT_SYMBOL(dpa_ioctl);
6610 +
6611 +int __cold dpa_remove(struct platform_device *of_dev)
6612 +{
6613 + int err;
6614 + struct device *dev;
6615 + struct net_device *net_dev;
6616 + struct dpa_priv_s *priv;
6617 +
6618 + dev = &of_dev->dev;
6619 + net_dev = dev_get_drvdata(dev);
6620 +
6621 + priv = netdev_priv(net_dev);
6622 +
6623 + dpaa_eth_sysfs_remove(dev);
6624 +
6625 + dev_set_drvdata(dev, NULL);
6626 + unregister_netdev(net_dev);
6627 +
6628 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
6629 +
6630 + qman_delete_cgr_safe(&priv->ingress_cgr);
6631 + qman_release_cgrid(priv->ingress_cgr.cgrid);
6632 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
6633 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
6634 +
6635 + dpa_private_napi_del(net_dev);
6636 +
6637 + dpa_bp_free(priv);
6638 +
6639 + if (priv->buf_layout)
6640 + devm_kfree(dev, priv->buf_layout);
6641 +
6642 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6643 + /* remove debugfs entry for this net_device */
6644 + dpa_netdev_debugfs_remove(net_dev);
6645 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6646 +
6647 +#ifdef CONFIG_FSL_DPAA_1588
6648 + if (priv->tsu && priv->tsu->valid)
6649 + dpa_ptp_cleanup(priv);
6650 +#endif
6651 +
6652 + free_netdev(net_dev);
6653 +
6654 + return err;
6655 +}
6656 +EXPORT_SYMBOL(dpa_remove);
6657 +
6658 +struct mac_device * __cold __must_check
6659 +__attribute__((nonnull))
6660 +dpa_mac_probe(struct platform_device *_of_dev)
6661 +{
6662 + struct device *dpa_dev, *dev;
6663 + struct device_node *mac_node;
6664 + struct platform_device *of_dev;
6665 + struct mac_device *mac_dev;
6666 +#ifdef CONFIG_FSL_DPAA_1588
6667 + int lenp;
6668 + const phandle *phandle_prop;
6669 + struct net_device *net_dev = NULL;
6670 + struct dpa_priv_s *priv = NULL;
6671 + struct device_node *timer_node;
6672 +#endif
6673 + dpa_dev = &_of_dev->dev;
6674 +
6675 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
6676 + if (unlikely(mac_node == NULL)) {
6677 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
6678 + return ERR_PTR(-EFAULT);
6679 + }
6680 +
6681 + of_dev = of_find_device_by_node(mac_node);
6682 + if (unlikely(of_dev == NULL)) {
6683 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
6684 + mac_node->full_name);
6685 + of_node_put(mac_node);
6686 + return ERR_PTR(-EINVAL);
6687 + }
6688 + of_node_put(mac_node);
6689 +
6690 + dev = &of_dev->dev;
6691 +
6692 + mac_dev = dev_get_drvdata(dev);
6693 + if (unlikely(mac_dev == NULL)) {
6694 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
6695 + dev_name(dev));
6696 + return ERR_PTR(-EINVAL);
6697 + }
6698 +
6699 +#ifdef CONFIG_FSL_DPAA_1588
6700 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
6701 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6702 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6703 + (mac_dev->speed == SPEED_1000)))) {
6704 + timer_node = of_find_node_by_phandle(*phandle_prop);
6705 + if (timer_node)
6706 + net_dev = dev_get_drvdata(dpa_dev);
6707 + if (timer_node && net_dev) {
6708 + priv = netdev_priv(net_dev);
6709 + if (!dpa_ptp_init(priv))
6710 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
6711 + mac_node->full_name);
6712 + }
6713 + }
6714 +#endif
6715 +
6716 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6717 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6718 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6719 + (mac_dev->speed == SPEED_1000))) {
6720 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
6721 + if (ptp_priv.node) {
6722 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
6723 + if (unlikely(ptp_priv.of_dev == NULL)) {
6724 + dev_err(dpa_dev,
6725 + "Cannot find device represented by timer_node\n");
6726 + of_node_put(ptp_priv.node);
6727 + return ERR_PTR(-EINVAL);
6728 + }
6729 + ptp_priv.mac_dev = mac_dev;
6730 + }
6731 + }
6732 +#endif
6733 + return mac_dev;
6734 +}
6735 +EXPORT_SYMBOL(dpa_mac_probe);
6736 +
6737 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
6738 +{
6739 + const struct dpa_priv_s *priv;
6740 + int _errno;
6741 + struct mac_device *mac_dev;
6742 +
6743 + priv = netdev_priv(net_dev);
6744 +
6745 + _errno = eth_mac_addr(net_dev, addr);
6746 + if (_errno < 0) {
6747 + if (netif_msg_drv(priv))
6748 + netdev_err(net_dev,
6749 + "eth_mac_addr() = %d\n",
6750 + _errno);
6751 + return _errno;
6752 + }
6753 +
6754 + mac_dev = priv->mac_dev;
6755 +
6756 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
6757 + net_dev->dev_addr);
6758 + if (_errno < 0) {
6759 + if (netif_msg_drv(priv))
6760 + netdev_err(net_dev,
6761 + "mac_dev->change_addr() = %d\n",
6762 + _errno);
6763 + return _errno;
6764 + }
6765 +
6766 + return 0;
6767 +}
6768 +EXPORT_SYMBOL(dpa_set_mac_address);
6769 +
6770 +void dpa_set_rx_mode(struct net_device *net_dev)
6771 +{
6772 + int _errno;
6773 + const struct dpa_priv_s *priv;
6774 +
6775 + priv = netdev_priv(net_dev);
6776 +
6777 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
6778 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
6779 + _errno = priv->mac_dev->set_promisc(
6780 + priv->mac_dev->get_mac_handle(priv->mac_dev),
6781 + priv->mac_dev->promisc);
6782 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6783 + netdev_err(net_dev,
6784 + "mac_dev->set_promisc() = %d\n",
6785 + _errno);
6786 + }
6787 +
6788 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
6789 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6790 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
6791 +}
6792 +EXPORT_SYMBOL(dpa_set_rx_mode);
6793 +
6794 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
6795 + struct dpa_buffer_layout_s *layout)
6796 +{
6797 + struct fm_port_params params;
6798 +
6799 + /* Rx */
6800 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
6801 + layout[RX].parse_results = true;
6802 + layout[RX].hash_results = true;
6803 +#ifdef CONFIG_FSL_DPAA_TS
6804 + layout[RX].time_stamp = true;
6805 +#endif
6806 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
6807 + layout[RX].manip_extra_space = params.manip_extra_space;
6808 + /* a value of zero for data alignment means "don't care", so align to
6809 + * a non-zero value to prevent FMD from using its own default
6810 + */
6811 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6812 +
6813 + /* Tx */
6814 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
6815 + layout[TX].parse_results = true;
6816 + layout[TX].hash_results = true;
6817 +#ifdef CONFIG_FSL_DPAA_TS
6818 + layout[TX].time_stamp = true;
6819 +#endif
6820 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
6821 + layout[TX].manip_extra_space = params.manip_extra_space;
6822 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6823 +}
6824 +EXPORT_SYMBOL(dpa_set_buffers_layout);
6825 +
6826 +int __attribute__((nonnull))
6827 +dpa_bp_alloc(struct dpa_bp *dpa_bp)
6828 +{
6829 + int err;
6830 + struct bman_pool_params bp_params;
6831 + struct platform_device *pdev;
6832 +
6833 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
6834 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
6835 + return -EINVAL;
6836 + }
6837 +
6838 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
6839 +#ifdef CONFIG_FMAN_PFC
6840 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
6841 + bp_params.thresholds[0] = bp_params.thresholds[2] =
6842 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
6843 + bp_params.thresholds[1] = bp_params.thresholds[3] =
6844 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
6845 +#endif
6846 +
6847 + /* If the pool is already specified, we only create one per bpid */
6848 + if (dpa_bpid2pool_use(dpa_bp->bpid))
6849 + return 0;
6850 +
6851 + if (dpa_bp->bpid == 0)
6852 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
6853 + else
6854 + bp_params.bpid = dpa_bp->bpid;
6855 +
6856 + dpa_bp->pool = bman_new_pool(&bp_params);
6857 + if (unlikely(dpa_bp->pool == NULL)) {
6858 + pr_err("bman_new_pool() failed\n");
6859 + return -ENODEV;
6860 + }
6861 +
6862 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
6863 +
6864 + pdev = platform_device_register_simple("dpaa_eth_bpool",
6865 + dpa_bp->bpid, NULL, 0);
6866 + if (IS_ERR(pdev)) {
6867 + pr_err("platform_device_register_simple() failed\n");
6868 + err = PTR_ERR(pdev);
6869 + goto pdev_register_failed;
6870 + }
6871 + {
6872 + struct dma_map_ops *ops = get_dma_ops(&pdev->dev);
6873 + ops->dma_supported = NULL;
6874 + }
6875 + err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
6876 + if (err) {
6877 + pr_err("dma_coerce_mask_and_coherent() failed\n");
6878 + goto pdev_mask_failed;
6879 + }
6880 +#ifdef CONFIG_FMAN_ARM
6881 + /* force coherency */
6882 + pdev->dev.archdata.dma_coherent = true;
6883 + arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
6884 +#endif
6885 +
6886 + dpa_bp->dev = &pdev->dev;
6887 +
6888 + if (dpa_bp->seed_cb) {
6889 + err = dpa_bp->seed_cb(dpa_bp);
6890 + if (err)
6891 + goto pool_seed_failed;
6892 + }
6893 +
6894 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
6895 +
6896 + return 0;
6897 +
6898 +pool_seed_failed:
6899 +pdev_mask_failed:
6900 + platform_device_unregister(pdev);
6901 +pdev_register_failed:
6902 + bman_free_pool(dpa_bp->pool);
6903 +
6904 + return err;
6905 +}
6906 +EXPORT_SYMBOL(dpa_bp_alloc);
6907 +
6908 +void dpa_bp_drain(struct dpa_bp *bp)
6909 +{
6910 + int ret, num = 8;
6911 +
6912 + do {
6913 + struct bm_buffer bmb[8];
6914 + int i;
6915 +
6916 + ret = bman_acquire(bp->pool, bmb, num, 0);
6917 + if (ret < 0) {
6918 + if (num == 8) {
6919 + /* we have less than 8 buffers left;
6920 + * drain them one by one
6921 + */
6922 + num = 1;
6923 + ret = 1;
6924 + continue;
6925 + } else {
6926 + /* Pool is fully drained */
6927 + break;
6928 + }
6929 + }
6930 +
6931 + for (i = 0; i < num; i++) {
6932 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
6933 +
6934 + dma_unmap_single(bp->dev, addr, bp->size,
6935 + DMA_BIDIRECTIONAL);
6936 +
6937 + bp->free_buf_cb(phys_to_virt(addr));
6938 + }
6939 + } while (ret > 0);
6940 +}
6941 +EXPORT_SYMBOL(dpa_bp_drain);
6942 +
6943 +static void __cold __attribute__((nonnull))
6944 +_dpa_bp_free(struct dpa_bp *dpa_bp)
6945 +{
6946 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
6947 +
6948 + /* the mapping between bpid and dpa_bp is done very late in the
6949 + * allocation procedure; if something failed before the mapping, the bp
6950 + * was not configured, therefore we don't need the below instructions
6951 + */
6952 + if (!bp)
6953 + return;
6954 +
6955 + if (!atomic_dec_and_test(&bp->refs))
6956 + return;
6957 +
6958 + if (bp->free_buf_cb)
6959 + dpa_bp_drain(bp);
6960 +
6961 + dpa_bp_array[bp->bpid] = NULL;
6962 + bman_free_pool(bp->pool);
6963 +
6964 + if (bp->dev)
6965 + platform_device_unregister(to_platform_device(bp->dev));
6966 +}
6967 +
6968 +void __cold __attribute__((nonnull))
6969 +dpa_bp_free(struct dpa_priv_s *priv)
6970 +{
6971 + int i;
6972 +
6973 + if (priv->dpa_bp)
6974 + for (i = 0; i < priv->bp_count; i++)
6975 + _dpa_bp_free(&priv->dpa_bp[i]);
6976 +}
6977 +EXPORT_SYMBOL(dpa_bp_free);
6978 +
6979 +struct dpa_bp *dpa_bpid2pool(int bpid)
6980 +{
6981 + return dpa_bp_array[bpid];
6982 +}
6983 +EXPORT_SYMBOL(dpa_bpid2pool);
6984 +
6985 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
6986 +{
6987 + dpa_bp_array[bpid] = dpa_bp;
6988 + atomic_set(&dpa_bp->refs, 1);
6989 +}
6990 +
6991 +bool dpa_bpid2pool_use(int bpid)
6992 +{
6993 + if (dpa_bpid2pool(bpid)) {
6994 + atomic_inc(&dpa_bp_array[bpid]->refs);
6995 + return true;
6996 + }
6997 +
6998 + return false;
6999 +}
7000 +
7001 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
7002 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
7003 + void *accel_priv, select_queue_fallback_t fallback)
7004 +{
7005 + return dpa_get_queue_mapping(skb);
7006 +}
7007 +EXPORT_SYMBOL(dpa_select_queue);
7008 +#endif
7009 +
7010 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
7011 + u32 fq_start,
7012 + u32 fq_count,
7013 + struct list_head *list,
7014 + enum dpa_fq_type fq_type)
7015 +{
7016 + int i;
7017 + struct dpa_fq *dpa_fq;
7018 +
7019 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
7020 + if (dpa_fq == NULL)
7021 + return NULL;
7022 +
7023 + for (i = 0; i < fq_count; i++) {
7024 + dpa_fq[i].fq_type = fq_type;
7025 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
7026 + dpa_fq[i].fqid = fq_start ?
7027 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
7028 + else
7029 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
7030 +
7031 + list_add_tail(&dpa_fq[i].list, list);
7032 + }
7033 +
7034 +#ifdef CONFIG_FMAN_PFC
7035 + if (fq_type == FQ_TYPE_TX)
7036 + for (i = 0; i < fq_count; i++)
7037 + dpa_fq[i].wq = i / dpa_num_cpus;
7038 + else
7039 +#endif
7040 + for (i = 0; i < fq_count; i++)
7041 + _dpa_assign_wq(dpa_fq + i);
7042 +
7043 + return dpa_fq;
7044 +}
7045 +EXPORT_SYMBOL(dpa_fq_alloc);
7046 +
7047 +/* Probing of FQs for MACful ports */
7048 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
7049 + struct fm_port_fqs *port_fqs,
7050 + bool alloc_tx_conf_fqs,
7051 + enum port_type ptype)
7052 +{
7053 + struct fqid_cell *fqids = NULL;
7054 + const void *fqids_off = NULL;
7055 + struct dpa_fq *dpa_fq = NULL;
7056 + struct device_node *np = dev->of_node;
7057 + int num_ranges;
7058 + int i, lenp;
7059 +
7060 + if (ptype == TX && alloc_tx_conf_fqs) {
7061 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
7062 + tx_confirm_fqids->count, list,
7063 + FQ_TYPE_TX_CONF_MQ))
7064 + goto fq_alloc_failed;
7065 + }
7066 +
7067 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
7068 + if (fqids_off == NULL) {
7069 + /* No dts definition, so use the defaults. */
7070 + fqids = default_fqids[ptype];
7071 + num_ranges = 3;
7072 + } else {
7073 + num_ranges = lenp / sizeof(*fqids);
7074 +
7075 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
7076 + GFP_KERNEL);
7077 + if (fqids == NULL)
7078 + goto fqids_alloc_failed;
7079 +
7080 + /* convert to CPU endianess */
7081 + for (i = 0; i < num_ranges; i++) {
7082 + fqids[i].start = be32_to_cpup(fqids_off +
7083 + i * sizeof(*fqids));
7084 + fqids[i].count = be32_to_cpup(fqids_off +
7085 + i * sizeof(*fqids) + sizeof(__be32));
7086 + }
7087 + }
7088 +
7089 + for (i = 0; i < num_ranges; i++) {
7090 + switch (i) {
7091 + case 0:
7092 + /* The first queue is the error queue */
7093 + if (fqids[i].count != 1)
7094 + goto invalid_error_queue;
7095 +
7096 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7097 + fqids[i].count, list,
7098 + ptype == RX ?
7099 + FQ_TYPE_RX_ERROR :
7100 + FQ_TYPE_TX_ERROR);
7101 + if (dpa_fq == NULL)
7102 + goto fq_alloc_failed;
7103 +
7104 + if (ptype == RX)
7105 + port_fqs->rx_errq = &dpa_fq[0];
7106 + else
7107 + port_fqs->tx_errq = &dpa_fq[0];
7108 + break;
7109 + case 1:
7110 + /* the second queue is the default queue */
7111 + if (fqids[i].count != 1)
7112 + goto invalid_default_queue;
7113 +
7114 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7115 + fqids[i].count, list,
7116 + ptype == RX ?
7117 + FQ_TYPE_RX_DEFAULT :
7118 + FQ_TYPE_TX_CONFIRM);
7119 + if (dpa_fq == NULL)
7120 + goto fq_alloc_failed;
7121 +
7122 + if (ptype == RX)
7123 + port_fqs->rx_defq = &dpa_fq[0];
7124 + else
7125 + port_fqs->tx_defq = &dpa_fq[0];
7126 + break;
7127 + default:
7128 + /* all subsequent queues are either RX* PCD or Tx */
7129 + if (ptype == RX) {
7130 + if (!dpa_fq_alloc(dev, fqids[i].start,
7131 + fqids[i].count, list,
7132 + FQ_TYPE_RX_PCD) ||
7133 + !dpa_fq_alloc(dev, fqids[i].start,
7134 + fqids[i].count, list,
7135 + FQ_TYPE_RX_PCD_HI_PRIO))
7136 + goto fq_alloc_failed;
7137 + } else {
7138 + if (!dpa_fq_alloc(dev, fqids[i].start,
7139 + fqids[i].count, list,
7140 + FQ_TYPE_TX))
7141 + goto fq_alloc_failed;
7142 + }
7143 + break;
7144 + }
7145 + }
7146 +
7147 + return 0;
7148 +
7149 +fq_alloc_failed:
7150 +fqids_alloc_failed:
7151 + dev_err(dev, "Cannot allocate memory for frame queues\n");
7152 + return -ENOMEM;
7153 +
7154 +invalid_default_queue:
7155 +invalid_error_queue:
7156 + dev_err(dev, "Too many default or error queues\n");
7157 + return -EINVAL;
7158 +}
7159 +EXPORT_SYMBOL(dpa_fq_probe_mac);
7160 +
7161 +static u32 rx_pool_channel;
7162 +static DEFINE_SPINLOCK(rx_pool_channel_init);
7163 +
7164 +int dpa_get_channel(void)
7165 +{
7166 + spin_lock(&rx_pool_channel_init);
7167 + if (!rx_pool_channel) {
7168 + u32 pool;
7169 + int ret = qman_alloc_pool(&pool);
7170 + if (!ret)
7171 + rx_pool_channel = pool;
7172 + }
7173 + spin_unlock(&rx_pool_channel_init);
7174 + if (!rx_pool_channel)
7175 + return -ENOMEM;
7176 + return rx_pool_channel;
7177 +}
7178 +EXPORT_SYMBOL(dpa_get_channel);
7179 +
7180 +void dpa_release_channel(void)
7181 +{
7182 + qman_release_pool(rx_pool_channel);
7183 +}
7184 +EXPORT_SYMBOL(dpa_release_channel);
7185 +
7186 +void dpaa_eth_add_channel(u16 channel)
7187 +{
7188 + const cpumask_t *cpus = qman_affine_cpus();
7189 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
7190 + int cpu;
7191 + struct qman_portal *portal;
7192 +
7193 + for_each_cpu(cpu, cpus) {
7194 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
7195 + qman_p_static_dequeue_add(portal, pool);
7196 + }
7197 +}
7198 +EXPORT_SYMBOL(dpaa_eth_add_channel);
7199 +
7200 +/**
7201 + * Congestion group state change notification callback.
7202 + * Stops the device's egress queues while they are congested and
7203 + * wakes them upon exiting congested state.
7204 + * Also updates some CGR-related stats.
7205 + */
7206 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
7207 +
7208 + int congested)
7209 +{
7210 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
7211 + struct dpa_priv_s, cgr_data.cgr);
7212 +
7213 + if (congested) {
7214 + priv->cgr_data.congestion_start_jiffies = jiffies;
7215 + netif_tx_stop_all_queues(priv->net_dev);
7216 + priv->cgr_data.cgr_congested_count++;
7217 + } else {
7218 + priv->cgr_data.congested_jiffies +=
7219 + (jiffies - priv->cgr_data.congestion_start_jiffies);
7220 + netif_tx_wake_all_queues(priv->net_dev);
7221 + }
7222 +}
7223 +
7224 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
7225 +{
7226 + struct qm_mcc_initcgr initcgr;
7227 + u32 cs_th;
7228 + int err;
7229 +
7230 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
7231 + if (err < 0) {
7232 + pr_err("Error %d allocating CGR ID\n", err);
7233 + goto out_error;
7234 + }
7235 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
7236 +
7237 + /* Enable Congestion State Change Notifications and CS taildrop */
7238 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
7239 + initcgr.cgr.cscn_en = QM_CGR_EN;
7240 +
7241 + /* Set different thresholds based on the MAC speed.
7242 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
7243 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
7244 + * In such cases, we ought to reconfigure the threshold, too.
7245 + */
7246 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
7247 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
7248 + else
7249 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
7250 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
7251 +
7252 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
7253 + initcgr.cgr.cstd_en = QM_CGR_EN;
7254 +
7255 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
7256 + &initcgr);
7257 + if (err < 0) {
7258 + pr_err("Error %d creating CGR with ID %d\n", err,
7259 + priv->cgr_data.cgr.cgrid);
7260 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
7261 + goto out_error;
7262 + }
7263 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
7264 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
7265 + priv->cgr_data.cgr.chan);
7266 +
7267 +out_error:
7268 + return err;
7269 +}
7270 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
7271 +
7272 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
7273 + struct dpa_fq *fq,
7274 + const struct qman_fq *template)
7275 +{
7276 + fq->fq_base = *template;
7277 + fq->net_dev = priv->net_dev;
7278 +
7279 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
7280 + fq->channel = priv->channel;
7281 +}
7282 +
7283 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
7284 + struct dpa_fq *fq,
7285 + struct fm_port *port,
7286 + const struct qman_fq *template)
7287 +{
7288 + fq->fq_base = *template;
7289 + fq->net_dev = priv->net_dev;
7290 +
7291 + if (port) {
7292 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
7293 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
7294 + } else {
7295 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
7296 + }
7297 +}
7298 +
7299 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
7300 + struct fm_port *tx_port)
7301 +{
7302 + struct dpa_fq *fq;
7303 + uint16_t portals[NR_CPUS];
7304 + int cpu, portal_cnt = 0, num_portals = 0;
7305 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
7306 + const cpumask_t *affine_cpus = qman_affine_cpus();
7307 + int egress_cnt = 0, conf_cnt = 0;
7308 +
7309 + /* Prepare for PCD FQs init */
7310 + for_each_cpu(cpu, affine_cpus)
7311 + portals[num_portals++] = qman_affine_channel(cpu);
7312 + if (num_portals == 0)
7313 + dev_err(priv->net_dev->dev.parent,
7314 + "No Qman software (affine) channels found");
7315 +
7316 + pcd_fqid = (priv->mac_dev) ?
7317 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
7318 + pcd_fqid_hi_prio = (priv->mac_dev) ?
7319 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
7320 +
7321 + /* Initialize each FQ in the list */
7322 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7323 + switch (fq->fq_type) {
7324 + case FQ_TYPE_RX_DEFAULT:
7325 + BUG_ON(!priv->mac_dev);
7326 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7327 + break;
7328 + case FQ_TYPE_RX_ERROR:
7329 + BUG_ON(!priv->mac_dev);
7330 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
7331 + break;
7332 + case FQ_TYPE_RX_PCD:
7333 + /* For MACless we can't have dynamic Rx queues */
7334 + BUG_ON(!priv->mac_dev && !fq->fqid);
7335 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7336 + if (!fq->fqid)
7337 + fq->fqid = pcd_fqid++;
7338 + fq->channel = portals[portal_cnt];
7339 + portal_cnt = (portal_cnt + 1) % num_portals;
7340 + break;
7341 + case FQ_TYPE_RX_PCD_HI_PRIO:
7342 + /* For MACless we can't have dynamic Hi Pri Rx queues */
7343 + BUG_ON(!priv->mac_dev && !fq->fqid);
7344 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7345 + if (!fq->fqid)
7346 + fq->fqid = pcd_fqid_hi_prio++;
7347 + fq->channel = portals[portal_cnt];
7348 + portal_cnt = (portal_cnt + 1) % num_portals;
7349 + break;
7350 + case FQ_TYPE_TX:
7351 + dpa_setup_egress(priv, fq, tx_port,
7352 + &fq_cbs->egress_ern);
7353 + /* If we have more Tx queues than the number of cores,
7354 + * just ignore the extra ones.
7355 + */
7356 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
7357 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7358 + break;
7359 + case FQ_TYPE_TX_CONFIRM:
7360 + BUG_ON(!priv->mac_dev);
7361 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7362 + break;
7363 + case FQ_TYPE_TX_CONF_MQ:
7364 + BUG_ON(!priv->mac_dev);
7365 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7366 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
7367 + break;
7368 + case FQ_TYPE_TX_ERROR:
7369 + BUG_ON(!priv->mac_dev);
7370 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
7371 + break;
7372 + default:
7373 + dev_warn(priv->net_dev->dev.parent,
7374 + "Unknown FQ type detected!\n");
7375 + break;
7376 + }
7377 + }
7378 +
7379 + /* The number of Tx queues may be smaller than the number of cores, if
7380 + * the Tx queue range is specified in the device tree instead of being
7381 + * dynamically allocated.
7382 + * Make sure all CPUs receive a corresponding Tx queue.
7383 + */
7384 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
7385 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7386 + if (fq->fq_type != FQ_TYPE_TX)
7387 + continue;
7388 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7389 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
7390 + break;
7391 + }
7392 + }
7393 +}
7394 +EXPORT_SYMBOL(dpa_fq_setup);
7395 +
7396 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
7397 +{
7398 + int _errno;
7399 + const struct dpa_priv_s *priv;
7400 + struct device *dev;
7401 + struct qman_fq *fq;
7402 + struct qm_mcc_initfq initfq;
7403 + struct qman_fq *confq;
7404 + int queue_id;
7405 +
7406 + priv = netdev_priv(dpa_fq->net_dev);
7407 + dev = dpa_fq->net_dev->dev.parent;
7408 +
7409 + if (dpa_fq->fqid == 0)
7410 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
7411 +
7412 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
7413 +
7414 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
7415 + if (_errno) {
7416 + dev_err(dev, "qman_create_fq() failed\n");
7417 + return _errno;
7418 + }
7419 + fq = &dpa_fq->fq_base;
7420 +
7421 + if (dpa_fq->init) {
7422 + memset(&initfq, 0, sizeof(initfq));
7423 +
7424 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
7425 + /* FIXME: why would we want to keep an empty FQ in cache? */
7426 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
7427 +
7428 + /* Try to reduce the number of portal interrupts for
7429 + * Tx Confirmation FQs.
7430 + */
7431 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
7432 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
7433 +
7434 + /* FQ placement */
7435 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
7436 +
7437 + initfq.fqd.dest.channel = dpa_fq->channel;
7438 + initfq.fqd.dest.wq = dpa_fq->wq;
7439 +
7440 + /* Put all egress queues in a congestion group of their own.
7441 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
7442 + * rather than Tx - but they nonetheless account for the
7443 + * memory footprint on behalf of egress traffic. We therefore
7444 + * place them in the netdev's CGR, along with the Tx FQs.
7445 + */
7446 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
7447 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
7448 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
7449 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7450 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7451 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
7452 + /* Set a fixed overhead accounting, in an attempt to
7453 + * reduce the impact of fixed-size skb shells and the
7454 + * driver's needed headroom on system memory. This is
7455 + * especially the case when the egress traffic is
7456 + * composed of small datagrams.
7457 + * Unfortunately, QMan's OAL value is capped to an
7458 + * insufficient value, but even that is better than
7459 + * no overhead accounting at all.
7460 + */
7461 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7462 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7463 + initfq.fqd.oac_init.oal =
7464 + (signed char)(min(sizeof(struct sk_buff) +
7465 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7466 + }
7467 +
7468 + if (td_enable) {
7469 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
7470 + qm_fqd_taildrop_set(&initfq.fqd.td,
7471 + DPA_FQ_TD, 1);
7472 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
7473 + }
7474 +
7475 + /* Configure the Tx confirmation queue, now that we know
7476 + * which Tx queue it pairs with.
7477 + */
7478 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
7479 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
7480 + if (queue_id >= 0) {
7481 + confq = priv->conf_fqs[queue_id];
7482 + if (confq) {
7483 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7484 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
7485 + * A2V=1 (contextA A2 field is valid)
7486 + * A0V=1 (contextA A0 field is valid)
7487 + * B0V=1 (contextB field is valid)
7488 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
7489 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
7490 + */
7491 + initfq.fqd.context_a.hi = 0x1e000000;
7492 + initfq.fqd.context_a.lo = 0x80000000;
7493 + }
7494 + }
7495 + }
7496 +
7497 + /* Put all *private* ingress queues in our "ingress CGR". */
7498 + if (priv->use_ingress_cgr &&
7499 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
7500 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
7501 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
7502 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
7503 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7504 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7505 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
7506 + /* Set a fixed overhead accounting, just like for the
7507 + * egress CGR.
7508 + */
7509 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7510 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7511 + initfq.fqd.oac_init.oal =
7512 + (signed char)(min(sizeof(struct sk_buff) +
7513 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7514 + }
7515 +
7516 + /* Initialization common to all ingress queues */
7517 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
7518 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7519 + initfq.fqd.fq_ctrl |=
7520 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
7521 + initfq.fqd.context_a.stashing.exclusive =
7522 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
7523 + QM_STASHING_EXCL_ANNOTATION;
7524 + initfq.fqd.context_a.stashing.data_cl = 2;
7525 + initfq.fqd.context_a.stashing.annotation_cl = 1;
7526 + initfq.fqd.context_a.stashing.context_cl =
7527 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
7528 + }
7529 +
7530 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
7531 + if (_errno < 0) {
7532 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
7533 + dpa_fq->init = 0;
7534 + } else {
7535 + dev_err(dev, "qman_init_fq(%u) = %d\n",
7536 + qman_fq_fqid(fq), _errno);
7537 + qman_destroy_fq(fq, 0);
7538 + }
7539 + return _errno;
7540 + }
7541 + }
7542 +
7543 + dpa_fq->fqid = qman_fq_fqid(fq);
7544 +
7545 + return 0;
7546 +}
7547 +EXPORT_SYMBOL(dpa_fq_init);
7548 +
7549 +int __cold __attribute__((nonnull))
7550 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
7551 +{
7552 + int _errno, __errno;
7553 + struct dpa_fq *dpa_fq;
7554 + const struct dpa_priv_s *priv;
7555 +
7556 + _errno = 0;
7557 +
7558 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
7559 + priv = netdev_priv(dpa_fq->net_dev);
7560 +
7561 + if (dpa_fq->init) {
7562 + _errno = qman_retire_fq(fq, NULL);
7563 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
7564 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
7565 + qman_fq_fqid(fq), _errno);
7566 +
7567 + __errno = qman_oos_fq(fq);
7568 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
7569 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
7570 + qman_fq_fqid(fq), __errno);
7571 + if (_errno >= 0)
7572 + _errno = __errno;
7573 + }
7574 + }
7575 +
7576 + qman_destroy_fq(fq, 0);
7577 + list_del(&dpa_fq->list);
7578 +
7579 + return _errno;
7580 +}
7581 +EXPORT_SYMBOL(_dpa_fq_free);
7582 +
7583 +int __cold __attribute__((nonnull))
7584 +dpa_fq_free(struct device *dev, struct list_head *list)
7585 +{
7586 + int _errno, __errno;
7587 + struct dpa_fq *dpa_fq, *tmp;
7588 +
7589 + _errno = 0;
7590 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7591 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
7592 + if (unlikely(__errno < 0) && _errno >= 0)
7593 + _errno = __errno;
7594 + }
7595 +
7596 + return _errno;
7597 +}
7598 +EXPORT_SYMBOL(dpa_fq_free);
7599 +
7600 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
7601 +{
7602 + int _errno, __errno;
7603 + struct dpa_fq *dpa_fq, *tmp;
7604 + static bool print_msg __read_mostly;
7605 +
7606 + _errno = 0;
7607 + print_msg = true;
7608 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7609 + __errno = dpa_fq_init(dpa_fq, td_enable);
7610 + if (unlikely(__errno < 0) && _errno >= 0) {
7611 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
7612 + if (print_msg) {
7613 + dev_warn(dev,
7614 + "Skip RX PCD High Priority FQs initialization\n");
7615 + print_msg = false;
7616 + }
7617 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
7618 + dev_warn(dev,
7619 + "Error freeing frame queues\n");
7620 + } else {
7621 + _errno = __errno;
7622 + break;
7623 + }
7624 + }
7625 + }
7626 +
7627 + return _errno;
7628 +}
7629 +EXPORT_SYMBOL(dpa_fqs_init);
7630 +static void
7631 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
7632 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
7633 +{
7634 + struct fm_port_params tx_port_param;
7635 + bool frag_enabled = false;
7636 +
7637 + memset(&tx_port_param, 0, sizeof(tx_port_param));
7638 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
7639 + buf_layout, frag_enabled);
7640 +}
7641 +
7642 +static void
7643 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
7644 + struct dpa_fq *errq, struct dpa_fq *defq,
7645 + struct dpa_buffer_layout_s *buf_layout)
7646 +{
7647 + struct fm_port_params rx_port_param;
7648 + int i;
7649 + bool frag_enabled = false;
7650 +
7651 + memset(&rx_port_param, 0, sizeof(rx_port_param));
7652 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
7653 + rx_port_param.num_pools = (uint8_t)count;
7654 + for (i = 0; i < count; i++) {
7655 + if (i >= rx_port_param.num_pools)
7656 + break;
7657 + rx_port_param.pool_param[i].id = bp[i].bpid;
7658 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
7659 + }
7660 +
7661 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
7662 + buf_layout, frag_enabled);
7663 +}
7664 +
7665 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
7666 +/* Defined as weak, to be implemented by fman pcd tester. */
7667 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
7668 +__attribute__((weak));
7669 +
7670 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
7671 +#else
7672 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
7673 +
7674 +int dpa_free_pcd_fqids(struct device *, uint32_t);
7675 +
7676 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
7677 +
7678 +
7679 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
7680 + uint8_t alignment, uint32_t *base_fqid)
7681 +{
7682 + dev_crit(dev, "callback not implemented!\n");
7683 +
7684 + return 0;
7685 +}
7686 +
7687 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
7688 +{
7689 +
7690 + dev_crit(dev, "callback not implemented!\n");
7691 +
7692 + return 0;
7693 +}
7694 +
7695 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
7696 + struct dpa_bp *bp, size_t count,
7697 + struct fm_port_fqs *port_fqs,
7698 + struct dpa_buffer_layout_s *buf_layout,
7699 + struct device *dev)
7700 +{
7701 + struct fm_port_pcd_param rx_port_pcd_param;
7702 + struct fm_port *rxport = mac_dev->port_dev[RX];
7703 + struct fm_port *txport = mac_dev->port_dev[TX];
7704 +
7705 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
7706 + port_fqs->tx_defq, &buf_layout[TX]);
7707 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
7708 + port_fqs->rx_defq, &buf_layout[RX]);
7709 +
7710 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
7711 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
7712 + rx_port_pcd_param.dev = dev;
7713 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
7714 +}
7715 +EXPORT_SYMBOL(dpaa_eth_init_ports);
7716 +
7717 +void dpa_release_sgt(struct qm_sg_entry *sgt)
7718 +{
7719 + struct dpa_bp *dpa_bp;
7720 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
7721 + uint8_t i = 0, j;
7722 +
7723 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
7724 +
7725 + do {
7726 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
7727 + DPA_BUG_ON(!dpa_bp);
7728 +
7729 + j = 0;
7730 + do {
7731 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
7732 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
7733 +
7734 + j++; i++;
7735 + } while (j < ARRAY_SIZE(bmb) &&
7736 + !qm_sg_entry_get_final(&sgt[i-1]) &&
7737 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
7738 + qm_sg_entry_get_bpid(&sgt[i]));
7739 +
7740 + while (bman_release(dpa_bp->pool, bmb, j, 0))
7741 + cpu_relax();
7742 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
7743 +}
7744 +EXPORT_SYMBOL(dpa_release_sgt);
7745 +
7746 +void __attribute__((nonnull))
7747 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
7748 +{
7749 + struct qm_sg_entry *sgt;
7750 + struct dpa_bp *dpa_bp;
7751 + struct bm_buffer bmb;
7752 + dma_addr_t addr;
7753 + void *vaddr;
7754 +
7755 + bmb.opaque = 0;
7756 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
7757 +
7758 + dpa_bp = dpa_bpid2pool(fd->bpid);
7759 + DPA_BUG_ON(!dpa_bp);
7760 +
7761 + if (fd->format == qm_fd_sg) {
7762 + vaddr = phys_to_virt(qm_fd_addr(fd));
7763 + sgt = vaddr + dpa_fd_offset(fd);
7764 +
7765 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
7766 + DMA_BIDIRECTIONAL);
7767 +
7768 + dpa_release_sgt(sgt);
7769 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
7770 + DMA_BIDIRECTIONAL);
7771 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
7772 + dev_err(dpa_bp->dev, "DMA mapping failed");
7773 + return;
7774 + }
7775 + bm_buffer_set64(&bmb, addr);
7776 + }
7777 +
7778 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
7779 + cpu_relax();
7780 +}
7781 +EXPORT_SYMBOL(dpa_fd_release);
7782 +
7783 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
7784 + const struct qm_mr_entry *msg)
7785 +{
7786 + switch (msg->ern.rc & QM_MR_RC_MASK) {
7787 + case QM_MR_RC_CGR_TAILDROP:
7788 + percpu_priv->ern_cnt.cg_tdrop++;
7789 + break;
7790 + case QM_MR_RC_WRED:
7791 + percpu_priv->ern_cnt.wred++;
7792 + break;
7793 + case QM_MR_RC_ERROR:
7794 + percpu_priv->ern_cnt.err_cond++;
7795 + break;
7796 + case QM_MR_RC_ORPWINDOW_EARLY:
7797 + percpu_priv->ern_cnt.early_window++;
7798 + break;
7799 + case QM_MR_RC_ORPWINDOW_LATE:
7800 + percpu_priv->ern_cnt.late_window++;
7801 + break;
7802 + case QM_MR_RC_FQ_TAILDROP:
7803 + percpu_priv->ern_cnt.fq_tdrop++;
7804 + break;
7805 + case QM_MR_RC_ORPWINDOW_RETIRED:
7806 + percpu_priv->ern_cnt.fq_retired++;
7807 + break;
7808 + case QM_MR_RC_ORP_ZERO:
7809 + percpu_priv->ern_cnt.orp_zero++;
7810 + break;
7811 + }
7812 +}
7813 +EXPORT_SYMBOL(count_ern);
7814 +
7815 +/**
7816 + * Turn on HW checksum computation for this outgoing frame.
7817 + * If the current protocol is not something we support in this regard
7818 + * (or if the stack has already computed the SW checksum), we do nothing.
7819 + *
7820 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
7821 + * otherwise.
7822 + *
7823 + * Note that this function may modify the fd->cmd field and the skb data buffer
7824 + * (the Parse Results area).
7825 + */
7826 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
7827 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
7828 +{
7829 + fm_prs_result_t *parse_result;
7830 + struct iphdr *iph;
7831 + struct ipv6hdr *ipv6h = NULL;
7832 + u8 l4_proto;
7833 + u16 ethertype = ntohs(skb->protocol);
7834 + int retval = 0;
7835 +
7836 + if (skb->ip_summed != CHECKSUM_PARTIAL)
7837 + return 0;
7838 +
7839 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
7840 + * L4 alone from the FM configuration anyway.
7841 + */
7842 +
7843 + /* Fill in some fields of the Parse Results array, so the FMan
7844 + * can find them as if they came from the FMan Parser.
7845 + */
7846 + parse_result = (fm_prs_result_t *)parse_results;
7847 +
7848 + /* If we're dealing with VLAN, get the real Ethernet type */
7849 + if (ethertype == ETH_P_8021Q) {
7850 + /* We can't always assume the MAC header is set correctly
7851 + * by the stack, so reset to beginning of skb->data
7852 + */
7853 + skb_reset_mac_header(skb);
7854 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
7855 + }
7856 +
7857 + /* Fill in the relevant L3 parse result fields
7858 + * and read the L4 protocol type
7859 + */
7860 + switch (ethertype) {
7861 + case ETH_P_IP:
7862 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
7863 + iph = ip_hdr(skb);
7864 + DPA_BUG_ON(iph == NULL);
7865 + l4_proto = iph->protocol;
7866 + break;
7867 + case ETH_P_IPV6:
7868 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
7869 + ipv6h = ipv6_hdr(skb);
7870 + DPA_BUG_ON(ipv6h == NULL);
7871 + l4_proto = ipv6h->nexthdr;
7872 + break;
7873 + default:
7874 + /* We shouldn't even be here */
7875 + if (netif_msg_tx_err(priv) && net_ratelimit())
7876 + netdev_alert(priv->net_dev,
7877 + "Can't compute HW csum for L3 proto 0x%x\n",
7878 + ntohs(skb->protocol));
7879 + retval = -EIO;
7880 + goto return_error;
7881 + }
7882 +
7883 + /* Fill in the relevant L4 parse result fields */
7884 + switch (l4_proto) {
7885 + case IPPROTO_UDP:
7886 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
7887 + break;
7888 + case IPPROTO_TCP:
7889 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
7890 + break;
7891 + default:
7892 + /* This can as well be a BUG() */
7893 + if (netif_msg_tx_err(priv) && net_ratelimit())
7894 + netdev_alert(priv->net_dev,
7895 + "Can't compute HW csum for L4 proto 0x%x\n",
7896 + l4_proto);
7897 + retval = -EIO;
7898 + goto return_error;
7899 + }
7900 +
7901 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
7902 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
7903 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
7904 +
7905 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
7906 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
7907 +
7908 + /* On P1023 and similar platforms fd->cmd interpretation could
7909 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
7910 + * is not set so we do not need to check; in the future, if/when
7911 + * using context_a we need to check this bit
7912 + */
7913 +
7914 +return_error:
7915 + return retval;
7916 +}
7917 +EXPORT_SYMBOL(dpa_enable_tx_csum);
7918 +
7919 +#ifdef CONFIG_FSL_DPAA_CEETM
7920 +void dpa_enable_ceetm(struct net_device *dev)
7921 +{
7922 + struct dpa_priv_s *priv = netdev_priv(dev);
7923 + priv->ceetm_en = true;
7924 +}
7925 +EXPORT_SYMBOL(dpa_enable_ceetm);
7926 +
7927 +void dpa_disable_ceetm(struct net_device *dev)
7928 +{
7929 + struct dpa_priv_s *priv = netdev_priv(dev);
7930 + priv->ceetm_en = false;
7931 +}
7932 +EXPORT_SYMBOL(dpa_disable_ceetm);
7933 +#endif
7934 --- /dev/null
7935 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
7936 @@ -0,0 +1,225 @@
7937 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
7938 + *
7939 + * Redistribution and use in source and binary forms, with or without
7940 + * modification, are permitted provided that the following conditions are met:
7941 + * * Redistributions of source code must retain the above copyright
7942 + * notice, this list of conditions and the following disclaimer.
7943 + * * Redistributions in binary form must reproduce the above copyright
7944 + * notice, this list of conditions and the following disclaimer in the
7945 + * documentation and/or other materials provided with the distribution.
7946 + * * Neither the name of Freescale Semiconductor nor the
7947 + * names of its contributors may be used to endorse or promote products
7948 + * derived from this software without specific prior written permission.
7949 + *
7950 + *
7951 + * ALTERNATIVELY, this software may be distributed under the terms of the
7952 + * GNU General Public License ("GPL") as published by the Free Software
7953 + * Foundation, either version 2 of that License or (at your option) any
7954 + * later version.
7955 + *
7956 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
7957 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7958 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7959 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
7960 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7961 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7962 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7963 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7964 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7965 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7966 + */
7967 +
7968 +#ifndef __DPAA_ETH_COMMON_H
7969 +#define __DPAA_ETH_COMMON_H
7970 +
7971 +#include <linux/etherdevice.h> /* struct net_device */
7972 +#include <linux/fsl_bman.h> /* struct bm_buffer */
7973 +#include <linux/of_platform.h> /* struct platform_device */
7974 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
7975 +
7976 +#include "dpaa_eth.h"
7977 +#include "lnxwrp_fsl_fman.h"
7978 +
7979 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
7980 + frag_enabled) \
7981 +{ \
7982 + param.errq = errq_id; \
7983 + param.defq = defq_id; \
7984 + param.priv_data_size = buf_layout->priv_data_size; \
7985 + param.parse_results = buf_layout->parse_results; \
7986 + param.hash_results = buf_layout->hash_results; \
7987 + param.frag_enable = frag_enabled; \
7988 + param.time_stamp = buf_layout->time_stamp; \
7989 + param.manip_extra_space = buf_layout->manip_extra_space; \
7990 + param.data_align = buf_layout->data_align; \
7991 + fm_set_##type##_port_params(port, &param); \
7992 +}
7993 +
7994 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
7995 +
7996 +#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES
7997 +
7998 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
7999 +
8000 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
8001 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
8002 + (_errno == -EIO))
8003 +/* return codes for the dpaa-eth hooks */
8004 +enum dpaa_eth_hook_result {
8005 + /* fd/skb was retained by the hook.
8006 + *
8007 + * On the Rx path, this means the Ethernet driver will _not_
8008 + * deliver the skb to the stack. Instead, the hook implementation
8009 + * is expected to properly dispose of the skb.
8010 + *
8011 + * On the Tx path, the Ethernet driver's dpa_tx() function will
8012 + * immediately return NETDEV_TX_OK. The hook implementation is expected
8013 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
8014 + * unless you know exactly what you're doing!
8015 + *
8016 + * On the confirmation/error paths, the Ethernet driver will _not_
8017 + * perform any fd cleanup, nor update the interface statistics.
8018 + */
8019 + DPAA_ETH_STOLEN,
8020 + /* fd/skb was returned to the Ethernet driver for regular processing.
8021 + * The hook is not allowed to, for instance, reallocate the skb (as if
8022 + * by linearizing, copying, cloning or reallocating the headroom).
8023 + */
8024 + DPAA_ETH_CONTINUE
8025 +};
8026 +
8027 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
8028 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
8029 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
8030 + struct sk_buff *skb, struct net_device *net_dev);
8031 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
8032 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
8033 +
8034 +/* used in napi related functions */
8035 +extern u16 qman_portal_max;
8036 +
8037 +/* from dpa_ethtool.c */
8038 +extern const struct ethtool_ops dpa_ethtool_ops;
8039 +
8040 +#ifdef CONFIG_FSL_DPAA_HOOKS
8041 +/* Various hooks used for unit-testing and/or fastpath optimizations.
8042 + * Currently only one set of such hooks is supported.
8043 + */
8044 +struct dpaa_eth_hooks_s {
8045 + /* Invoked on the Tx private path, immediately after receiving the skb
8046 + * from the stack.
8047 + */
8048 + dpaa_eth_egress_hook_t tx;
8049 +
8050 + /* Invoked on the Rx private path, right before passing the skb
8051 + * up the stack. At that point, the packet's protocol id has already
8052 + * been set. The skb's data pointer is now at the L3 header, and
8053 + * skb->mac_header points to the L2 header. skb->len has been adjusted
8054 + * to be the length of L3+payload (i.e., the length of the
8055 + * original frame minus the L2 header len).
8056 + * For more details on what the skb looks like, see eth_type_trans().
8057 + */
8058 + dpaa_eth_ingress_hook_t rx_default;
8059 +
8060 + /* Driver hook for the Rx error private path. */
8061 + dpaa_eth_confirm_hook_t rx_error;
8062 + /* Driver hook for the Tx confirmation private path. */
8063 + dpaa_eth_confirm_hook_t tx_confirm;
8064 + /* Driver hook for the Tx error private path. */
8065 + dpaa_eth_confirm_hook_t tx_error;
8066 +};
8067 +
8068 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
8069 +
8070 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
8071 +#endif
8072 +
8073 +int dpa_netdev_init(struct net_device *net_dev,
8074 + const uint8_t *mac_addr,
8075 + uint16_t tx_timeout);
8076 +int __cold dpa_start(struct net_device *net_dev);
8077 +int __cold dpa_stop(struct net_device *net_dev);
8078 +void __cold dpa_timeout(struct net_device *net_dev);
8079 +void __cold
8080 +dpa_get_stats64(struct net_device *net_dev,
8081 + struct rtnl_link_stats64 *stats);
8082 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu);
8083 +int dpa_ndo_init(struct net_device *net_dev);
8084 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
8085 +netdev_features_t dpa_fix_features(struct net_device *dev,
8086 + netdev_features_t features);
8087 +#ifdef CONFIG_FSL_DPAA_TS
8088 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
8089 + enum port_type rx_tx, const void *data);
8090 +/* Updates the skb shared hw timestamp from the hardware timestamp */
8091 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8092 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
8093 +#endif /* CONFIG_FSL_DPAA_TS */
8094 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
8095 +int __cold dpa_remove(struct platform_device *of_dev);
8096 +struct mac_device * __cold __must_check
8097 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
8098 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
8099 +void dpa_set_rx_mode(struct net_device *net_dev);
8100 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8101 + struct dpa_buffer_layout_s *layout);
8102 +int __attribute__((nonnull))
8103 +dpa_bp_alloc(struct dpa_bp *dpa_bp);
8104 +void __cold __attribute__((nonnull))
8105 +dpa_bp_free(struct dpa_priv_s *priv);
8106 +struct dpa_bp *dpa_bpid2pool(int bpid);
8107 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
8108 +bool dpa_bpid2pool_use(int bpid);
8109 +void dpa_bp_drain(struct dpa_bp *bp);
8110 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8111 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8112 + void *accel_priv, select_queue_fallback_t fallback);
8113 +#endif
8114 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8115 + u32 fq_start,
8116 + u32 fq_count,
8117 + struct list_head *list,
8118 + enum dpa_fq_type fq_type);
8119 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8120 + struct fm_port_fqs *port_fqs,
8121 + bool tx_conf_fqs_per_core,
8122 + enum port_type ptype);
8123 +int dpa_get_channel(void);
8124 +void dpa_release_channel(void);
8125 +void dpaa_eth_add_channel(u16 channel);
8126 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
8127 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8128 + struct fm_port *tx_port);
8129 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
8130 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
8131 +int __cold __attribute__((nonnull))
8132 +dpa_fq_free(struct device *dev, struct list_head *list);
8133 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
8134 + struct dpa_bp *bp, size_t count,
8135 + struct fm_port_fqs *port_fqs,
8136 + struct dpa_buffer_layout_s *buf_layout,
8137 + struct device *dev);
8138 +void dpa_release_sgt(struct qm_sg_entry *sgt);
8139 +void __attribute__((nonnull))
8140 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
8141 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
8142 + const struct qm_mr_entry *msg);
8143 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
8144 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
8145 +#ifdef CONFIG_FSL_DPAA_CEETM
8146 +void dpa_enable_ceetm(struct net_device *dev);
8147 +void dpa_disable_ceetm(struct net_device *dev);
8148 +#endif
8149 +struct proxy_device {
8150 + struct mac_device *mac_dev;
8151 +};
8152 +
8153 +/* mac device control functions exposed by proxy interface*/
8154 +int dpa_proxy_start(struct net_device *net_dev);
8155 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
8156 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8157 + struct net_device *net_dev);
8158 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8159 + struct net_device *net_dev);
8160 +
8161 +#endif /* __DPAA_ETH_COMMON_H */
8162 --- /dev/null
8163 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8164 @@ -0,0 +1,381 @@
8165 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
8166 + *
8167 + * Redistribution and use in source and binary forms, with or without
8168 + * modification, are permitted provided that the following conditions are met:
8169 + * * Redistributions of source code must retain the above copyright
8170 + * notice, this list of conditions and the following disclaimer.
8171 + * * Redistributions in binary form must reproduce the above copyright
8172 + * notice, this list of conditions and the following disclaimer in the
8173 + * documentation and/or other materials provided with the distribution.
8174 + * * Neither the name of Freescale Semiconductor nor the
8175 + * names of its contributors may be used to endorse or promote products
8176 + * derived from this software without specific prior written permission.
8177 + *
8178 + *
8179 + * ALTERNATIVELY, this software may be distributed under the terms of the
8180 + * GNU General Public License ("GPL") as published by the Free Software
8181 + * Foundation, either version 2 of that License or (at your option) any
8182 + * later version.
8183 + *
8184 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8185 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8186 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8187 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8188 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8189 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8190 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8191 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8192 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8193 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8194 + */
8195 +
8196 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8197 +#define pr_fmt(fmt) \
8198 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8199 + KBUILD_BASENAME".c", __LINE__, __func__
8200 +#else
8201 +#define pr_fmt(fmt) \
8202 + KBUILD_MODNAME ": " fmt
8203 +#endif
8204 +
8205 +#include <linux/init.h>
8206 +#include <linux/module.h>
8207 +#include <linux/of_platform.h>
8208 +#include "dpaa_eth.h"
8209 +#include "dpaa_eth_common.h"
8210 +#include "dpaa_eth_base.h"
8211 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
8212 +#include "mac.h"
8213 +
8214 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
8215 +
8216 +MODULE_LICENSE("Dual BSD/GPL");
8217 +
8218 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
8219 +
8220 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
8221 +#ifdef CONFIG_PM
8222 +
8223 +static int proxy_suspend(struct device *dev)
8224 +{
8225 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8226 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8227 + int err = 0;
8228 +
8229 + err = fm_port_suspend(mac_dev->port_dev[RX]);
8230 + if (err)
8231 + goto port_suspend_failed;
8232 +
8233 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8234 + if (err)
8235 + err = fm_port_resume(mac_dev->port_dev[RX]);
8236 +
8237 +port_suspend_failed:
8238 + return err;
8239 +}
8240 +
8241 +static int proxy_resume(struct device *dev)
8242 +{
8243 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8244 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8245 + int err = 0;
8246 +
8247 + err = fm_port_resume(mac_dev->port_dev[TX]);
8248 + if (err)
8249 + goto port_resume_failed;
8250 +
8251 + err = fm_port_resume(mac_dev->port_dev[RX]);
8252 + if (err)
8253 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8254 +
8255 +port_resume_failed:
8256 + return err;
8257 +}
8258 +
8259 +static const struct dev_pm_ops proxy_pm_ops = {
8260 + .suspend = proxy_suspend,
8261 + .resume = proxy_resume,
8262 +};
8263 +
8264 +#define PROXY_PM_OPS (&proxy_pm_ops)
8265 +
8266 +#else /* CONFIG_PM */
8267 +
8268 +#define PROXY_PM_OPS NULL
8269 +
8270 +#endif /* CONFIG_PM */
8271 +
8272 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
8273 +{
8274 + int err = 0, i;
8275 + struct device *dev;
8276 + struct device_node *dpa_node;
8277 + struct dpa_bp *dpa_bp;
8278 + struct list_head proxy_fq_list;
8279 + size_t count;
8280 + struct fm_port_fqs port_fqs;
8281 + struct dpa_buffer_layout_s *buf_layout = NULL;
8282 + struct mac_device *mac_dev;
8283 + struct proxy_device *proxy_dev;
8284 +
8285 + dev = &_of_dev->dev;
8286 +
8287 + dpa_node = dev->of_node;
8288 +
8289 + if (!of_device_is_available(dpa_node))
8290 + return -ENODEV;
8291 +
8292 + /* Get the buffer pools assigned to this interface */
8293 + dpa_bp = dpa_bp_probe(_of_dev, &count);
8294 + if (IS_ERR(dpa_bp))
8295 + return PTR_ERR(dpa_bp);
8296 +
8297 + mac_dev = dpa_mac_probe(_of_dev);
8298 + if (IS_ERR(mac_dev))
8299 + return PTR_ERR(mac_dev);
8300 +
8301 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
8302 + if (!proxy_dev) {
8303 + dev_err(dev, "devm_kzalloc() failed\n");
8304 + return -ENOMEM;
8305 + }
8306 +
8307 + proxy_dev->mac_dev = mac_dev;
8308 + dev_set_drvdata(dev, proxy_dev);
8309 +
8310 + /* We have physical ports, so we need to establish
8311 + * the buffer layout.
8312 + */
8313 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
8314 + GFP_KERNEL);
8315 + if (!buf_layout) {
8316 + dev_err(dev, "devm_kzalloc() failed\n");
8317 + return -ENOMEM;
8318 + }
8319 + dpa_set_buffers_layout(mac_dev, buf_layout);
8320 +
8321 + INIT_LIST_HEAD(&proxy_fq_list);
8322 +
8323 + memset(&port_fqs, 0, sizeof(port_fqs));
8324 +
8325 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
8326 + if (!err)
8327 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
8328 + TX);
8329 + if (err < 0) {
8330 + devm_kfree(dev, buf_layout);
8331 + return err;
8332 + }
8333 +
8334 + /* Proxy initializer - Just configures the MAC on behalf of
8335 + * another partition.
8336 + */
8337 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
8338 + buf_layout, dev);
8339 +
8340 + /* Proxy interfaces need to be started, and the allocated
8341 + * memory freed
8342 + */
8343 + devm_kfree(dev, buf_layout);
8344 + devm_kfree(dev, dpa_bp);
8345 +
8346 + /* Free FQ structures */
8347 + devm_kfree(dev, port_fqs.rx_defq);
8348 + devm_kfree(dev, port_fqs.rx_errq);
8349 + devm_kfree(dev, port_fqs.tx_defq);
8350 + devm_kfree(dev, port_fqs.tx_errq);
8351 +
8352 + for_each_port_device(i, mac_dev->port_dev) {
8353 + err = fm_port_enable(mac_dev->port_dev[i]);
8354 + if (err)
8355 + goto port_enable_fail;
8356 + }
8357 +
8358 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
8359 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
8360 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
8361 +
8362 + return 0; /* Proxy interface initialization ended */
8363 +
8364 +port_enable_fail:
8365 + for_each_port_device(i, mac_dev->port_dev)
8366 + fm_port_disable(mac_dev->port_dev[i]);
8367 + dpa_eth_proxy_remove(_of_dev);
8368 +
8369 + return err;
8370 +}
8371 +
8372 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8373 + struct net_device *net_dev)
8374 +{
8375 + struct mac_device *mac_dev;
8376 + int _errno;
8377 +
8378 + mac_dev = proxy_dev->mac_dev;
8379 +
8380 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8381 + net_dev->dev_addr);
8382 + if (_errno < 0)
8383 + return _errno;
8384 +
8385 + return 0;
8386 +}
8387 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
8388 +
8389 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8390 + struct net_device *net_dev)
8391 +{
8392 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8393 + int _errno;
8394 +
8395 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
8396 + mac_dev->promisc = !mac_dev->promisc;
8397 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
8398 + mac_dev->promisc);
8399 + if (unlikely(_errno < 0))
8400 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
8401 + _errno);
8402 + }
8403 +
8404 + _errno = mac_dev->set_multi(net_dev, mac_dev);
8405 + if (unlikely(_errno < 0))
8406 + return _errno;
8407 +
8408 + return 0;
8409 +}
8410 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
8411 +
8412 +int dpa_proxy_start(struct net_device *net_dev)
8413 +{
8414 + struct mac_device *mac_dev;
8415 + const struct dpa_priv_s *priv;
8416 + struct proxy_device *proxy_dev;
8417 + int _errno;
8418 + int i;
8419 +
8420 + priv = netdev_priv(net_dev);
8421 + proxy_dev = (struct proxy_device *)priv->peer;
8422 + mac_dev = proxy_dev->mac_dev;
8423 +
8424 + _errno = mac_dev->init_phy(net_dev, mac_dev);
8425 + if (_errno < 0) {
8426 + if (netif_msg_drv(priv))
8427 + netdev_err(net_dev, "init_phy() = %d\n",
8428 + _errno);
8429 + return _errno;
8430 + }
8431 +
8432 + for_each_port_device(i, mac_dev->port_dev) {
8433 + _errno = fm_port_enable(mac_dev->port_dev[i]);
8434 + if (_errno)
8435 + goto port_enable_fail;
8436 + }
8437 +
8438 + _errno = mac_dev->start(mac_dev);
8439 + if (_errno < 0) {
8440 + if (netif_msg_drv(priv))
8441 + netdev_err(net_dev, "mac_dev->start() = %d\n",
8442 + _errno);
8443 + goto port_enable_fail;
8444 + }
8445 +
8446 + return _errno;
8447 +
8448 +port_enable_fail:
8449 + for_each_port_device(i, mac_dev->port_dev)
8450 + fm_port_disable(mac_dev->port_dev[i]);
8451 +
8452 + return _errno;
8453 +}
8454 +EXPORT_SYMBOL(dpa_proxy_start);
8455 +
8456 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
8457 +{
8458 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8459 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
8460 + int _errno, i, err;
8461 +
8462 + _errno = mac_dev->stop(mac_dev);
8463 + if (_errno < 0) {
8464 + if (netif_msg_drv(priv))
8465 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8466 + _errno);
8467 + return _errno;
8468 + }
8469 +
8470 + for_each_port_device(i, mac_dev->port_dev) {
8471 + err = fm_port_disable(mac_dev->port_dev[i]);
8472 + _errno = err ? err : _errno;
8473 + }
8474 +
8475 + if (mac_dev->phy_dev)
8476 + phy_disconnect(mac_dev->phy_dev);
8477 + mac_dev->phy_dev = NULL;
8478 +
8479 + return _errno;
8480 +}
8481 +EXPORT_SYMBOL(dpa_proxy_stop);
8482 +
8483 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
8484 +{
8485 + struct device *dev = &of_dev->dev;
8486 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8487 +
8488 + kfree(proxy_dev);
8489 +
8490 + dev_set_drvdata(dev, NULL);
8491 +
8492 + return 0;
8493 +}
8494 +
8495 +static const struct of_device_id dpa_proxy_match[] = {
8496 + {
8497 + .compatible = "fsl,dpa-ethernet-init"
8498 + },
8499 + {}
8500 +};
8501 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
8502 +
8503 +static struct platform_driver dpa_proxy_driver = {
8504 + .driver = {
8505 + .name = KBUILD_MODNAME "-proxy",
8506 + .of_match_table = dpa_proxy_match,
8507 + .owner = THIS_MODULE,
8508 + .pm = PROXY_PM_OPS,
8509 + },
8510 + .probe = dpaa_eth_proxy_probe,
8511 + .remove = dpa_eth_proxy_remove
8512 +};
8513 +
8514 +static int __init __cold dpa_proxy_load(void)
8515 +{
8516 + int _errno;
8517 +
8518 + pr_info(DPA_DESCRIPTION "\n");
8519 +
8520 + /* Initialize dpaa_eth mirror values */
8521 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
8522 + dpa_max_frm = fm_get_max_frm();
8523 +
8524 + _errno = platform_driver_register(&dpa_proxy_driver);
8525 + if (unlikely(_errno < 0)) {
8526 + pr_err(KBUILD_MODNAME
8527 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
8528 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
8529 + }
8530 +
8531 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8532 + KBUILD_BASENAME".c", __func__);
8533 +
8534 + return _errno;
8535 +}
8536 +module_init(dpa_proxy_load);
8537 +
8538 +static void __exit __cold dpa_proxy_unload(void)
8539 +{
8540 + platform_driver_unregister(&dpa_proxy_driver);
8541 +
8542 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8543 + KBUILD_BASENAME".c", __func__);
8544 +}
8545 +module_exit(dpa_proxy_unload);
8546 --- /dev/null
8547 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8548 @@ -0,0 +1,1179 @@
8549 +/* Copyright 2012 Freescale Semiconductor Inc.
8550 + *
8551 + * Redistribution and use in source and binary forms, with or without
8552 + * modification, are permitted provided that the following conditions are met:
8553 + * * Redistributions of source code must retain the above copyright
8554 + * notice, this list of conditions and the following disclaimer.
8555 + * * Redistributions in binary form must reproduce the above copyright
8556 + * notice, this list of conditions and the following disclaimer in the
8557 + * documentation and/or other materials provided with the distribution.
8558 + * * Neither the name of Freescale Semiconductor nor the
8559 + * names of its contributors may be used to endorse or promote products
8560 + * derived from this software without specific prior written permission.
8561 + *
8562 + *
8563 + * ALTERNATIVELY, this software may be distributed under the terms of the
8564 + * GNU General Public License ("GPL") as published by the Free Software
8565 + * Foundation, either version 2 of that License or (at your option) any
8566 + * later version.
8567 + *
8568 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8569 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8570 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8571 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8572 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8573 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8574 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8575 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8576 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8577 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8578 + */
8579 +
8580 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8581 +#define pr_fmt(fmt) \
8582 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8583 + KBUILD_BASENAME".c", __LINE__, __func__
8584 +#else
8585 +#define pr_fmt(fmt) \
8586 + KBUILD_MODNAME ": " fmt
8587 +#endif
8588 +
8589 +#include <linux/init.h>
8590 +#include <linux/skbuff.h>
8591 +#include <linux/highmem.h>
8592 +#include <linux/fsl_bman.h>
8593 +#include <net/sock.h>
8594 +
8595 +#include "dpaa_eth.h"
8596 +#include "dpaa_eth_common.h"
8597 +#ifdef CONFIG_FSL_DPAA_1588
8598 +#include "dpaa_1588.h"
8599 +#endif
8600 +#ifdef CONFIG_FSL_DPAA_CEETM
8601 +#include "dpaa_eth_ceetm.h"
8602 +#endif
8603 +
8604 +/* DMA map and add a page frag back into the bpool.
8605 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
8606 + * specifically for fitting into @dpa_bp.
8607 + */
8608 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
8609 + int *count_ptr)
8610 +{
8611 + struct bm_buffer bmb;
8612 + dma_addr_t addr;
8613 +
8614 + bmb.opaque = 0;
8615 +
8616 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
8617 + DMA_BIDIRECTIONAL);
8618 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
8619 + dev_err(dpa_bp->dev, "DMA mapping failed");
8620 + return;
8621 + }
8622 +
8623 + bm_buffer_set64(&bmb, addr);
8624 +
8625 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
8626 + cpu_relax();
8627 +
8628 + (*count_ptr)++;
8629 +}
8630 +
8631 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
8632 +{
8633 + struct bm_buffer bmb[8];
8634 + void *new_buf;
8635 + dma_addr_t addr;
8636 + uint8_t i;
8637 + struct device *dev = dpa_bp->dev;
8638 + struct sk_buff *skb, **skbh;
8639 +
8640 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
8641 +
8642 + for (i = 0; i < 8; i++) {
8643 + /* We'll prepend the skb back-pointer; can't use the DPA
8644 + * priv space, because FMan will overwrite it (from offset 0)
8645 + * if it ends up being the second, third, etc. fragment
8646 + * in a S/G frame.
8647 + *
8648 + * We only need enough space to store a pointer, but allocate
8649 + * an entire cacheline for performance reasons.
8650 + */
8651 +#ifndef CONFIG_PPC
8652 + if (unlikely(dpaa_errata_a010022)) {
8653 + struct page *new_page = alloc_page(GFP_ATOMIC);
8654 + if (unlikely(!new_page))
8655 + goto netdev_alloc_failed;
8656 + new_buf = page_address(new_page);
8657 + }
8658 + else
8659 +#endif
8660 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
8661 +
8662 + if (unlikely(!new_buf))
8663 + goto netdev_alloc_failed;
8664 + new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
8665 +
8666 + skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
8667 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
8668 + if (unlikely(!skb)) {
8669 + put_page(virt_to_head_page(new_buf));
8670 + goto build_skb_failed;
8671 + }
8672 + DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
8673 +
8674 + addr = dma_map_single(dev, new_buf,
8675 + dpa_bp->size, DMA_BIDIRECTIONAL);
8676 + if (unlikely(dma_mapping_error(dev, addr)))
8677 + goto dma_map_failed;
8678 +
8679 + bm_buffer_set64(&bmb[i], addr);
8680 + }
8681 +
8682 +release_bufs:
8683 + /* Release the buffers. In case bman is busy, keep trying
8684 + * until successful. bman_release() is guaranteed to succeed
8685 + * in a reasonable amount of time
8686 + */
8687 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
8688 + cpu_relax();
8689 + return i;
8690 +
8691 +dma_map_failed:
8692 + kfree_skb(skb);
8693 +
8694 +build_skb_failed:
8695 +netdev_alloc_failed:
8696 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
8697 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
8698 +
8699 + bm_buffer_set64(&bmb[i], 0);
8700 + /* Avoid releasing a completely null buffer; bman_release() requires
8701 + * at least one buffer.
8702 + */
8703 + if (likely(i))
8704 + goto release_bufs;
8705 +
8706 + return 0;
8707 +}
8708 +
8709 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
8710 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
8711 +{
8712 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
8713 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
8714 +}
8715 +
8716 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
8717 +{
8718 + int i;
8719 +
8720 + /* Give each CPU an allotment of "config_count" buffers */
8721 + for_each_possible_cpu(i) {
8722 + int j;
8723 +
8724 + /* Although we access another CPU's counters here
8725 + * we do it at boot time so it is safe
8726 + */
8727 + for (j = 0; j < dpa_bp->config_count; j += 8)
8728 + dpa_bp_add_8_bufs(dpa_bp, i);
8729 + }
8730 + return 0;
8731 +}
8732 +EXPORT_SYMBOL(dpa_bp_priv_seed);
8733 +
8734 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
8735 + * REFILL_THRESHOLD.
8736 + */
8737 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
8738 +{
8739 + int count = *countptr;
8740 + int new_bufs;
8741 +
8742 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
8743 + do {
8744 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
8745 + if (unlikely(!new_bufs)) {
8746 + /* Avoid looping forever if we've temporarily
8747 + * run out of memory. We'll try again at the
8748 + * next NAPI cycle.
8749 + */
8750 + break;
8751 + }
8752 + count += new_bufs;
8753 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
8754 +
8755 + *countptr = count;
8756 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
8757 + return -ENOMEM;
8758 + }
8759 +
8760 + return 0;
8761 +}
8762 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
8763 +
8764 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
8765 + * either contiguous frames or scatter/gather ones.
8766 + * Skb freeing is not handled here.
8767 + *
8768 + * This function may be called on error paths in the Tx function, so guard
8769 + * against cases when not all fd relevant fields were filled in.
8770 + *
8771 + * Return the skb backpointer, since for S/G frames the buffer containing it
8772 + * gets freed here.
8773 + */
8774 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
8775 + const struct qm_fd *fd)
8776 +{
8777 + const struct qm_sg_entry *sgt;
8778 + int i;
8779 + struct dpa_bp *dpa_bp = priv->dpa_bp;
8780 + dma_addr_t addr = qm_fd_addr(fd);
8781 + dma_addr_t sg_addr;
8782 + struct sk_buff **skbh;
8783 + struct sk_buff *skb = NULL;
8784 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
8785 + int nr_frags;
8786 + int sg_len;
8787 +
8788 + /* retrieve skb back pointer */
8789 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
8790 +
8791 + if (unlikely(fd->format == qm_fd_sg)) {
8792 + nr_frags = skb_shinfo(skb)->nr_frags;
8793 + dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) +
8794 + sizeof(struct qm_sg_entry) * (1 + nr_frags),
8795 + dma_dir);
8796 +
8797 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
8798 + * it's from lowmem.
8799 + */
8800 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
8801 +#ifdef CONFIG_FSL_DPAA_1588
8802 + if (priv->tsu && priv->tsu->valid &&
8803 + priv->tsu->hwts_tx_en_ioctl)
8804 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8805 +#endif
8806 +#ifdef CONFIG_FSL_DPAA_TS
8807 + if (unlikely(priv->ts_tx_en &&
8808 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8809 + struct skb_shared_hwtstamps shhwtstamps;
8810 +
8811 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8812 + skb_tstamp_tx(skb, &shhwtstamps);
8813 + }
8814 +#endif /* CONFIG_FSL_DPAA_TS */
8815 +
8816 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
8817 + sg_addr = qm_sg_addr(&sgt[0]);
8818 + sg_len = qm_sg_entry_get_len(&sgt[0]);
8819 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8820 +
8821 + /* remaining pages were mapped with dma_map_page() */
8822 + for (i = 1; i <= nr_frags; i++) {
8823 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
8824 + sg_addr = qm_sg_addr(&sgt[i]);
8825 + sg_len = qm_sg_entry_get_len(&sgt[i]);
8826 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8827 + }
8828 +
8829 + /* Free the page frag that we allocated on Tx */
8830 + put_page(virt_to_head_page(sgt));
8831 + } else {
8832 + dma_unmap_single(dpa_bp->dev, addr,
8833 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
8834 +#ifdef CONFIG_FSL_DPAA_TS
8835 + /* get the timestamp for non-SG frames */
8836 +#ifdef CONFIG_FSL_DPAA_1588
8837 + if (priv->tsu && priv->tsu->valid &&
8838 + priv->tsu->hwts_tx_en_ioctl)
8839 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8840 +#endif
8841 + if (unlikely(priv->ts_tx_en &&
8842 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8843 + struct skb_shared_hwtstamps shhwtstamps;
8844 +
8845 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8846 + skb_tstamp_tx(skb, &shhwtstamps);
8847 + }
8848 +#endif
8849 + }
8850 +
8851 + return skb;
8852 +}
8853 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
8854 +
8855 +#ifndef CONFIG_FSL_DPAA_TS
8856 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
8857 +{
8858 +#ifndef CONFIG_PPC
8859 + /* Do no recycle skbs realigned by the errata workaround */
8860 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
8861 + return false;
8862 +#endif
8863 +
8864 + /* No recycling possible if skb buffer is kmalloc'ed */
8865 + if (skb->head_frag == 0)
8866 + return false;
8867 +
8868 + /* or if it's an userspace buffer */
8869 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
8870 + return false;
8871 +
8872 + /* or if it's cloned or shared */
8873 + if (skb_shared(skb) || skb_cloned(skb) ||
8874 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
8875 + return false;
8876 +
8877 + return true;
8878 +}
8879 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
8880 +
8881 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
8882 + uint32_t min_size,
8883 + uint16_t min_offset,
8884 + unsigned char **new_buf_start)
8885 +{
8886 + unsigned char *new;
8887 +
8888 + /* In order to recycle a buffer, the following conditions must be met:
8889 + * - buffer size no less than the buffer pool size
8890 + * - buffer size no higher than an upper limit (to avoid moving too much
8891 + * system memory to the buffer pools)
8892 + * - buffer address aligned to cacheline bytes
8893 + * - offset of data from start of buffer no lower than a minimum value
8894 + * - offset of data from start of buffer no higher than a maximum value
8895 + */
8896 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
8897 +
8898 + /* left align to the nearest cacheline */
8899 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
8900 +
8901 + if (likely(new >= skb->head &&
8902 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
8903 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
8904 + *new_buf_start = new;
8905 + return true;
8906 + }
8907 +
8908 + return false;
8909 +}
8910 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
8911 +#endif
8912 +
8913 +/* Build a linear skb around the received buffer.
8914 + * We are guaranteed there is enough room at the end of the data buffer to
8915 + * accommodate the shared info area of the skb.
8916 + */
8917 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
8918 + const struct qm_fd *fd, int *use_gro)
8919 +{
8920 + dma_addr_t addr = qm_fd_addr(fd);
8921 + ssize_t fd_off = dpa_fd_offset(fd);
8922 + void *vaddr;
8923 + const fm_prs_result_t *parse_results;
8924 + struct sk_buff *skb = NULL, **skbh;
8925 +
8926 + vaddr = phys_to_virt(addr);
8927 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
8928 +
8929 + /* Retrieve the skb and adjust data and tail pointers, to make sure
8930 + * forwarded skbs will have enough space on Tx if extra headers
8931 + * are added.
8932 + */
8933 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
8934 +
8935 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
8936 + /* When using jumbo Rx buffers, we risk having frames dropped due to
8937 + * the socket backlog reaching its maximum allowed size.
8938 + * Use the frame length for the skb truesize instead of the buffer
8939 + * size, as this is the size of the data that actually gets copied to
8940 + * userspace.
8941 + * The stack may increase the payload. In this case, it will want to
8942 + * warn us that the frame length is larger than the truesize. We
8943 + * bypass the warning.
8944 + */
8945 +#ifndef CONFIG_PPC
8946 + /* We do not support Jumbo frames on LS1043 and thus we edit
8947 + * the skb truesize only when the 4k errata is not present.
8948 + */
8949 + if (likely(!dpaa_errata_a010022))
8950 +#endif
8951 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
8952 +#endif
8953 +
8954 + DPA_BUG_ON(fd_off != priv->rx_headroom);
8955 + skb_reserve(skb, fd_off);
8956 + skb_put(skb, dpa_fd_length(fd));
8957 +
8958 + /* Peek at the parse results for csum validation */
8959 + parse_results = (const fm_prs_result_t *)(vaddr +
8960 + DPA_RX_PRIV_DATA_SIZE);
8961 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
8962 +
8963 +#ifdef CONFIG_FSL_DPAA_1588
8964 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
8965 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
8966 +#endif
8967 +#ifdef CONFIG_FSL_DPAA_TS
8968 + if (priv->ts_rx_en)
8969 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
8970 +#endif /* CONFIG_FSL_DPAA_TS */
8971 +
8972 + return skb;
8973 +}
8974 +
8975 +
8976 +/* Build an skb with the data of the first S/G entry in the linear portion and
8977 + * the rest of the frame as skb fragments.
8978 + *
8979 + * The page fragment holding the S/G Table is recycled here.
8980 + */
8981 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
8982 + const struct qm_fd *fd, int *use_gro,
8983 + int *count_ptr)
8984 +{
8985 + const struct qm_sg_entry *sgt;
8986 + dma_addr_t addr = qm_fd_addr(fd);
8987 + ssize_t fd_off = dpa_fd_offset(fd);
8988 + dma_addr_t sg_addr;
8989 + void *vaddr, *sg_vaddr;
8990 + struct dpa_bp *dpa_bp;
8991 + struct page *page, *head_page;
8992 + int frag_offset, frag_len;
8993 + int page_offset;
8994 + int i;
8995 + const fm_prs_result_t *parse_results;
8996 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
8997 +
8998 + vaddr = phys_to_virt(addr);
8999 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
9000 +
9001 + dpa_bp = priv->dpa_bp;
9002 + /* Iterate through the SGT entries and add data buffers to the skb */
9003 + sgt = vaddr + fd_off;
9004 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
9005 + /* Extension bit is not supported */
9006 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9007 +
9008 + /* We use a single global Rx pool */
9009 + DPA_BUG_ON(dpa_bp !=
9010 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
9011 +
9012 + sg_addr = qm_sg_addr(&sgt[i]);
9013 + sg_vaddr = phys_to_virt(sg_addr);
9014 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
9015 + SMP_CACHE_BYTES));
9016 +
9017 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
9018 + DMA_BIDIRECTIONAL);
9019 + if (i == 0) {
9020 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
9021 + DPA_BUG_ON(skb->head != sg_vaddr);
9022 +#ifdef CONFIG_FSL_DPAA_1588
9023 + if (priv->tsu && priv->tsu->valid &&
9024 + priv->tsu->hwts_rx_en_ioctl)
9025 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9026 +#endif
9027 +#ifdef CONFIG_FSL_DPAA_TS
9028 + if (priv->ts_rx_en)
9029 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9030 +#endif /* CONFIG_FSL_DPAA_TS */
9031 +
9032 + /* In the case of a SG frame, FMan stores the Internal
9033 + * Context in the buffer containing the sgt.
9034 + * Inspect the parse results before anything else.
9035 + */
9036 + parse_results = (const fm_prs_result_t *)(vaddr +
9037 + DPA_RX_PRIV_DATA_SIZE);
9038 + _dpa_process_parse_results(parse_results, fd, skb,
9039 + use_gro);
9040 +
9041 + /* Make sure forwarded skbs will have enough space
9042 + * on Tx, if extra headers are added.
9043 + */
9044 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9045 + skb_reserve(skb, fd_off);
9046 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
9047 + } else {
9048 + /* Not the first S/G entry; all data from buffer will
9049 + * be added in an skb fragment; fragment index is offset
9050 + * by one since first S/G entry was incorporated in the
9051 + * linear part of the skb.
9052 + *
9053 + * Caution: 'page' may be a tail page.
9054 + */
9055 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
9056 + page = virt_to_page(sg_vaddr);
9057 + head_page = virt_to_head_page(sg_vaddr);
9058 +
9059 + /* Free (only) the skbuff shell because its data buffer
9060 + * is already a frag in the main skb.
9061 + */
9062 + get_page(head_page);
9063 + dev_kfree_skb(skb_tmp);
9064 +
9065 + /* Compute offset in (possibly tail) page */
9066 + page_offset = ((unsigned long)sg_vaddr &
9067 + (PAGE_SIZE - 1)) +
9068 + (page_address(page) - page_address(head_page));
9069 + /* page_offset only refers to the beginning of sgt[i];
9070 + * but the buffer itself may have an internal offset.
9071 + */
9072 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
9073 + page_offset;
9074 + frag_len = qm_sg_entry_get_len(&sgt[i]);
9075 + /* skb_add_rx_frag() does no checking on the page; if
9076 + * we pass it a tail page, we'll end up with
9077 + * bad page accounting and eventually with segafults.
9078 + */
9079 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
9080 + frag_len, dpa_bp->size);
9081 + }
9082 + /* Update the pool count for the current {cpu x bpool} */
9083 + (*count_ptr)--;
9084 +
9085 + if (qm_sg_entry_get_final(&sgt[i]))
9086 + break;
9087 + }
9088 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
9089 +
9090 + /* recycle the SGT fragment */
9091 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9092 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
9093 + return skb;
9094 +}
9095 +
9096 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9097 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
9098 + struct sk_buff *skb)
9099 +{
9100 + if (unlikely(priv->loop_to < 0))
9101 + return 0; /* loop disabled by default */
9102 +
9103 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
9104 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
9105 +
9106 + return 1; /* Frame Tx on the selected interface */
9107 +}
9108 +#endif
9109 +
9110 +void __hot _dpa_rx(struct net_device *net_dev,
9111 + struct qman_portal *portal,
9112 + const struct dpa_priv_s *priv,
9113 + struct dpa_percpu_priv_s *percpu_priv,
9114 + const struct qm_fd *fd,
9115 + u32 fqid,
9116 + int *count_ptr)
9117 +{
9118 + struct dpa_bp *dpa_bp;
9119 + struct sk_buff *skb;
9120 + dma_addr_t addr = qm_fd_addr(fd);
9121 + u32 fd_status = fd->status;
9122 + unsigned int skb_len;
9123 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
9124 + int use_gro = net_dev->features & NETIF_F_GRO;
9125 +
9126 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
9127 + if (netif_msg_hw(priv) && net_ratelimit())
9128 + netdev_warn(net_dev, "FD status = 0x%08x\n",
9129 + fd_status & FM_FD_STAT_RX_ERRORS);
9130 +
9131 + percpu_stats->rx_errors++;
9132 + goto _release_frame;
9133 + }
9134 +
9135 + dpa_bp = priv->dpa_bp;
9136 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9137 +
9138 + /* prefetch the first 64 bytes of the frame or the SGT start */
9139 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
9140 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
9141 +
9142 + /* The only FD types that we may receive are contig and S/G */
9143 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
9144 +
9145 + if (likely(fd->format == qm_fd_contig)) {
9146 +#ifdef CONFIG_FSL_DPAA_HOOKS
9147 + /* Execute the Rx processing hook, if it exists. */
9148 + if (dpaa_eth_hooks.rx_default &&
9149 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
9150 + fqid) == DPAA_ETH_STOLEN) {
9151 + /* won't count the rx bytes in */
9152 + return;
9153 + }
9154 +#endif
9155 + skb = contig_fd_to_skb(priv, fd, &use_gro);
9156 + } else {
9157 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
9158 + percpu_priv->rx_sg++;
9159 + }
9160 +
9161 + /* Account for either the contig buffer or the SGT buffer (depending on
9162 + * which case we were in) having been removed from the pool.
9163 + */
9164 + (*count_ptr)--;
9165 + skb->protocol = eth_type_trans(skb, net_dev);
9166 +
9167 + /* IP Reassembled frames are allowed to be larger than MTU */
9168 + if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu) &&
9169 + !(fd_status & FM_FD_IPR))) {
9170 + percpu_stats->rx_dropped++;
9171 + goto drop_bad_frame;
9172 + }
9173 +
9174 + skb_len = skb->len;
9175 +
9176 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9177 + if (dpa_skb_loop(priv, skb)) {
9178 + percpu_stats->rx_packets++;
9179 + percpu_stats->rx_bytes += skb_len;
9180 + return;
9181 + }
9182 +#endif
9183 +
9184 + if (use_gro) {
9185 + gro_result_t gro_result;
9186 + const struct qman_portal_config *pc =
9187 + qman_p_get_portal_config(portal);
9188 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
9189 +
9190 + np->p = portal;
9191 + gro_result = napi_gro_receive(&np->napi, skb);
9192 + /* If frame is dropped by the stack, rx_dropped counter is
9193 + * incremented automatically, so no need for us to update it
9194 + */
9195 + if (unlikely(gro_result == GRO_DROP))
9196 + goto packet_dropped;
9197 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
9198 + goto packet_dropped;
9199 +
9200 + percpu_stats->rx_packets++;
9201 + percpu_stats->rx_bytes += skb_len;
9202 +
9203 +packet_dropped:
9204 + return;
9205 +
9206 +drop_bad_frame:
9207 + dev_kfree_skb(skb);
9208 + return;
9209 +
9210 +_release_frame:
9211 + dpa_fd_release(net_dev, fd);
9212 +}
9213 +
9214 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
9215 + struct sk_buff *skb, struct qm_fd *fd,
9216 + int *count_ptr, int *offset)
9217 +{
9218 + struct sk_buff **skbh;
9219 + dma_addr_t addr;
9220 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9221 + struct net_device *net_dev = priv->net_dev;
9222 + int err;
9223 + enum dma_data_direction dma_dir;
9224 + unsigned char *buffer_start;
9225 + int dma_map_size;
9226 +
9227 +#ifndef CONFIG_FSL_DPAA_TS
9228 + /* Check recycling conditions; only if timestamp support is not
9229 + * enabled, otherwise we need the fd back on tx confirmation
9230 + */
9231 +
9232 + /* We can recycle the buffer if:
9233 + * - the pool is not full
9234 + * - the buffer meets the skb recycling conditions
9235 + * - the buffer meets our own (size, offset, align) conditions
9236 + */
9237 + if (likely((*count_ptr < dpa_bp->target_count) &&
9238 + dpa_skb_is_recyclable(skb) &&
9239 + dpa_buf_is_recyclable(skb, dpa_bp->size,
9240 + priv->tx_headroom, &buffer_start))) {
9241 + /* Buffer is recyclable; use the new start address
9242 + * and set fd parameters and DMA mapping direction
9243 + */
9244 + fd->bpid = dpa_bp->bpid;
9245 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
9246 + fd->offset = (uint16_t)(skb->data - buffer_start);
9247 + dma_dir = DMA_BIDIRECTIONAL;
9248 + dma_map_size = dpa_bp->size;
9249 +
9250 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
9251 + *offset = skb_headroom(skb) - fd->offset;
9252 + } else
9253 +#endif
9254 + {
9255 + /* Not recyclable.
9256 + * We are guaranteed to have at least tx_headroom bytes
9257 + * available, so just use that for offset.
9258 + */
9259 + fd->bpid = 0xff;
9260 + buffer_start = skb->data - priv->tx_headroom;
9261 + fd->offset = priv->tx_headroom;
9262 + dma_dir = DMA_TO_DEVICE;
9263 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
9264 +
9265 + /* The buffer will be Tx-confirmed, but the TxConf cb must
9266 + * necessarily look at our Tx private data to retrieve the
9267 + * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.)
9268 + */
9269 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
9270 + }
9271 +
9272 + /* Enable L3/L4 hardware checksum computation.
9273 + *
9274 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9275 + * need to write into the skb.
9276 + */
9277 + err = dpa_enable_tx_csum(priv, skb, fd,
9278 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
9279 + if (unlikely(err < 0)) {
9280 + if (netif_msg_tx_err(priv) && net_ratelimit())
9281 + netdev_err(net_dev, "HW csum error: %d\n", err);
9282 + return err;
9283 + }
9284 +
9285 + /* Fill in the rest of the FD fields */
9286 + fd->format = qm_fd_contig;
9287 + fd->length20 = skb->len;
9288 + fd->cmd |= FM_FD_CMD_FCO;
9289 +
9290 + /* Map the entire buffer size that may be seen by FMan, but no more */
9291 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
9292 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9293 + if (netif_msg_tx_err(priv) && net_ratelimit())
9294 + netdev_err(net_dev, "dma_map_single() failed\n");
9295 + return -EINVAL;
9296 + }
9297 + qm_fd_addr_set64(fd, addr);
9298 +
9299 + return 0;
9300 +}
9301 +EXPORT_SYMBOL(skb_to_contig_fd);
9302 +
9303 +#ifndef CONFIG_PPC
9304 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
9305 + * 16 bytes and 4K memory address crossings.
9306 + */
9307 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
9308 +{
9309 + int nr_frags, i = 0;
9310 + skb_frag_t *frag;
9311 +
9312 + /* Check if the headroom is aligned */
9313 + if (((uintptr_t)skb->data - priv->tx_headroom) %
9314 + priv->buf_layout[TX].data_align != 0)
9315 + return true;
9316 +
9317 + /* Check if the headroom crosses a boundary */
9318 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
9319 + return true;
9320 +
9321 + /* Check if the non-paged data crosses a boundary */
9322 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
9323 + return true;
9324 +
9325 + /* Check if the entire linear skb crosses a boundary */
9326 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
9327 + return true;
9328 +
9329 + nr_frags = skb_shinfo(skb)->nr_frags;
9330 +
9331 + while (i < nr_frags) {
9332 + frag = &skb_shinfo(skb)->frags[i];
9333 +
9334 + /* Check if a paged fragment crosses a boundary from its
9335 + * offset to its end.
9336 + */
9337 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
9338 + return true;
9339 +
9340 + i++;
9341 + }
9342 +
9343 + return false;
9344 +}
9345 +
9346 +/* Realign the skb by copying its contents at the start of a newly allocated
9347 + * page. Build a new skb around the new buffer and release the old one.
9348 + * A performance drop should be expected.
9349 + */
9350 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
9351 + struct dpa_priv_s *priv)
9352 +{
9353 + int trans_offset = skb_transport_offset(skb);
9354 + int net_offset = skb_network_offset(skb);
9355 + struct sk_buff *nskb = NULL;
9356 + int nsize, headroom;
9357 + struct page *npage;
9358 + void *npage_addr;
9359 +
9360 + /* Guarantee the minimum required headroom */
9361 + if (skb_headroom(skb) >= priv->tx_headroom)
9362 + headroom = skb_headroom(skb);
9363 + else
9364 + headroom = priv->tx_headroom;
9365 +
9366 + npage = alloc_page(GFP_ATOMIC);
9367 + if (unlikely(!npage)) {
9368 + WARN_ONCE(1, "Memory allocation failure\n");
9369 + return NULL;
9370 + }
9371 + npage_addr = page_address(npage);
9372 +
9373 + /* For the new skb we only need the old one's data (both non-paged and
9374 + * paged) and a headroom large enough to fit our private info. We can
9375 + * skip the old tailroom.
9376 + *
9377 + * Make sure the new linearized buffer will not exceed a page's size.
9378 + */
9379 + nsize = headroom + skb->len +
9380 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
9381 + if (unlikely(nsize > 4096))
9382 + goto err;
9383 +
9384 + nskb = build_skb(npage_addr, nsize);
9385 + if (unlikely(!nskb))
9386 + goto err;
9387 +
9388 + /* Reserve only the needed headroom in order to guarantee the data's
9389 + * alignment.
9390 + * Code borrowed and adapted from skb_copy().
9391 + */
9392 + skb_reserve(nskb, priv->tx_headroom);
9393 + skb_put(nskb, skb->len);
9394 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
9395 + WARN_ONCE(1, "skb parsing failure\n");
9396 + goto err;
9397 + }
9398 + copy_skb_header(nskb, skb);
9399 +
9400 +#ifdef CONFIG_FSL_DPAA_TS
9401 + /* Copy relevant timestamp info from the old skb to the new */
9402 + if (priv->ts_tx_en) {
9403 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
9404 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
9405 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
9406 + if (skb->sk)
9407 + skb_set_owner_w(nskb, skb->sk);
9408 + }
9409 +#endif
9410 + /* We move the headroom when we align it so we have to reset the
9411 + * network and transport header offsets relative to the new data
9412 + * pointer. The checksum offload relies on these offsets.
9413 + */
9414 + skb_set_network_header(nskb, net_offset);
9415 + skb_set_transport_header(nskb, trans_offset);
9416 +
9417 + /* We don't want the buffer to be recycled so we mark it accordingly */
9418 + nskb->mark = NONREC_MARK;
9419 +
9420 + dev_kfree_skb(skb);
9421 + return nskb;
9422 +
9423 +err:
9424 + if (nskb)
9425 + dev_kfree_skb(nskb);
9426 + put_page(npage);
9427 + return NULL;
9428 +}
9429 +#endif
9430 +
9431 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
9432 + struct sk_buff *skb, struct qm_fd *fd)
9433 +{
9434 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9435 + dma_addr_t addr;
9436 + dma_addr_t sg_addr;
9437 + struct sk_buff **skbh;
9438 + struct net_device *net_dev = priv->net_dev;
9439 + int sg_len, sgt_size;
9440 + int err;
9441 +
9442 + struct qm_sg_entry *sgt;
9443 + void *sgt_buf;
9444 + skb_frag_t *frag;
9445 + int i = 0, j = 0;
9446 + int nr_frags;
9447 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
9448 +
9449 + nr_frags = skb_shinfo(skb)->nr_frags;
9450 + fd->format = qm_fd_sg;
9451 +
9452 + sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags);
9453 +
9454 + /* Get a page frag to store the SGTable, or a full page if the errata
9455 + * is in place and we need to avoid crossing a 4k boundary.
9456 + */
9457 +#ifndef CONFIG_PPC
9458 + if (unlikely(dpaa_errata_a010022))
9459 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
9460 + else
9461 +#endif
9462 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
9463 + if (unlikely(!sgt_buf)) {
9464 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
9465 + return -ENOMEM;
9466 + }
9467 +
9468 + /* it seems that the memory allocator does not zero the allocated mem */
9469 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
9470 +
9471 + /* Enable L3/L4 hardware checksum computation.
9472 + *
9473 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9474 + * need to write into the skb.
9475 + */
9476 + err = dpa_enable_tx_csum(priv, skb, fd,
9477 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
9478 + if (unlikely(err < 0)) {
9479 + if (netif_msg_tx_err(priv) && net_ratelimit())
9480 + netdev_err(net_dev, "HW csum error: %d\n", err);
9481 + goto csum_failed;
9482 + }
9483 +
9484 + /* Assign the data from skb->data to the first SG list entry */
9485 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
9486 + sg_len = skb_headlen(skb);
9487 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
9488 + qm_sg_entry_set_offset(&sgt[0], 0);
9489 + qm_sg_entry_set_len(&sgt[0], sg_len);
9490 + qm_sg_entry_set_ext(&sgt[0], 0);
9491 + qm_sg_entry_set_final(&sgt[0], 0);
9492 +
9493 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
9494 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9495 + dev_err(dpa_bp->dev, "DMA mapping failed");
9496 + err = -EINVAL;
9497 + goto sg0_map_failed;
9498 + }
9499 +
9500 + qm_sg_entry_set64(&sgt[0], addr);
9501 +
9502 + /* populate the rest of SGT entries */
9503 + for (i = 1; i <= nr_frags; i++) {
9504 + frag = &skb_shinfo(skb)->frags[i - 1];
9505 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
9506 + qm_sg_entry_set_offset(&sgt[i], 0);
9507 + qm_sg_entry_set_len(&sgt[i], frag->size);
9508 + qm_sg_entry_set_ext(&sgt[i], 0);
9509 +
9510 + if (i == nr_frags)
9511 + qm_sg_entry_set_final(&sgt[i], 1);
9512 + else
9513 + qm_sg_entry_set_final(&sgt[i], 0);
9514 +
9515 + DPA_BUG_ON(!skb_frag_page(frag));
9516 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
9517 + dma_dir);
9518 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9519 + dev_err(dpa_bp->dev, "DMA mapping failed");
9520 + err = -EINVAL;
9521 + goto sg_map_failed;
9522 + }
9523 +
9524 + /* keep the offset in the address */
9525 + qm_sg_entry_set64(&sgt[i], addr);
9526 + }
9527 +
9528 + fd->length20 = skb->len;
9529 + fd->offset = priv->tx_headroom;
9530 +
9531 + /* DMA map the SGT page */
9532 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
9533 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
9534 + priv->tx_headroom + sgt_size,
9535 + dma_dir);
9536 +
9537 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9538 + dev_err(dpa_bp->dev, "DMA mapping failed");
9539 + err = -EINVAL;
9540 + goto sgt_map_failed;
9541 + }
9542 +
9543 + qm_fd_addr_set64(fd, addr);
9544 + fd->bpid = 0xff;
9545 + fd->cmd |= FM_FD_CMD_FCO;
9546 +
9547 + return 0;
9548 +
9549 +sgt_map_failed:
9550 +sg_map_failed:
9551 + for (j = 0; j < i; j++) {
9552 + sg_addr = qm_sg_addr(&sgt[j]);
9553 + dma_unmap_page(dpa_bp->dev, sg_addr,
9554 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
9555 + }
9556 +sg0_map_failed:
9557 +csum_failed:
9558 + put_page(virt_to_head_page(sgt_buf));
9559 +
9560 + return err;
9561 +}
9562 +EXPORT_SYMBOL(skb_to_sg_fd);
9563 +
9564 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
9565 +{
9566 + struct dpa_priv_s *priv;
9567 + const int queue_mapping = dpa_get_queue_mapping(skb);
9568 + struct qman_fq *egress_fq, *conf_fq;
9569 +
9570 +#ifdef CONFIG_FSL_DPAA_HOOKS
9571 + /* If there is a Tx hook, run it. */
9572 + if (dpaa_eth_hooks.tx &&
9573 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
9574 + /* won't update any Tx stats */
9575 + return NETDEV_TX_OK;
9576 +#endif
9577 +
9578 + priv = netdev_priv(net_dev);
9579 +
9580 +#ifdef CONFIG_FSL_DPAA_CEETM
9581 + if (priv->ceetm_en)
9582 + return ceetm_tx(skb, net_dev);
9583 +#endif
9584 +
9585 + egress_fq = priv->egress_fqs[queue_mapping];
9586 + conf_fq = priv->conf_fqs[queue_mapping];
9587 +
9588 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
9589 +}
9590 +
9591 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
9592 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
9593 +{
9594 + struct dpa_priv_s *priv;
9595 + struct qm_fd fd;
9596 + struct dpa_percpu_priv_s *percpu_priv;
9597 + struct rtnl_link_stats64 *percpu_stats;
9598 + int err = 0;
9599 + bool nonlinear;
9600 + int *countptr, offset = 0;
9601 +
9602 + priv = netdev_priv(net_dev);
9603 + /* Non-migratable context, safe to use raw_cpu_ptr */
9604 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
9605 + percpu_stats = &percpu_priv->stats;
9606 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
9607 +
9608 + clear_fd(&fd);
9609 +
9610 +#ifndef CONFIG_PPC
9611 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
9612 + skb = a010022_realign_skb(skb, priv);
9613 + if (!skb)
9614 + goto skb_to_fd_failed;
9615 + }
9616 +#endif
9617 +
9618 + nonlinear = skb_is_nonlinear(skb);
9619 +
9620 +#ifdef CONFIG_FSL_DPAA_1588
9621 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
9622 + fd.cmd |= FM_FD_CMD_UPD;
9623 +#endif
9624 +#ifdef CONFIG_FSL_DPAA_TS
9625 + if (unlikely(priv->ts_tx_en &&
9626 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
9627 + fd.cmd |= FM_FD_CMD_UPD;
9628 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
9629 +#endif /* CONFIG_FSL_DPAA_TS */
9630 +
9631 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
9632 + * we don't feed FMan with more fragments than it supports.
9633 + * Btw, we're using the first sgt entry to store the linear part of
9634 + * the skb, so we're one extra frag short.
9635 + */
9636 + if (nonlinear &&
9637 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
9638 + /* Just create a S/G fd based on the skb */
9639 + err = skb_to_sg_fd(priv, skb, &fd);
9640 + percpu_priv->tx_frag_skbuffs++;
9641 + } else {
9642 + /* Make sure we have enough headroom to accommodate private
9643 + * data, parse results, etc. Normally this shouldn't happen if
9644 + * we're here via the standard kernel stack.
9645 + */
9646 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
9647 + struct sk_buff *skb_new;
9648 +
9649 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
9650 + if (unlikely(!skb_new)) {
9651 + dev_kfree_skb(skb);
9652 + percpu_stats->tx_errors++;
9653 + return NETDEV_TX_OK;
9654 + }
9655 + dev_kfree_skb(skb);
9656 + skb = skb_new;
9657 + }
9658 +
9659 + /* We're going to store the skb backpointer at the beginning
9660 + * of the data buffer, so we need a privately owned skb
9661 + */
9662 +
9663 + /* Code borrowed from skb_unshare(). */
9664 + if (skb_cloned(skb)) {
9665 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
9666 + kfree_skb(skb);
9667 + skb = nskb;
9668 +#ifndef CONFIG_PPC
9669 + if (unlikely(dpaa_errata_a010022) &&
9670 + a010022_check_skb(skb, priv)) {
9671 + skb = a010022_realign_skb(skb, priv);
9672 + if (!skb)
9673 + goto skb_to_fd_failed;
9674 + }
9675 +#endif
9676 + /* skb_copy() has now linearized the skbuff. */
9677 + } else if (unlikely(nonlinear)) {
9678 + /* We are here because the egress skb contains
9679 + * more fragments than we support. In this case,
9680 + * we have no choice but to linearize it ourselves.
9681 + */
9682 + err = __skb_linearize(skb);
9683 + }
9684 + if (unlikely(!skb || err < 0))
9685 + /* Common out-of-memory error path */
9686 + goto enomem;
9687 +
9688 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
9689 + }
9690 + if (unlikely(err < 0))
9691 + goto skb_to_fd_failed;
9692 +
9693 + if (fd.bpid != 0xff) {
9694 + skb_recycle(skb);
9695 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
9696 + * but we need the skb to look as if returned by build_skb().
9697 + * We need to manually adjust the tailptr as well.
9698 + */
9699 + skb->data = skb->head + offset;
9700 + skb_reset_tail_pointer(skb);
9701 +
9702 + (*countptr)++;
9703 + percpu_priv->tx_returned++;
9704 + }
9705 +
9706 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
9707 + goto xmit_failed;
9708 +
9709 + netif_trans_update(net_dev);
9710 + return NETDEV_TX_OK;
9711 +
9712 +xmit_failed:
9713 + if (fd.bpid != 0xff) {
9714 + (*countptr)--;
9715 + percpu_priv->tx_returned--;
9716 + dpa_fd_release(net_dev, &fd);
9717 + percpu_stats->tx_errors++;
9718 + return NETDEV_TX_OK;
9719 + }
9720 + _dpa_cleanup_tx_fd(priv, &fd);
9721 +skb_to_fd_failed:
9722 +enomem:
9723 + percpu_stats->tx_errors++;
9724 + dev_kfree_skb(skb);
9725 + return NETDEV_TX_OK;
9726 +}
9727 +EXPORT_SYMBOL(dpa_tx_extended);
9728 --- /dev/null
9729 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9730 @@ -0,0 +1,278 @@
9731 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
9732 + *
9733 + * Redistribution and use in source and binary forms, with or without
9734 + * modification, are permitted provided that the following conditions are met:
9735 + * * Redistributions of source code must retain the above copyright
9736 + * notice, this list of conditions and the following disclaimer.
9737 + * * Redistributions in binary form must reproduce the above copyright
9738 + * notice, this list of conditions and the following disclaimer in the
9739 + * documentation and/or other materials provided with the distribution.
9740 + * * Neither the name of Freescale Semiconductor nor the
9741 + * names of its contributors may be used to endorse or promote products
9742 + * derived from this software without specific prior written permission.
9743 + *
9744 + *
9745 + * ALTERNATIVELY, this software may be distributed under the terms of the
9746 + * GNU General Public License ("GPL") as published by the Free Software
9747 + * Foundation, either version 2 of that License or (at your option) any
9748 + * later version.
9749 + *
9750 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9751 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9752 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9753 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9754 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9755 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9756 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9757 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9758 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9759 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9760 + */
9761 +
9762 +#include <linux/init.h>
9763 +#include <linux/module.h>
9764 +#include <linux/kthread.h>
9765 +#include <linux/io.h>
9766 +#include <linux/of_net.h>
9767 +#include "dpaa_eth.h"
9768 +#include "mac.h" /* struct mac_device */
9769 +#ifdef CONFIG_FSL_DPAA_1588
9770 +#include "dpaa_1588.h"
9771 +#endif
9772 +
9773 +static ssize_t dpaa_eth_show_addr(struct device *dev,
9774 + struct device_attribute *attr, char *buf)
9775 +{
9776 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9777 + struct mac_device *mac_dev = priv->mac_dev;
9778 +
9779 + if (mac_dev)
9780 + return sprintf(buf, "%llx",
9781 + (unsigned long long)mac_dev->res->start);
9782 + else
9783 + return sprintf(buf, "none");
9784 +}
9785 +
9786 +static ssize_t dpaa_eth_show_type(struct device *dev,
9787 + struct device_attribute *attr, char *buf)
9788 +{
9789 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9790 + ssize_t res = 0;
9791 +
9792 + if (priv)
9793 + res = sprintf(buf, "%s", priv->if_type);
9794 +
9795 + return res;
9796 +}
9797 +
9798 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
9799 + struct device_attribute *attr, char *buf)
9800 +{
9801 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9802 + ssize_t bytes = 0;
9803 + int i = 0;
9804 + char *str;
9805 + struct dpa_fq *fq;
9806 + struct dpa_fq *tmp;
9807 + struct dpa_fq *prev = NULL;
9808 + u32 first_fqid = 0;
9809 + u32 last_fqid = 0;
9810 + char *prevstr = NULL;
9811 +
9812 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
9813 + switch (fq->fq_type) {
9814 + case FQ_TYPE_RX_DEFAULT:
9815 + str = "Rx default";
9816 + break;
9817 + case FQ_TYPE_RX_ERROR:
9818 + str = "Rx error";
9819 + break;
9820 + case FQ_TYPE_RX_PCD:
9821 + str = "Rx PCD";
9822 + break;
9823 + case FQ_TYPE_TX_CONFIRM:
9824 + str = "Tx default confirmation";
9825 + break;
9826 + case FQ_TYPE_TX_CONF_MQ:
9827 + str = "Tx confirmation (mq)";
9828 + break;
9829 + case FQ_TYPE_TX_ERROR:
9830 + str = "Tx error";
9831 + break;
9832 + case FQ_TYPE_TX:
9833 + str = "Tx";
9834 + break;
9835 + case FQ_TYPE_RX_PCD_HI_PRIO:
9836 + str ="Rx PCD High Priority";
9837 + break;
9838 + default:
9839 + str = "Unknown";
9840 + }
9841 +
9842 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
9843 + str != prevstr)) {
9844 + if (last_fqid == first_fqid)
9845 + bytes += sprintf(buf + bytes,
9846 + "%s: %d\n", prevstr, prev->fqid);
9847 + else
9848 + bytes += sprintf(buf + bytes,
9849 + "%s: %d - %d\n", prevstr,
9850 + first_fqid, last_fqid);
9851 + }
9852 +
9853 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
9854 + last_fqid = fq->fqid;
9855 + else
9856 + first_fqid = last_fqid = fq->fqid;
9857 +
9858 + prev = fq;
9859 + prevstr = str;
9860 + i++;
9861 + }
9862 +
9863 + if (prev) {
9864 + if (last_fqid == first_fqid)
9865 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
9866 + prev->fqid);
9867 + else
9868 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
9869 + first_fqid, last_fqid);
9870 + }
9871 +
9872 + return bytes;
9873 +}
9874 +
9875 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
9876 + struct device_attribute *attr, char *buf)
9877 +{
9878 + ssize_t bytes = 0;
9879 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9880 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9881 + int i = 0;
9882 +
9883 + for (i = 0; i < priv->bp_count; i++)
9884 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
9885 + dpa_bp[i].bpid);
9886 +
9887 + return bytes;
9888 +}
9889 +
9890 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
9891 + struct device_attribute *attr, char *buf)
9892 +{
9893 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9894 + struct mac_device *mac_dev = priv->mac_dev;
9895 + int n = 0;
9896 +
9897 + if (mac_dev)
9898 + n = fm_mac_dump_regs(mac_dev, buf, n);
9899 + else
9900 + return sprintf(buf, "no mac registers\n");
9901 +
9902 + return n;
9903 +}
9904 +
9905 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
9906 + struct device_attribute *attr, char *buf)
9907 +{
9908 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9909 + struct mac_device *mac_dev = priv->mac_dev;
9910 + int n = 0;
9911 +
9912 + if (mac_dev)
9913 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
9914 + else
9915 + return sprintf(buf, "no mac rx stats\n");
9916 +
9917 + return n;
9918 +}
9919 +
9920 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
9921 + struct device_attribute *attr, char *buf)
9922 +{
9923 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9924 + struct mac_device *mac_dev = priv->mac_dev;
9925 + int n = 0;
9926 +
9927 + if (mac_dev)
9928 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
9929 + else
9930 + return sprintf(buf, "no mac tx stats\n");
9931 +
9932 + return n;
9933 +}
9934 +
9935 +#ifdef CONFIG_FSL_DPAA_1588
9936 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
9937 + struct device_attribute *attr, char *buf)
9938 +{
9939 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9940 +
9941 + if (priv->tsu && priv->tsu->valid)
9942 + return sprintf(buf, "1\n");
9943 + else
9944 + return sprintf(buf, "0\n");
9945 +}
9946 +
9947 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
9948 + struct device_attribute *attr,
9949 + const char *buf, size_t count)
9950 +{
9951 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9952 + unsigned int num;
9953 + unsigned long flags;
9954 +
9955 + if (kstrtouint(buf, 0, &num) < 0)
9956 + return -EINVAL;
9957 +
9958 + local_irq_save(flags);
9959 +
9960 + if (num) {
9961 + if (priv->tsu)
9962 + priv->tsu->valid = TRUE;
9963 + } else {
9964 + if (priv->tsu)
9965 + priv->tsu->valid = FALSE;
9966 + }
9967 +
9968 + local_irq_restore(flags);
9969 +
9970 + return count;
9971 +}
9972 +#endif
9973 +
9974 +static struct device_attribute dpaa_eth_attrs[] = {
9975 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
9976 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
9977 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
9978 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
9979 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
9980 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
9981 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
9982 +#ifdef CONFIG_FSL_DPAA_1588
9983 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
9984 + dpaa_eth_set_ptp_1588),
9985 +#endif
9986 +};
9987 +
9988 +void dpaa_eth_sysfs_init(struct device *dev)
9989 +{
9990 + int i;
9991 +
9992 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
9993 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
9994 + dev_err(dev, "Error creating sysfs file\n");
9995 + while (i > 0)
9996 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
9997 + return;
9998 + }
9999 +}
10000 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
10001 +
10002 +void dpaa_eth_sysfs_remove(struct device *dev)
10003 +{
10004 + int i;
10005 +
10006 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10007 + device_remove_file(dev, &dpaa_eth_attrs[i]);
10008 +}
10009 --- /dev/null
10010 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10011 @@ -0,0 +1,144 @@
10012 +/* Copyright 2013 Freescale Semiconductor Inc.
10013 + *
10014 + * Redistribution and use in source and binary forms, with or without
10015 + * modification, are permitted provided that the following conditions are met:
10016 + * * Redistributions of source code must retain the above copyright
10017 + * notice, this list of conditions and the following disclaimer.
10018 + * * Redistributions in binary form must reproduce the above copyright
10019 + * notice, this list of conditions and the following disclaimer in the
10020 + * documentation and/or other materials provided with the distribution.
10021 + * * Neither the name of Freescale Semiconductor nor the
10022 + * names of its contributors may be used to endorse or promote products
10023 + * derived from this software without specific prior written permission.
10024 + *
10025 + *
10026 + * ALTERNATIVELY, this software may be distributed under the terms of the
10027 + * GNU General Public License ("GPL") as published by the Free Software
10028 + * Foundation, either version 2 of that License or (at your option) any
10029 + * later version.
10030 + *
10031 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10032 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10033 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10034 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10035 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10036 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10037 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10038 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10039 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10040 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10041 + */
10042 +
10043 +#undef TRACE_SYSTEM
10044 +#define TRACE_SYSTEM dpaa_eth
10045 +
10046 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
10047 +#define _DPAA_ETH_TRACE_H
10048 +
10049 +#include <linux/skbuff.h>
10050 +#include <linux/netdevice.h>
10051 +#include "dpaa_eth.h"
10052 +#include <linux/tracepoint.h>
10053 +
10054 +#define fd_format_name(format) { qm_fd_##format, #format }
10055 +#define fd_format_list \
10056 + fd_format_name(contig), \
10057 + fd_format_name(sg)
10058 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
10059 + " status=0x%08x"
10060 +
10061 +/* This is used to declare a class of events.
10062 + * individual events of this type will be defined below.
10063 + */
10064 +
10065 +/* Store details about a frame descriptor and the FQ on which it was
10066 + * transmitted/received.
10067 + */
10068 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
10069 + /* Trace function prototype */
10070 + TP_PROTO(struct net_device *netdev,
10071 + struct qman_fq *fq,
10072 + const struct qm_fd *fd),
10073 +
10074 + /* Repeat argument list here */
10075 + TP_ARGS(netdev, fq, fd),
10076 +
10077 + /* A structure containing the relevant information we want to record.
10078 + * Declare name and type for each normal element, name, type and size
10079 + * for arrays. Use __string for variable length strings.
10080 + */
10081 + TP_STRUCT__entry(
10082 + __field(u32, fqid)
10083 + __field(u64, fd_addr)
10084 + __field(u8, fd_format)
10085 + __field(u16, fd_offset)
10086 + __field(u32, fd_length)
10087 + __field(u32, fd_status)
10088 + __string(name, netdev->name)
10089 + ),
10090 +
10091 + /* The function that assigns values to the above declared fields */
10092 + TP_fast_assign(
10093 + __entry->fqid = fq->fqid;
10094 + __entry->fd_addr = qm_fd_addr_get64(fd);
10095 + __entry->fd_format = fd->format;
10096 + __entry->fd_offset = dpa_fd_offset(fd);
10097 + __entry->fd_length = dpa_fd_length(fd);
10098 + __entry->fd_status = fd->status;
10099 + __assign_str(name, netdev->name);
10100 + ),
10101 +
10102 + /* This is what gets printed when the trace event is triggered */
10103 + /* TODO: print the status using __print_flags() */
10104 + TP_printk(TR_FMT,
10105 + __get_str(name), __entry->fqid, __entry->fd_addr,
10106 + __print_symbolic(__entry->fd_format, fd_format_list),
10107 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
10108 +);
10109 +
10110 +/* Now declare events of the above type. Format is:
10111 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
10112 + */
10113 +
10114 +/* Tx (egress) fd */
10115 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
10116 +
10117 + TP_PROTO(struct net_device *netdev,
10118 + struct qman_fq *fq,
10119 + const struct qm_fd *fd),
10120 +
10121 + TP_ARGS(netdev, fq, fd)
10122 +);
10123 +
10124 +/* Rx fd */
10125 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
10126 +
10127 + TP_PROTO(struct net_device *netdev,
10128 + struct qman_fq *fq,
10129 + const struct qm_fd *fd),
10130 +
10131 + TP_ARGS(netdev, fq, fd)
10132 +);
10133 +
10134 +/* Tx confirmation fd */
10135 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
10136 +
10137 + TP_PROTO(struct net_device *netdev,
10138 + struct qman_fq *fq,
10139 + const struct qm_fd *fd),
10140 +
10141 + TP_ARGS(netdev, fq, fd)
10142 +);
10143 +
10144 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
10145 + * The syntax is the same as for DECLARE_EVENT_CLASS().
10146 + */
10147 +
10148 +#endif /* _DPAA_ETH_TRACE_H */
10149 +
10150 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
10151 +#undef TRACE_INCLUDE_PATH
10152 +#define TRACE_INCLUDE_PATH .
10153 +#undef TRACE_INCLUDE_FILE
10154 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
10155 +#include <trace/define_trace.h>
10156 --- /dev/null
10157 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10158 @@ -0,0 +1,544 @@
10159 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10160 + *
10161 + * Redistribution and use in source and binary forms, with or without
10162 + * modification, are permitted provided that the following conditions are met:
10163 + * * Redistributions of source code must retain the above copyright
10164 + * notice, this list of conditions and the following disclaimer.
10165 + * * Redistributions in binary form must reproduce the above copyright
10166 + * notice, this list of conditions and the following disclaimer in the
10167 + * documentation and/or other materials provided with the distribution.
10168 + * * Neither the name of Freescale Semiconductor nor the
10169 + * names of its contributors may be used to endorse or promote products
10170 + * derived from this software without specific prior written permission.
10171 + *
10172 + *
10173 + * ALTERNATIVELY, this software may be distributed under the terms of the
10174 + * GNU General Public License ("GPL") as published by the Free Software
10175 + * Foundation, either version 2 of that License or (at your option) any
10176 + * later version.
10177 + *
10178 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10179 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10180 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10181 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10182 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10183 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10184 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10185 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10186 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10187 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10188 + */
10189 +
10190 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10191 +#define pr_fmt(fmt) \
10192 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10193 + KBUILD_BASENAME".c", __LINE__, __func__
10194 +#else
10195 +#define pr_fmt(fmt) \
10196 + KBUILD_MODNAME ": " fmt
10197 +#endif
10198 +
10199 +#include <linux/string.h>
10200 +
10201 +#include "dpaa_eth.h"
10202 +#include "mac.h" /* struct mac_device */
10203 +#include "dpaa_eth_common.h"
10204 +
10205 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
10206 + "interrupts",
10207 + "rx packets",
10208 + "tx packets",
10209 + "tx recycled",
10210 + "tx confirm",
10211 + "tx S/G",
10212 + "rx S/G",
10213 + "tx error",
10214 + "rx error",
10215 + "bp count"
10216 +};
10217 +
10218 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
10219 + /* dpa rx errors */
10220 + "rx dma error",
10221 + "rx frame physical error",
10222 + "rx frame size error",
10223 + "rx header error",
10224 + "rx csum error",
10225 +
10226 + /* demultiplexing errors */
10227 + "qman cg_tdrop",
10228 + "qman wred",
10229 + "qman error cond",
10230 + "qman early window",
10231 + "qman late window",
10232 + "qman fq tdrop",
10233 + "qman fq retired",
10234 + "qman orp disabled",
10235 +
10236 + /* congestion related stats */
10237 + "congestion time (ms)",
10238 + "entered congestion",
10239 + "congested (0/1)"
10240 +};
10241 +
10242 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
10243 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
10244 +
10245 +static int __cold dpa_get_settings(struct net_device *net_dev,
10246 + struct ethtool_cmd *et_cmd)
10247 +{
10248 + int _errno;
10249 + struct dpa_priv_s *priv;
10250 +
10251 + priv = netdev_priv(net_dev);
10252 +
10253 + if (priv->mac_dev == NULL) {
10254 + netdev_info(net_dev, "This is a MAC-less interface\n");
10255 + return -ENODEV;
10256 + }
10257 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10258 + netdev_dbg(net_dev, "phy device not initialized\n");
10259 + return 0;
10260 + }
10261 +
10262 + _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd);
10263 + if (unlikely(_errno < 0))
10264 + netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno);
10265 +
10266 + return _errno;
10267 +}
10268 +
10269 +static int __cold dpa_set_settings(struct net_device *net_dev,
10270 + struct ethtool_cmd *et_cmd)
10271 +{
10272 + int _errno;
10273 + struct dpa_priv_s *priv;
10274 +
10275 + priv = netdev_priv(net_dev);
10276 +
10277 + if (priv->mac_dev == NULL) {
10278 + netdev_info(net_dev, "This is a MAC-less interface\n");
10279 + return -ENODEV;
10280 + }
10281 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10282 + netdev_err(net_dev, "phy device not initialized\n");
10283 + return -ENODEV;
10284 + }
10285 +
10286 + _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd);
10287 + if (unlikely(_errno < 0))
10288 + netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno);
10289 +
10290 + return _errno;
10291 +}
10292 +
10293 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
10294 + struct ethtool_drvinfo *drvinfo)
10295 +{
10296 + int _errno;
10297 +
10298 + strncpy(drvinfo->driver, KBUILD_MODNAME,
10299 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
10300 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
10301 + "%X", 0);
10302 +
10303 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
10304 + /* Truncated output */
10305 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
10306 + } else if (unlikely(_errno < 0)) {
10307 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
10308 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
10309 + }
10310 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
10311 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
10312 +}
10313 +
10314 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
10315 +{
10316 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
10317 +}
10318 +
10319 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
10320 + uint32_t msg_enable)
10321 +{
10322 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
10323 +}
10324 +
10325 +static int __cold dpa_nway_reset(struct net_device *net_dev)
10326 +{
10327 + int _errno;
10328 + struct dpa_priv_s *priv;
10329 +
10330 + priv = netdev_priv(net_dev);
10331 +
10332 + if (priv->mac_dev == NULL) {
10333 + netdev_info(net_dev, "This is a MAC-less interface\n");
10334 + return -ENODEV;
10335 + }
10336 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10337 + netdev_err(net_dev, "phy device not initialized\n");
10338 + return -ENODEV;
10339 + }
10340 +
10341 + _errno = 0;
10342 + if (priv->mac_dev->phy_dev->autoneg) {
10343 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
10344 + if (unlikely(_errno < 0))
10345 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10346 + _errno);
10347 + }
10348 +
10349 + return _errno;
10350 +}
10351 +
10352 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
10353 + struct ethtool_pauseparam *epause)
10354 +{
10355 + struct dpa_priv_s *priv;
10356 + struct mac_device *mac_dev;
10357 + struct phy_device *phy_dev;
10358 +
10359 + priv = netdev_priv(net_dev);
10360 + mac_dev = priv->mac_dev;
10361 +
10362 + if (mac_dev == NULL) {
10363 + netdev_info(net_dev, "This is a MAC-less interface\n");
10364 + return;
10365 + }
10366 +
10367 + phy_dev = mac_dev->phy_dev;
10368 + if (unlikely(phy_dev == NULL)) {
10369 + netdev_err(net_dev, "phy device not initialized\n");
10370 + return;
10371 + }
10372 +
10373 + epause->autoneg = mac_dev->autoneg_pause;
10374 + epause->rx_pause = mac_dev->rx_pause_active;
10375 + epause->tx_pause = mac_dev->tx_pause_active;
10376 +}
10377 +
10378 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
10379 + struct ethtool_pauseparam *epause)
10380 +{
10381 + struct dpa_priv_s *priv;
10382 + struct mac_device *mac_dev;
10383 + struct phy_device *phy_dev;
10384 + int _errno;
10385 + u32 newadv, oldadv;
10386 + bool rx_pause, tx_pause;
10387 +
10388 + priv = netdev_priv(net_dev);
10389 + mac_dev = priv->mac_dev;
10390 +
10391 + if (mac_dev == NULL) {
10392 + netdev_info(net_dev, "This is a MAC-less interface\n");
10393 + return -ENODEV;
10394 + }
10395 +
10396 + phy_dev = mac_dev->phy_dev;
10397 + if (unlikely(phy_dev == NULL)) {
10398 + netdev_err(net_dev, "phy device not initialized\n");
10399 + return -ENODEV;
10400 + }
10401 +
10402 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
10403 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
10404 + (epause->rx_pause != epause->tx_pause)))
10405 + return -EINVAL;
10406 +
10407 + /* The MAC should know how to handle PAUSE frame autonegotiation before
10408 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
10409 + * settings.
10410 + */
10411 + mac_dev->autoneg_pause = !!epause->autoneg;
10412 + mac_dev->rx_pause_req = !!epause->rx_pause;
10413 + mac_dev->tx_pause_req = !!epause->tx_pause;
10414 +
10415 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
10416 + * rx/tx pause settings.
10417 + */
10418 + newadv = 0;
10419 + if (epause->rx_pause)
10420 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
10421 + if (epause->tx_pause)
10422 + newadv |= ADVERTISED_Asym_Pause;
10423 +
10424 + oldadv = phy_dev->advertising &
10425 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
10426 +
10427 + /* If there are differences between the old and the new advertised
10428 + * values, restart PHY autonegotiation and advertise the new values.
10429 + */
10430 + if (oldadv != newadv) {
10431 + phy_dev->advertising &= ~(ADVERTISED_Pause
10432 + | ADVERTISED_Asym_Pause);
10433 + phy_dev->advertising |= newadv;
10434 + if (phy_dev->autoneg) {
10435 + _errno = phy_start_aneg(phy_dev);
10436 + if (unlikely(_errno < 0))
10437 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10438 + _errno);
10439 + }
10440 + }
10441 +
10442 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
10443 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
10444 + if (unlikely(_errno < 0))
10445 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
10446 +
10447 + return _errno;
10448 +}
10449 +
10450 +#ifdef CONFIG_PM
10451 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10452 +{
10453 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10454 +
10455 + wol->supported = 0;
10456 + wol->wolopts = 0;
10457 +
10458 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
10459 + return;
10460 +
10461 + if (priv->wol & DPAA_WOL_MAGIC) {
10462 + wol->supported = WAKE_MAGIC;
10463 + wol->wolopts = WAKE_MAGIC;
10464 + }
10465 +}
10466 +
10467 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10468 +{
10469 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10470 +
10471 + if (priv->mac_dev == NULL) {
10472 + netdev_info(net_dev, "This is a MAC-less interface\n");
10473 + return -ENODEV;
10474 + }
10475 +
10476 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10477 + netdev_dbg(net_dev, "phy device not initialized\n");
10478 + return -ENODEV;
10479 + }
10480 +
10481 + if (!device_can_wakeup(net_dev->dev.parent) ||
10482 + (wol->wolopts & ~WAKE_MAGIC))
10483 + return -EOPNOTSUPP;
10484 +
10485 + priv->wol = 0;
10486 +
10487 + if (wol->wolopts & WAKE_MAGIC) {
10488 + priv->wol = DPAA_WOL_MAGIC;
10489 + device_set_wakeup_enable(net_dev->dev.parent, 1);
10490 + } else {
10491 + device_set_wakeup_enable(net_dev->dev.parent, 0);
10492 + }
10493 +
10494 + return 0;
10495 +}
10496 +#endif
10497 +
10498 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10499 +{
10500 + struct dpa_priv_s *priv;
10501 +
10502 + priv = netdev_priv(net_dev);
10503 + if (priv->mac_dev == NULL) {
10504 + netdev_info(net_dev, "This is a MAC-less interface\n");
10505 + return -ENODEV;
10506 + }
10507 +
10508 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10509 + netdev_err(net_dev, "phy device not initialized\n");
10510 + return -ENODEV;
10511 + }
10512 +
10513 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
10514 +}
10515 +
10516 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10517 +{
10518 + struct dpa_priv_s *priv;
10519 +
10520 + priv = netdev_priv(net_dev);
10521 + if (priv->mac_dev == NULL) {
10522 + netdev_info(net_dev, "This is a MAC-less interface\n");
10523 + return -ENODEV;
10524 + }
10525 +
10526 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10527 + netdev_err(net_dev, "phy device not initialized\n");
10528 + return -ENODEV;
10529 + }
10530 +
10531 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
10532 +}
10533 +
10534 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
10535 +{
10536 + unsigned int total_stats, num_stats;
10537 +
10538 + num_stats = num_online_cpus() + 1;
10539 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
10540 +
10541 + switch (type) {
10542 + case ETH_SS_STATS:
10543 + return total_stats;
10544 + default:
10545 + return -EOPNOTSUPP;
10546 + }
10547 +}
10548 +
10549 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
10550 + int crr_cpu, u64 bp_count, u64 *data)
10551 +{
10552 + int num_stat_values = num_cpus + 1;
10553 + int crr_stat = 0;
10554 +
10555 + /* update current CPU's stats and also add them to the total values */
10556 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
10557 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
10558 +
10559 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
10560 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
10561 +
10562 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
10563 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
10564 +
10565 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
10566 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
10567 +
10568 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
10569 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
10570 +
10571 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
10572 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
10573 +
10574 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
10575 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
10576 +
10577 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
10578 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
10579 +
10580 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
10581 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
10582 +
10583 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
10584 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
10585 +}
10586 +
10587 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
10588 + struct ethtool_stats *stats, u64 *data)
10589 +{
10590 + u64 bp_count, cg_time, cg_num, cg_status;
10591 + struct dpa_percpu_priv_s *percpu_priv;
10592 + struct qm_mcr_querycgr query_cgr;
10593 + struct dpa_rx_errors rx_errors;
10594 + struct dpa_ern_cnt ern_cnt;
10595 + struct dpa_priv_s *priv;
10596 + unsigned int num_cpus, offset;
10597 + struct dpa_bp *dpa_bp;
10598 + int total_stats, i;
10599 +
10600 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
10601 + priv = netdev_priv(net_dev);
10602 + dpa_bp = priv->dpa_bp;
10603 + num_cpus = num_online_cpus();
10604 + bp_count = 0;
10605 +
10606 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
10607 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
10608 + memset(data, 0, total_stats * sizeof(u64));
10609 +
10610 + for_each_online_cpu(i) {
10611 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
10612 +
10613 + if (dpa_bp->percpu_count)
10614 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
10615 +
10616 + rx_errors.dme += percpu_priv->rx_errors.dme;
10617 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
10618 + rx_errors.fse += percpu_priv->rx_errors.fse;
10619 + rx_errors.phe += percpu_priv->rx_errors.phe;
10620 + rx_errors.cse += percpu_priv->rx_errors.cse;
10621 +
10622 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
10623 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
10624 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
10625 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
10626 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
10627 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
10628 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
10629 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
10630 +
10631 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
10632 + }
10633 +
10634 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
10635 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
10636 +
10637 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
10638 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
10639 +
10640 + /* gather congestion related counters */
10641 + cg_num = 0;
10642 + cg_status = 0;
10643 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
10644 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
10645 + cg_num = priv->cgr_data.cgr_congested_count;
10646 + cg_status = query_cgr.cgr.cs;
10647 +
10648 + /* reset congestion stats (like QMan API does */
10649 + priv->cgr_data.congested_jiffies = 0;
10650 + priv->cgr_data.cgr_congested_count = 0;
10651 + }
10652 +
10653 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
10654 + data[offset++] = cg_time;
10655 + data[offset++] = cg_num;
10656 + data[offset++] = cg_status;
10657 +}
10658 +
10659 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
10660 +{
10661 + unsigned int i, j, num_cpus, size;
10662 + char stat_string_cpu[ETH_GSTRING_LEN];
10663 + u8 *strings;
10664 +
10665 + strings = data;
10666 + num_cpus = num_online_cpus();
10667 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
10668 +
10669 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
10670 + for (j = 0; j < num_cpus; j++) {
10671 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
10672 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10673 + strings += ETH_GSTRING_LEN;
10674 + }
10675 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
10676 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10677 + strings += ETH_GSTRING_LEN;
10678 + }
10679 + memcpy(strings, dpa_stats_global, size);
10680 +}
10681 +
10682 +const struct ethtool_ops dpa_ethtool_ops = {
10683 + .get_settings = dpa_get_settings,
10684 + .set_settings = dpa_set_settings,
10685 + .get_drvinfo = dpa_get_drvinfo,
10686 + .get_msglevel = dpa_get_msglevel,
10687 + .set_msglevel = dpa_set_msglevel,
10688 + .nway_reset = dpa_nway_reset,
10689 + .get_pauseparam = dpa_get_pauseparam,
10690 + .set_pauseparam = dpa_set_pauseparam,
10691 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
10692 + .get_link = ethtool_op_get_link,
10693 + .get_eee = dpa_get_eee,
10694 + .set_eee = dpa_set_eee,
10695 + .get_sset_count = dpa_get_sset_count,
10696 + .get_ethtool_stats = dpa_get_ethtool_stats,
10697 + .get_strings = dpa_get_strings,
10698 +#ifdef CONFIG_PM
10699 + .get_wol = dpa_get_wol,
10700 + .set_wol = dpa_set_wol,
10701 +#endif
10702 +};
10703 --- /dev/null
10704 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10705 @@ -0,0 +1,291 @@
10706 +/*
10707 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
10708 + *
10709 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
10710 + *
10711 + * Copyright 2014 Freescale Semiconductor, Inc.
10712 + *
10713 + * This program is free software; you can redistribute it and/or modify it
10714 + * under the terms of the GNU General Public License as published by the
10715 + * Free Software Foundation; either version 2 of the License, or (at your
10716 + * option) any later version.
10717 +*/
10718 +
10719 +#include <linux/device.h>
10720 +#include <linux/hrtimer.h>
10721 +#include <linux/init.h>
10722 +#include <linux/interrupt.h>
10723 +#include <linux/kernel.h>
10724 +#include <linux/module.h>
10725 +#include <linux/of.h>
10726 +#include <linux/of_platform.h>
10727 +#include <linux/timex.h>
10728 +#include <linux/io.h>
10729 +
10730 +#include <linux/ptp_clock_kernel.h>
10731 +
10732 +#include "dpaa_eth.h"
10733 +#include "mac.h"
10734 +
10735 +static struct mac_device *mac_dev;
10736 +static u32 freqCompensation;
10737 +
10738 +/* Bit definitions for the TMR_CTRL register */
10739 +#define ALM1P (1<<31) /* Alarm1 output polarity */
10740 +#define ALM2P (1<<30) /* Alarm2 output polarity */
10741 +#define FS (1<<28) /* FIPER start indication */
10742 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
10743 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
10744 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
10745 +#define TCLK_PERIOD_MASK (0x3ff)
10746 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
10747 +#define FRD (1<<14) /* FIPER Realignment Disable */
10748 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
10749 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
10750 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
10751 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
10752 +#define COPH (1<<7) /* Generated clock output phase. */
10753 +#define CIPH (1<<6) /* External oscillator input clock phase */
10754 +#define TMSR (1<<5) /* Timer soft reset. */
10755 +#define BYP (1<<3) /* Bypass drift compensated clock */
10756 +#define TE (1<<2) /* 1588 timer enable. */
10757 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
10758 +#define CKSEL_MASK (0x3)
10759 +
10760 +/* Bit definitions for the TMR_TEVENT register */
10761 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
10762 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
10763 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
10764 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
10765 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
10766 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
10767 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
10768 +
10769 +/* Bit definitions for the TMR_TEMASK register */
10770 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
10771 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
10772 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
10773 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
10774 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
10775 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
10776 +
10777 +/* Bit definitions for the TMR_PEVENT register */
10778 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
10779 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
10780 +#define RXP (1<<0) /* PTP frame has been received */
10781 +
10782 +/* Bit definitions for the TMR_PEMASK register */
10783 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
10784 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
10785 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
10786 +
10787 +/* Bit definitions for the TMR_STAT register */
10788 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
10789 +#define STAT_VEC_MASK (0x3f)
10790 +
10791 +/* Bit definitions for the TMR_PRSC register */
10792 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
10793 +#define PRSC_OCK_MASK (0xffff)
10794 +
10795 +
10796 +#define N_EXT_TS 2
10797 +
10798 +static void set_alarm(void)
10799 +{
10800 + u64 ns;
10801 +
10802 + if (mac_dev->fm_rtc_get_cnt)
10803 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10804 + ns += 1500000000ULL;
10805 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
10806 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10807 + if (mac_dev->fm_rtc_set_alarm)
10808 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
10809 +}
10810 +
10811 +static void set_fipers(void)
10812 +{
10813 + u64 fiper;
10814 +
10815 + if (mac_dev->fm_rtc_disable)
10816 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
10817 +
10818 + set_alarm();
10819 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10820 + if (mac_dev->fm_rtc_set_fiper)
10821 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
10822 +
10823 + if (mac_dev->fm_rtc_enable)
10824 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
10825 +}
10826 +
10827 +/* PTP clock operations */
10828 +
10829 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
10830 +{
10831 + u64 adj;
10832 + u32 diff, tmr_add;
10833 + int neg_adj = 0;
10834 +
10835 + if (ppb < 0) {
10836 + neg_adj = 1;
10837 + ppb = -ppb;
10838 + }
10839 +
10840 + tmr_add = freqCompensation;
10841 + adj = tmr_add;
10842 + adj *= ppb;
10843 + diff = div_u64(adj, 1000000000ULL);
10844 +
10845 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
10846 +
10847 + if (mac_dev->fm_rtc_set_drift)
10848 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
10849 +
10850 + return 0;
10851 +}
10852 +
10853 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
10854 +{
10855 + s64 now;
10856 +
10857 + if (mac_dev->fm_rtc_get_cnt)
10858 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
10859 +
10860 + now += delta;
10861 +
10862 + if (mac_dev->fm_rtc_set_cnt)
10863 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
10864 + set_fipers();
10865 +
10866 + return 0;
10867 +}
10868 +
10869 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
10870 +{
10871 + u64 ns;
10872 + u32 remainder;
10873 +
10874 + if (mac_dev->fm_rtc_get_cnt)
10875 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10876 +
10877 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
10878 + ts->tv_nsec = remainder;
10879 + return 0;
10880 +}
10881 +
10882 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
10883 + const struct timespec64 *ts)
10884 +{
10885 + u64 ns;
10886 +
10887 + ns = ts->tv_sec * 1000000000ULL;
10888 + ns += ts->tv_nsec;
10889 +
10890 + if (mac_dev->fm_rtc_set_cnt)
10891 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
10892 + set_fipers();
10893 + return 0;
10894 +}
10895 +
10896 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
10897 + struct ptp_clock_request *rq, int on)
10898 +{
10899 + u32 bit;
10900 +
10901 + switch (rq->type) {
10902 + case PTP_CLK_REQ_EXTTS:
10903 + switch (rq->extts.index) {
10904 + case 0:
10905 + bit = ETS1EN;
10906 + break;
10907 + case 1:
10908 + bit = ETS2EN;
10909 + break;
10910 + default:
10911 + return -EINVAL;
10912 + }
10913 + if (on) {
10914 + if (mac_dev->fm_rtc_enable_interrupt)
10915 + mac_dev->fm_rtc_enable_interrupt(
10916 + mac_dev->fm_dev, bit);
10917 + } else {
10918 + if (mac_dev->fm_rtc_disable_interrupt)
10919 + mac_dev->fm_rtc_disable_interrupt(
10920 + mac_dev->fm_dev, bit);
10921 + }
10922 + return 0;
10923 +
10924 + case PTP_CLK_REQ_PPS:
10925 + if (on) {
10926 + if (mac_dev->fm_rtc_enable_interrupt)
10927 + mac_dev->fm_rtc_enable_interrupt(
10928 + mac_dev->fm_dev, PP1EN);
10929 + } else {
10930 + if (mac_dev->fm_rtc_disable_interrupt)
10931 + mac_dev->fm_rtc_disable_interrupt(
10932 + mac_dev->fm_dev, PP1EN);
10933 + }
10934 + return 0;
10935 +
10936 + default:
10937 + break;
10938 + }
10939 +
10940 + return -EOPNOTSUPP;
10941 +}
10942 +
10943 +static struct ptp_clock_info ptp_dpa_caps = {
10944 + .owner = THIS_MODULE,
10945 + .name = "dpaa clock",
10946 + .max_adj = 512000,
10947 + .n_alarm = 0,
10948 + .n_ext_ts = N_EXT_TS,
10949 + .n_per_out = 0,
10950 + .pps = 1,
10951 + .adjfreq = ptp_dpa_adjfreq,
10952 + .adjtime = ptp_dpa_adjtime,
10953 + .gettime64 = ptp_dpa_gettime,
10954 + .settime64 = ptp_dpa_settime,
10955 + .enable = ptp_dpa_enable,
10956 +};
10957 +
10958 +static int __init __cold dpa_ptp_load(void)
10959 +{
10960 + struct device *ptp_dev;
10961 + struct timespec64 now;
10962 + struct ptp_clock *clock = ptp_priv.clock;
10963 + int dpa_phc_index;
10964 + int err;
10965 +
10966 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
10967 + return -ENODEV;
10968 +
10969 + ptp_dev = &ptp_priv.of_dev->dev;
10970 + mac_dev = ptp_priv.mac_dev;
10971 +
10972 + if (mac_dev->fm_rtc_get_drift)
10973 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
10974 +
10975 + getnstimeofday64(&now);
10976 + ptp_dpa_settime(&ptp_dpa_caps, &now);
10977 +
10978 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
10979 + if (IS_ERR(clock)) {
10980 + err = PTR_ERR(clock);
10981 + return err;
10982 + }
10983 + dpa_phc_index = ptp_clock_index(clock);
10984 + return 0;
10985 +}
10986 +module_init(dpa_ptp_load);
10987 +
10988 +static void __exit __cold dpa_ptp_unload(void)
10989 +{
10990 + struct ptp_clock *clock = ptp_priv.clock;
10991 +
10992 + if (mac_dev->fm_rtc_disable_interrupt)
10993 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
10994 + ptp_clock_unregister(clock);
10995 +}
10996 +module_exit(dpa_ptp_unload);
10997 --- /dev/null
10998 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
10999 @@ -0,0 +1,907 @@
11000 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11001 + *
11002 + * Redistribution and use in source and binary forms, with or without
11003 + * modification, are permitted provided that the following conditions are met:
11004 + * * Redistributions of source code must retain the above copyright
11005 + * notice, this list of conditions and the following disclaimer.
11006 + * * Redistributions in binary form must reproduce the above copyright
11007 + * notice, this list of conditions and the following disclaimer in the
11008 + * documentation and/or other materials provided with the distribution.
11009 + * * Neither the name of Freescale Semiconductor nor the
11010 + * names of its contributors may be used to endorse or promote products
11011 + * derived from this software without specific prior written permission.
11012 + *
11013 + *
11014 + * ALTERNATIVELY, this software may be distributed under the terms of the
11015 + * GNU General Public License ("GPL") as published by the Free Software
11016 + * Foundation, either version 2 of that License or (at your option) any
11017 + * later version.
11018 + *
11019 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11020 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11021 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11022 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11023 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11024 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11025 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11026 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11027 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11028 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11029 + */
11030 +
11031 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11032 +#define pr_fmt(fmt) \
11033 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11034 + KBUILD_BASENAME".c", __LINE__, __func__
11035 +#else
11036 +#define pr_fmt(fmt) \
11037 + KBUILD_MODNAME ": " fmt
11038 +#endif
11039 +
11040 +#include <linux/init.h>
11041 +#include <linux/module.h>
11042 +#include <linux/io.h>
11043 +#include <linux/of_platform.h>
11044 +#include <linux/of_mdio.h>
11045 +#include <linux/phy.h>
11046 +#include <linux/netdevice.h>
11047 +
11048 +#include "dpaa_eth.h"
11049 +#include "mac.h"
11050 +#include "lnxwrp_fsl_fman.h"
11051 +
11052 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
11053 +
11054 +#include "fsl_fman_dtsec.h"
11055 +#include "fsl_fman_tgec.h"
11056 +#include "fsl_fman_memac.h"
11057 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
11058 +
11059 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
11060 +
11061 +MODULE_LICENSE("Dual BSD/GPL");
11062 +
11063 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
11064 +
11065 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
11066 +
11067 +struct mac_priv_s {
11068 + struct fm_mac_dev *fm_mac;
11069 +};
11070 +
11071 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
11072 +const size_t mac_sizeof_priv[] = {
11073 + [DTSEC] = sizeof(struct mac_priv_s),
11074 + [XGMAC] = sizeof(struct mac_priv_s),
11075 + [MEMAC] = sizeof(struct mac_priv_s)
11076 +};
11077 +
11078 +static const enet_mode_t _100[] = {
11079 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
11080 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
11081 +};
11082 +
11083 +static const enet_mode_t _1000[] = {
11084 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
11085 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
11086 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
11087 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
11088 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
11089 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
11090 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
11091 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
11092 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
11093 +};
11094 +
11095 +static enet_mode_t __cold __attribute__((nonnull))
11096 +macdev2enetinterface(const struct mac_device *mac_dev)
11097 +{
11098 + switch (mac_dev->max_speed) {
11099 + case SPEED_100:
11100 + return _100[mac_dev->phy_if];
11101 + case SPEED_1000:
11102 + return _1000[mac_dev->phy_if];
11103 + case SPEED_2500:
11104 + return e_ENET_MODE_SGMII_2500;
11105 + case SPEED_10000:
11106 + return e_ENET_MODE_XGMII_10000;
11107 + default:
11108 + return e_ENET_MODE_MII_100;
11109 + }
11110 +}
11111 +
11112 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
11113 +{
11114 + struct mac_device *mac_dev;
11115 +
11116 + mac_dev = (struct mac_device *)_mac_dev;
11117 +
11118 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
11119 + /* don't flag RX FIFO after the first */
11120 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11121 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
11122 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
11123 + exception);
11124 + }
11125 +
11126 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
11127 + exception);
11128 +}
11129 +
11130 +static int __cold init(struct mac_device *mac_dev)
11131 +{
11132 + int _errno;
11133 + struct mac_priv_s *priv;
11134 + t_FmMacParams param;
11135 + uint32_t version;
11136 +
11137 + priv = macdev_priv(mac_dev);
11138 +
11139 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11140 + mac_dev->dev, mac_dev->res->start, 0x2000);
11141 + param.enetMode = macdev2enetinterface(mac_dev);
11142 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
11143 + sizeof(mac_dev->addr)));
11144 + param.macId = mac_dev->cell_index;
11145 + param.h_Fm = (handle_t)mac_dev->fm;
11146 + param.mdioIrq = NO_IRQ;
11147 + param.f_Exception = mac_exception;
11148 + param.f_Event = mac_exception;
11149 + param.h_App = mac_dev;
11150 +
11151 + priv->fm_mac = fm_mac_config(&param);
11152 + if (unlikely(priv->fm_mac == NULL)) {
11153 + _errno = -EINVAL;
11154 + goto _return;
11155 + }
11156 +
11157 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11158 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11159 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11160 +
11161 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
11162 + fm_get_max_frm());
11163 + if (unlikely(_errno < 0))
11164 + goto _return_fm_mac_free;
11165 +
11166 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11167 + /* 10G always works with pad and CRC */
11168 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
11169 + if (unlikely(_errno < 0))
11170 + goto _return_fm_mac_free;
11171 +
11172 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
11173 + mac_dev->half_duplex);
11174 + if (unlikely(_errno < 0))
11175 + goto _return_fm_mac_free;
11176 + } else {
11177 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11178 + if (unlikely(_errno < 0))
11179 + goto _return_fm_mac_free;
11180 + }
11181 +
11182 + _errno = fm_mac_init(priv->fm_mac);
11183 + if (unlikely(_errno < 0))
11184 + goto _return_fm_mac_free;
11185 +
11186 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
11187 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
11188 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11189 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11190 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
11191 + if (unlikely(_errno < 0))
11192 + goto _return_fm_mac_free;
11193 + }
11194 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
11195 +
11196 + /* For 10G MAC, disable Tx ECC exception */
11197 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
11198 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11199 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
11200 + if (unlikely(_errno < 0))
11201 + goto _return_fm_mac_free;
11202 + }
11203 +
11204 + _errno = fm_mac_get_version(priv->fm_mac, &version);
11205 + if (unlikely(_errno < 0))
11206 + goto _return_fm_mac_free;
11207 +
11208 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
11209 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11210 + "dTSEC" : "XGEC"), version);
11211 +
11212 + goto _return;
11213 +
11214 +
11215 +_return_fm_mac_free:
11216 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
11217 +
11218 +_return:
11219 + return _errno;
11220 +}
11221 +
11222 +static int __cold memac_init(struct mac_device *mac_dev)
11223 +{
11224 + int _errno;
11225 + struct mac_priv_s *priv;
11226 + t_FmMacParams param;
11227 +
11228 + priv = macdev_priv(mac_dev);
11229 +
11230 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11231 + mac_dev->dev, mac_dev->res->start, 0x2000);
11232 + param.enetMode = macdev2enetinterface(mac_dev);
11233 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
11234 + param.macId = mac_dev->cell_index;
11235 + param.h_Fm = (handle_t)mac_dev->fm;
11236 + param.mdioIrq = NO_IRQ;
11237 + param.f_Exception = mac_exception;
11238 + param.f_Event = mac_exception;
11239 + param.h_App = mac_dev;
11240 +
11241 + priv->fm_mac = fm_mac_config(&param);
11242 + if (unlikely(priv->fm_mac == NULL)) {
11243 + _errno = -EINVAL;
11244 + goto _return;
11245 + }
11246 +
11247 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11248 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11249 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11250 +
11251 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
11252 + if (unlikely(_errno < 0))
11253 + goto _return_fm_mac_free;
11254 +
11255 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11256 + if (unlikely(_errno < 0))
11257 + goto _return_fm_mac_free;
11258 +
11259 + _errno = fm_mac_init(priv->fm_mac);
11260 + if (unlikely(_errno < 0))
11261 + goto _return_fm_mac_free;
11262 +
11263 + dev_info(mac_dev->dev, "FMan MEMAC\n");
11264 +
11265 + goto _return;
11266 +
11267 +_return_fm_mac_free:
11268 + fm_mac_free(priv->fm_mac);
11269 +
11270 +_return:
11271 + return _errno;
11272 +}
11273 +
11274 +static int __cold start(struct mac_device *mac_dev)
11275 +{
11276 + int _errno;
11277 + struct phy_device *phy_dev = mac_dev->phy_dev;
11278 +
11279 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
11280 +
11281 + if (!_errno && phy_dev)
11282 + phy_start(phy_dev);
11283 +
11284 + return _errno;
11285 +}
11286 +
11287 +static int __cold stop(struct mac_device *mac_dev)
11288 +{
11289 + if (mac_dev->phy_dev)
11290 + phy_stop(mac_dev->phy_dev);
11291 +
11292 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
11293 +}
11294 +
11295 +static int __cold set_multi(struct net_device *net_dev,
11296 + struct mac_device *mac_dev)
11297 +{
11298 + struct mac_priv_s *mac_priv;
11299 + struct mac_address *old_addr, *tmp;
11300 + struct netdev_hw_addr *ha;
11301 + int _errno;
11302 +
11303 + mac_priv = macdev_priv(mac_dev);
11304 +
11305 + /* Clear previous address list */
11306 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
11307 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
11308 + (t_EnetAddr *)old_addr->addr);
11309 + if (_errno < 0)
11310 + return _errno;
11311 +
11312 + list_del(&old_addr->list);
11313 + kfree(old_addr);
11314 + }
11315 +
11316 + /* Add all the addresses from the new list */
11317 + netdev_for_each_mc_addr(ha, net_dev) {
11318 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
11319 + (t_EnetAddr *)ha->addr);
11320 + if (_errno < 0)
11321 + return _errno;
11322 +
11323 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
11324 + if (!tmp) {
11325 + dev_err(mac_dev->dev, "Out of memory\n");
11326 + return -ENOMEM;
11327 + }
11328 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
11329 + list_add(&tmp->list, &mac_dev->mc_addr_list);
11330 + }
11331 + return 0;
11332 +}
11333 +
11334 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
11335 + * active PAUSE settings. Otherwise, the new active settings should be reflected
11336 + * in FMan.
11337 + */
11338 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
11339 +{
11340 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11341 + int _errno = 0;
11342 +
11343 + if (unlikely(rx != mac_dev->rx_pause_active)) {
11344 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
11345 + if (likely(_errno == 0))
11346 + mac_dev->rx_pause_active = rx;
11347 + }
11348 +
11349 + if (unlikely(tx != mac_dev->tx_pause_active)) {
11350 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
11351 + if (likely(_errno == 0))
11352 + mac_dev->tx_pause_active = tx;
11353 + }
11354 +
11355 + return _errno;
11356 +}
11357 +EXPORT_SYMBOL(set_mac_active_pause);
11358 +
11359 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
11360 + * autonegotiation or values set by eththool.
11361 + */
11362 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
11363 +{
11364 + struct phy_device *phy_dev = mac_dev->phy_dev;
11365 + u16 lcl_adv, rmt_adv;
11366 + u8 flowctrl;
11367 +
11368 + *rx_pause = *tx_pause = false;
11369 +
11370 + if (!phy_dev->duplex)
11371 + return;
11372 +
11373 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
11374 + * are those set by ethtool.
11375 + */
11376 + if (!mac_dev->autoneg_pause) {
11377 + *rx_pause = mac_dev->rx_pause_req;
11378 + *tx_pause = mac_dev->tx_pause_req;
11379 + return;
11380 + }
11381 +
11382 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
11383 + * settings depend on the result of the link negotiation.
11384 + */
11385 +
11386 + /* get local capabilities */
11387 + lcl_adv = 0;
11388 + if (phy_dev->advertising & ADVERTISED_Pause)
11389 + lcl_adv |= ADVERTISE_PAUSE_CAP;
11390 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
11391 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
11392 +
11393 + /* get link partner capabilities */
11394 + rmt_adv = 0;
11395 + if (phy_dev->pause)
11396 + rmt_adv |= LPA_PAUSE_CAP;
11397 + if (phy_dev->asym_pause)
11398 + rmt_adv |= LPA_PAUSE_ASYM;
11399 +
11400 + /* Calculate TX/RX settings based on local and peer advertised
11401 + * symmetric/asymmetric PAUSE capabilities.
11402 + */
11403 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
11404 + if (flowctrl & FLOW_CTRL_RX)
11405 + *rx_pause = true;
11406 + if (flowctrl & FLOW_CTRL_TX)
11407 + *tx_pause = true;
11408 +}
11409 +EXPORT_SYMBOL(get_pause_cfg);
11410 +
11411 +static void adjust_link_void(struct net_device *net_dev)
11412 +{
11413 +}
11414 +
11415 +static void adjust_link(struct net_device *net_dev)
11416 +{
11417 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11418 + struct mac_device *mac_dev = priv->mac_dev;
11419 + struct phy_device *phy_dev = mac_dev->phy_dev;
11420 + struct fm_mac_dev *fm_mac_dev;
11421 + bool rx_pause, tx_pause;
11422 + int _errno;
11423 +
11424 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11425 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
11426 + phy_dev->duplex);
11427 +
11428 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11429 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11430 + if (unlikely(_errno < 0))
11431 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11432 +}
11433 +
11434 +/* Initializes driver's PHY state, and attaches to the PHY.
11435 + * Returns 0 on success.
11436 + */
11437 +static int dtsec_init_phy(struct net_device *net_dev,
11438 + struct mac_device *mac_dev)
11439 +{
11440 + struct phy_device *phy_dev;
11441 +
11442 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11443 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11444 + 0, mac_dev->phy_if);
11445 + else
11446 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11447 + &adjust_link, 0, mac_dev->phy_if);
11448 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11449 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11450 + mac_dev->phy_node ?
11451 + mac_dev->phy_node->full_name :
11452 + mac_dev->fixed_bus_id);
11453 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11454 + }
11455 +
11456 + /* Remove any features not supported by the controller */
11457 + phy_dev->supported &= mac_dev->if_support;
11458 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11459 + * as most of the PHY drivers do not enable them by default.
11460 + */
11461 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11462 + phy_dev->advertising = phy_dev->supported;
11463 +
11464 + mac_dev->phy_dev = phy_dev;
11465 +
11466 + return 0;
11467 +}
11468 +
11469 +static int xgmac_init_phy(struct net_device *net_dev,
11470 + struct mac_device *mac_dev)
11471 +{
11472 + struct phy_device *phy_dev;
11473 +
11474 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11475 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11476 + 0, mac_dev->phy_if);
11477 + else
11478 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11479 + &adjust_link_void, 0, mac_dev->phy_if);
11480 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11481 + netdev_err(net_dev, "Could not attach to PHY %s\n",
11482 + mac_dev->phy_node ?
11483 + mac_dev->phy_node->full_name :
11484 + mac_dev->fixed_bus_id);
11485 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11486 + }
11487 +
11488 + phy_dev->supported &= mac_dev->if_support;
11489 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11490 + * as most of the PHY drivers do not enable them by default.
11491 + */
11492 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11493 + phy_dev->advertising = phy_dev->supported;
11494 +
11495 + mac_dev->phy_dev = phy_dev;
11496 +
11497 + return 0;
11498 +}
11499 +
11500 +static int memac_init_phy(struct net_device *net_dev,
11501 + struct mac_device *mac_dev)
11502 +{
11503 + struct phy_device *phy_dev;
11504 +
11505 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
11506 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) ||
11507 + of_phy_is_fixed_link(mac_dev->phy_node)) {
11508 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11509 + &adjust_link_void, 0,
11510 + mac_dev->phy_if);
11511 + } else {
11512 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11513 + &adjust_link, 0, mac_dev->phy_if);
11514 + }
11515 +
11516 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11517 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11518 + mac_dev->phy_node ?
11519 + mac_dev->phy_node->full_name :
11520 + mac_dev->fixed_bus_id);
11521 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11522 + }
11523 +
11524 + /* Remove any features not supported by the controller */
11525 + phy_dev->supported &= mac_dev->if_support;
11526 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11527 + * as most of the PHY drivers do not enable them by default.
11528 + */
11529 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11530 + phy_dev->advertising = phy_dev->supported;
11531 +
11532 + mac_dev->phy_dev = phy_dev;
11533 +
11534 + return 0;
11535 +}
11536 +
11537 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
11538 +{
11539 + int _errno, __errno;
11540 +
11541 + _errno = fm_mac_disable(fm_mac_dev);
11542 + __errno = fm_mac_free(fm_mac_dev);
11543 +
11544 + if (unlikely(__errno < 0))
11545 + _errno = __errno;
11546 +
11547 + return _errno;
11548 +}
11549 +
11550 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
11551 +{
11552 + const struct mac_priv_s *priv;
11553 + priv = macdev_priv(mac_dev);
11554 + return priv->fm_mac;
11555 +}
11556 +
11557 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11558 +{
11559 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
11560 + int i = 0, n = nn;
11561 +
11562 + FM_DMP_SUBTITLE(buf, n, "\n");
11563 +
11564 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
11565 +
11566 + FM_DMP_V32(buf, n, p_mm, tsec_id);
11567 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
11568 + FM_DMP_V32(buf, n, p_mm, ievent);
11569 + FM_DMP_V32(buf, n, p_mm, imask);
11570 + FM_DMP_V32(buf, n, p_mm, ecntrl);
11571 + FM_DMP_V32(buf, n, p_mm, ptv);
11572 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
11573 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
11574 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
11575 + FM_DMP_V32(buf, n, p_mm, tctrl);
11576 + FM_DMP_V32(buf, n, p_mm, rctrl);
11577 + FM_DMP_V32(buf, n, p_mm, maccfg1);
11578 + FM_DMP_V32(buf, n, p_mm, maccfg2);
11579 + FM_DMP_V32(buf, n, p_mm, ipgifg);
11580 + FM_DMP_V32(buf, n, p_mm, hafdup);
11581 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11582 +
11583 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
11584 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
11585 +
11586 + for (i = 0; i < 7; ++i) {
11587 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
11588 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
11589 + }
11590 +
11591 + FM_DMP_V32(buf, n, p_mm, car1);
11592 + FM_DMP_V32(buf, n, p_mm, car2);
11593 +
11594 + return n;
11595 +}
11596 +
11597 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11598 +{
11599 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
11600 + int n = nn;
11601 +
11602 + FM_DMP_SUBTITLE(buf, n, "\n");
11603 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
11604 +
11605 + FM_DMP_V32(buf, n, p_mm, tgec_id);
11606 + FM_DMP_V32(buf, n, p_mm, command_config);
11607 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
11608 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
11609 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11610 + FM_DMP_V32(buf, n, p_mm, pause_quant);
11611 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
11612 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
11613 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
11614 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
11615 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11616 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
11617 + FM_DMP_V32(buf, n, p_mm, mdio_command);
11618 + FM_DMP_V32(buf, n, p_mm, mdio_data);
11619 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
11620 + FM_DMP_V32(buf, n, p_mm, status);
11621 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
11622 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
11623 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
11624 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
11625 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
11626 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
11627 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
11628 + FM_DMP_V32(buf, n, p_mm, imask);
11629 + FM_DMP_V32(buf, n, p_mm, ievent);
11630 +
11631 + return n;
11632 +}
11633 +
11634 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11635 +{
11636 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11637 + int i = 0, n = nn;
11638 +
11639 + FM_DMP_SUBTITLE(buf, n, "\n");
11640 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
11641 +
11642 + FM_DMP_V32(buf, n, p_mm, command_config);
11643 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
11644 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
11645 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11646 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11647 + FM_DMP_V32(buf, n, p_mm, ievent);
11648 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
11649 + FM_DMP_V32(buf, n, p_mm, imask);
11650 +
11651 + for (i = 0; i < 4; ++i)
11652 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
11653 +
11654 + for (i = 0; i < 4; ++i)
11655 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
11656 +
11657 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
11658 +
11659 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
11660 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
11661 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
11662 + }
11663 +
11664 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
11665 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
11666 + FM_DMP_V32(buf, n, p_mm, statn_config);
11667 + FM_DMP_V32(buf, n, p_mm, if_mode);
11668 + FM_DMP_V32(buf, n, p_mm, if_status);
11669 + FM_DMP_V32(buf, n, p_mm, hg_config);
11670 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
11671 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
11672 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
11673 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
11674 + FM_DMP_V32(buf, n, p_mm, rhm);
11675 + FM_DMP_V32(buf, n, p_mm, thm);
11676 +
11677 + return n;
11678 +}
11679 +
11680 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
11681 +{
11682 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11683 + int n = nn;
11684 +
11685 + FM_DMP_SUBTITLE(buf, n, "\n");
11686 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
11687 +
11688 + /* Rx Statistics Counter */
11689 + FM_DMP_V32(buf, n, p_mm, reoct_l);
11690 + FM_DMP_V32(buf, n, p_mm, reoct_u);
11691 + FM_DMP_V32(buf, n, p_mm, roct_l);
11692 + FM_DMP_V32(buf, n, p_mm, roct_u);
11693 + FM_DMP_V32(buf, n, p_mm, raln_l);
11694 + FM_DMP_V32(buf, n, p_mm, raln_u);
11695 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
11696 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
11697 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
11698 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
11699 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
11700 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
11701 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
11702 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
11703 + FM_DMP_V32(buf, n, p_mm, rerr_l);
11704 + FM_DMP_V32(buf, n, p_mm, rerr_u);
11705 + FM_DMP_V32(buf, n, p_mm, ruca_l);
11706 + FM_DMP_V32(buf, n, p_mm, ruca_u);
11707 + FM_DMP_V32(buf, n, p_mm, rmca_l);
11708 + FM_DMP_V32(buf, n, p_mm, rmca_u);
11709 + FM_DMP_V32(buf, n, p_mm, rbca_l);
11710 + FM_DMP_V32(buf, n, p_mm, rbca_u);
11711 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
11712 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
11713 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
11714 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
11715 + FM_DMP_V32(buf, n, p_mm, rund_l);
11716 + FM_DMP_V32(buf, n, p_mm, rund_u);
11717 + FM_DMP_V32(buf, n, p_mm, r64_l);
11718 + FM_DMP_V32(buf, n, p_mm, r64_u);
11719 + FM_DMP_V32(buf, n, p_mm, r127_l);
11720 + FM_DMP_V32(buf, n, p_mm, r127_u);
11721 + FM_DMP_V32(buf, n, p_mm, r255_l);
11722 + FM_DMP_V32(buf, n, p_mm, r255_u);
11723 + FM_DMP_V32(buf, n, p_mm, r511_l);
11724 + FM_DMP_V32(buf, n, p_mm, r511_u);
11725 + FM_DMP_V32(buf, n, p_mm, r1023_l);
11726 + FM_DMP_V32(buf, n, p_mm, r1023_u);
11727 + FM_DMP_V32(buf, n, p_mm, r1518_l);
11728 + FM_DMP_V32(buf, n, p_mm, r1518_u);
11729 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
11730 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
11731 + FM_DMP_V32(buf, n, p_mm, rovr_l);
11732 + FM_DMP_V32(buf, n, p_mm, rovr_u);
11733 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
11734 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
11735 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
11736 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
11737 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
11738 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
11739 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
11740 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
11741 +
11742 + return n;
11743 +}
11744 +
11745 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
11746 +{
11747 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11748 + int n = nn;
11749 +
11750 + FM_DMP_SUBTITLE(buf, n, "\n");
11751 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
11752 +
11753 +
11754 + /* Tx Statistics Counter */
11755 + FM_DMP_V32(buf, n, p_mm, teoct_l);
11756 + FM_DMP_V32(buf, n, p_mm, teoct_u);
11757 + FM_DMP_V32(buf, n, p_mm, toct_l);
11758 + FM_DMP_V32(buf, n, p_mm, toct_u);
11759 + FM_DMP_V32(buf, n, p_mm, txpf_l);
11760 + FM_DMP_V32(buf, n, p_mm, txpf_u);
11761 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
11762 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
11763 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
11764 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
11765 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
11766 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
11767 + FM_DMP_V32(buf, n, p_mm, terr_l);
11768 + FM_DMP_V32(buf, n, p_mm, terr_u);
11769 + FM_DMP_V32(buf, n, p_mm, tuca_l);
11770 + FM_DMP_V32(buf, n, p_mm, tuca_u);
11771 + FM_DMP_V32(buf, n, p_mm, tmca_l);
11772 + FM_DMP_V32(buf, n, p_mm, tmca_u);
11773 + FM_DMP_V32(buf, n, p_mm, tbca_l);
11774 + FM_DMP_V32(buf, n, p_mm, tbca_u);
11775 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
11776 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
11777 + FM_DMP_V32(buf, n, p_mm, tund_l);
11778 + FM_DMP_V32(buf, n, p_mm, tund_u);
11779 + FM_DMP_V32(buf, n, p_mm, t64_l);
11780 + FM_DMP_V32(buf, n, p_mm, t64_u);
11781 + FM_DMP_V32(buf, n, p_mm, t127_l);
11782 + FM_DMP_V32(buf, n, p_mm, t127_u);
11783 + FM_DMP_V32(buf, n, p_mm, t255_l);
11784 + FM_DMP_V32(buf, n, p_mm, t255_u);
11785 + FM_DMP_V32(buf, n, p_mm, t511_l);
11786 + FM_DMP_V32(buf, n, p_mm, t511_u);
11787 + FM_DMP_V32(buf, n, p_mm, t1023_l);
11788 + FM_DMP_V32(buf, n, p_mm, t1023_u);
11789 + FM_DMP_V32(buf, n, p_mm, t1518_l);
11790 + FM_DMP_V32(buf, n, p_mm, t1518_u);
11791 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
11792 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
11793 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
11794 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
11795 +
11796 + return n;
11797 +}
11798 +
11799 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11800 +{
11801 + int n = nn;
11802 +
11803 + n = h_mac->dump_mac_regs(h_mac, buf, n);
11804 +
11805 + return n;
11806 +}
11807 +EXPORT_SYMBOL(fm_mac_dump_regs);
11808 +
11809 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
11810 +{
11811 + int n = nn;
11812 +
11813 + if(h_mac->dump_mac_rx_stats)
11814 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
11815 +
11816 + return n;
11817 +}
11818 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
11819 +
11820 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
11821 +{
11822 + int n = nn;
11823 +
11824 + if(h_mac->dump_mac_tx_stats)
11825 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
11826 +
11827 + return n;
11828 +}
11829 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
11830 +
11831 +static void __cold setup_dtsec(struct mac_device *mac_dev)
11832 +{
11833 + mac_dev->init_phy = dtsec_init_phy;
11834 + mac_dev->init = init;
11835 + mac_dev->start = start;
11836 + mac_dev->stop = stop;
11837 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11838 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11839 + mac_dev->set_multi = set_multi;
11840 + mac_dev->uninit = uninit;
11841 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
11842 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
11843 + mac_dev->get_mac_handle = get_mac_handle;
11844 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11845 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11846 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11847 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11848 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11849 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11850 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11851 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11852 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11853 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11854 + mac_dev->set_wol = fm_mac_set_wol;
11855 + mac_dev->dump_mac_regs = dtsec_dump_regs;
11856 +}
11857 +
11858 +static void __cold setup_xgmac(struct mac_device *mac_dev)
11859 +{
11860 + mac_dev->init_phy = xgmac_init_phy;
11861 + mac_dev->init = init;
11862 + mac_dev->start = start;
11863 + mac_dev->stop = stop;
11864 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11865 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11866 + mac_dev->set_multi = set_multi;
11867 + mac_dev->uninit = uninit;
11868 + mac_dev->get_mac_handle = get_mac_handle;
11869 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11870 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11871 + mac_dev->set_wol = fm_mac_set_wol;
11872 + mac_dev->dump_mac_regs = xgmac_dump_regs;
11873 +}
11874 +
11875 +static void __cold setup_memac(struct mac_device *mac_dev)
11876 +{
11877 + mac_dev->init_phy = memac_init_phy;
11878 + mac_dev->init = memac_init;
11879 + mac_dev->start = start;
11880 + mac_dev->stop = stop;
11881 + mac_dev->set_promisc = fm_mac_set_promiscuous;
11882 + mac_dev->change_addr = fm_mac_modify_mac_addr;
11883 + mac_dev->set_multi = set_multi;
11884 + mac_dev->uninit = uninit;
11885 + mac_dev->get_mac_handle = get_mac_handle;
11886 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
11887 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
11888 + mac_dev->fm_rtc_enable = fm_rtc_enable;
11889 + mac_dev->fm_rtc_disable = fm_rtc_disable;
11890 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
11891 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
11892 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
11893 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
11894 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
11895 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
11896 + mac_dev->set_wol = fm_mac_set_wol;
11897 + mac_dev->dump_mac_regs = memac_dump_regs;
11898 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
11899 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
11900 +}
11901 +
11902 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
11903 + [DTSEC] = setup_dtsec,
11904 + [XGMAC] = setup_xgmac,
11905 + [MEMAC] = setup_memac
11906 +};
11907 --- /dev/null
11908 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
11909 @@ -0,0 +1,489 @@
11910 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11911 + *
11912 + * Redistribution and use in source and binary forms, with or without
11913 + * modification, are permitted provided that the following conditions are met:
11914 + * * Redistributions of source code must retain the above copyright
11915 + * notice, this list of conditions and the following disclaimer.
11916 + * * Redistributions in binary form must reproduce the above copyright
11917 + * notice, this list of conditions and the following disclaimer in the
11918 + * documentation and/or other materials provided with the distribution.
11919 + * * Neither the name of Freescale Semiconductor nor the
11920 + * names of its contributors may be used to endorse or promote products
11921 + * derived from this software without specific prior written permission.
11922 + *
11923 + *
11924 + * ALTERNATIVELY, this software may be distributed under the terms of the
11925 + * GNU General Public License ("GPL") as published by the Free Software
11926 + * Foundation, either version 2 of that License or (at your option) any
11927 + * later version.
11928 + *
11929 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11930 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11931 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11932 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11933 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11934 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11935 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11936 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11937 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11938 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11939 + */
11940 +
11941 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11942 +#define pr_fmt(fmt) \
11943 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11944 + KBUILD_BASENAME".c", __LINE__, __func__
11945 +#else
11946 +#define pr_fmt(fmt) \
11947 + KBUILD_MODNAME ": " fmt
11948 +#endif
11949 +
11950 +#include <linux/init.h>
11951 +#include <linux/module.h>
11952 +#include <linux/of_address.h>
11953 +#include <linux/of_platform.h>
11954 +#include <linux/of_net.h>
11955 +#include <linux/of_mdio.h>
11956 +#include <linux/phy_fixed.h>
11957 +#include <linux/device.h>
11958 +#include <linux/phy.h>
11959 +#include <linux/io.h>
11960 +
11961 +#include "lnxwrp_fm_ext.h"
11962 +
11963 +#include "mac.h"
11964 +
11965 +#define DTSEC_SUPPORTED \
11966 + (SUPPORTED_10baseT_Half \
11967 + | SUPPORTED_10baseT_Full \
11968 + | SUPPORTED_100baseT_Half \
11969 + | SUPPORTED_100baseT_Full \
11970 + | SUPPORTED_Autoneg \
11971 + | SUPPORTED_Pause \
11972 + | SUPPORTED_Asym_Pause \
11973 + | SUPPORTED_MII)
11974 +
11975 +static const char phy_str[][11] = {
11976 + [PHY_INTERFACE_MODE_MII] = "mii",
11977 + [PHY_INTERFACE_MODE_GMII] = "gmii",
11978 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
11979 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
11980 + [PHY_INTERFACE_MODE_TBI] = "tbi",
11981 + [PHY_INTERFACE_MODE_RMII] = "rmii",
11982 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
11983 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
11984 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
11985 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
11986 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
11987 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
11988 + [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
11989 +};
11990 +
11991 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
11992 +{
11993 + int i;
11994 +
11995 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
11996 + if (strcmp(str, phy_str[i]) == 0)
11997 + return (phy_interface_t)i;
11998 +
11999 + return PHY_INTERFACE_MODE_MII;
12000 +}
12001 +
12002 +static const uint16_t phy2speed[] = {
12003 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
12004 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
12005 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
12006 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
12007 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
12008 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
12009 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
12010 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
12011 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
12012 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
12013 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
12014 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
12015 + [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500,
12016 +};
12017 +
12018 +static struct mac_device * __cold
12019 +alloc_macdev(struct device *dev, size_t sizeof_priv,
12020 + void (*setup)(struct mac_device *mac_dev))
12021 +{
12022 + struct mac_device *mac_dev;
12023 +
12024 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
12025 + if (unlikely(mac_dev == NULL))
12026 + mac_dev = ERR_PTR(-ENOMEM);
12027 + else {
12028 + mac_dev->dev = dev;
12029 + dev_set_drvdata(dev, mac_dev);
12030 + setup(mac_dev);
12031 + }
12032 +
12033 + return mac_dev;
12034 +}
12035 +
12036 +static int __cold free_macdev(struct mac_device *mac_dev)
12037 +{
12038 + dev_set_drvdata(mac_dev->dev, NULL);
12039 +
12040 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
12041 +}
12042 +
12043 +static const struct of_device_id mac_match[] = {
12044 + [DTSEC] = {
12045 + .compatible = "fsl,fman-1g-mac"
12046 + },
12047 + [XGMAC] = {
12048 + .compatible = "fsl,fman-10g-mac"
12049 + },
12050 + [MEMAC] = {
12051 + .compatible = "fsl,fman-memac"
12052 + },
12053 + {}
12054 +};
12055 +MODULE_DEVICE_TABLE(of, mac_match);
12056 +
12057 +static int __cold mac_probe(struct platform_device *_of_dev)
12058 +{
12059 + int _errno, i;
12060 + struct device *dev;
12061 + struct device_node *mac_node, *dev_node;
12062 + struct mac_device *mac_dev;
12063 + struct platform_device *of_dev;
12064 + struct resource res;
12065 + const uint8_t *mac_addr;
12066 + const char *char_prop;
12067 + int nph;
12068 + u32 cell_index;
12069 + const struct of_device_id *match;
12070 +
12071 + dev = &_of_dev->dev;
12072 + mac_node = dev->of_node;
12073 +
12074 + match = of_match_device(mac_match, dev);
12075 + if (!match)
12076 + return -EINVAL;
12077 +
12078 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
12079 + i++)
12080 + ;
12081 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
12082 +
12083 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
12084 + if (IS_ERR(mac_dev)) {
12085 + _errno = PTR_ERR(mac_dev);
12086 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
12087 + goto _return;
12088 + }
12089 +
12090 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
12091 +
12092 + /* Get the FM node */
12093 + dev_node = of_get_parent(mac_node);
12094 + if (unlikely(dev_node == NULL)) {
12095 + dev_err(dev, "of_get_parent(%s) failed\n",
12096 + mac_node->full_name);
12097 + _errno = -EINVAL;
12098 + goto _return_dev_set_drvdata;
12099 + }
12100 +
12101 + of_dev = of_find_device_by_node(dev_node);
12102 + if (unlikely(of_dev == NULL)) {
12103 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12104 + dev_node->full_name);
12105 + _errno = -EINVAL;
12106 + goto _return_of_node_put;
12107 + }
12108 +
12109 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
12110 + if (unlikely(mac_dev->fm_dev == NULL)) {
12111 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
12112 + _errno = -ENODEV;
12113 + goto _return_of_node_put;
12114 + }
12115 +
12116 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
12117 + of_node_put(dev_node);
12118 +
12119 + /* Get the address of the memory mapped registers */
12120 + _errno = of_address_to_resource(mac_node, 0, &res);
12121 + if (unlikely(_errno < 0)) {
12122 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
12123 + mac_node->full_name, _errno);
12124 + goto _return_dev_set_drvdata;
12125 + }
12126 +
12127 + mac_dev->res = __devm_request_region(
12128 + dev,
12129 + fm_get_mem_region(mac_dev->fm_dev),
12130 + res.start, res.end + 1 - res.start, "mac");
12131 + if (unlikely(mac_dev->res == NULL)) {
12132 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
12133 + _errno = -EBUSY;
12134 + goto _return_dev_set_drvdata;
12135 + }
12136 +
12137 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
12138 + mac_dev->res->end + 1
12139 + - mac_dev->res->start);
12140 + if (unlikely(mac_dev->vaddr == NULL)) {
12141 + dev_err(dev, "devm_ioremap() failed\n");
12142 + _errno = -EIO;
12143 + goto _return_dev_set_drvdata;
12144 + }
12145 +
12146 +#define TBIPA_OFFSET 0x1c
12147 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
12148 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
12149 + if (mac_dev->tbi_node) {
12150 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
12151 + const __be32 *tbi_reg;
12152 + void __iomem *addr;
12153 +
12154 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
12155 + if (tbi_reg)
12156 + tbiaddr = be32_to_cpup(tbi_reg);
12157 + addr = mac_dev->vaddr + TBIPA_OFFSET;
12158 + /* TODO: out_be32 does not exist on ARM */
12159 + out_be32(addr, tbiaddr);
12160 + }
12161 +
12162 + if (!of_device_is_available(mac_node)) {
12163 + devm_iounmap(dev, mac_dev->vaddr);
12164 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
12165 + res.start, res.end + 1 - res.start);
12166 + fm_unbind(mac_dev->fm_dev);
12167 + devm_kfree(dev, mac_dev);
12168 + dev_set_drvdata(dev, NULL);
12169 + return -ENODEV;
12170 + }
12171 +
12172 + /* Get the cell-index */
12173 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
12174 + if (unlikely(_errno)) {
12175 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
12176 + mac_node->full_name);
12177 + goto _return_dev_set_drvdata;
12178 + }
12179 + mac_dev->cell_index = (uint8_t)cell_index;
12180 + if (mac_dev->cell_index >= 8)
12181 + mac_dev->cell_index -= 8;
12182 +
12183 + /* Get the MAC address */
12184 + mac_addr = of_get_mac_address(mac_node);
12185 + if (unlikely(mac_addr == NULL)) {
12186 + dev_err(dev, "of_get_mac_address(%s) failed\n",
12187 + mac_node->full_name);
12188 + _errno = -EINVAL;
12189 + goto _return_dev_set_drvdata;
12190 + }
12191 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
12192 +
12193 + /* Verify the number of port handles */
12194 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
12195 + if (unlikely(nph < 0)) {
12196 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
12197 + mac_node->full_name);
12198 + _errno = nph;
12199 + goto _return_dev_set_drvdata;
12200 + }
12201 +
12202 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
12203 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
12204 + mac_node->full_name);
12205 + _errno = -EINVAL;
12206 + goto _return_dev_set_drvdata;
12207 + }
12208 +
12209 + for_each_port_device(i, mac_dev->port_dev) {
12210 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
12211 + if (unlikely(dev_node == NULL)) {
12212 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
12213 + mac_node->full_name);
12214 + _errno = -EINVAL;
12215 + goto _return_of_node_put;
12216 + }
12217 +
12218 + of_dev = of_find_device_by_node(dev_node);
12219 + if (unlikely(of_dev == NULL)) {
12220 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12221 + dev_node->full_name);
12222 + _errno = -EINVAL;
12223 + goto _return_of_node_put;
12224 + }
12225 +
12226 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
12227 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
12228 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
12229 + dev_node->full_name);
12230 + _errno = -EINVAL;
12231 + goto _return_of_node_put;
12232 + }
12233 + of_node_put(dev_node);
12234 + }
12235 +
12236 + /* Get the PHY connection type */
12237 + _errno = of_property_read_string(mac_node, "phy-connection-type",
12238 + &char_prop);
12239 + if (unlikely(_errno)) {
12240 + dev_warn(dev,
12241 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
12242 + mac_node->full_name);
12243 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
12244 + } else
12245 + mac_dev->phy_if = str2phy(char_prop);
12246 +
12247 + mac_dev->link = false;
12248 + mac_dev->half_duplex = false;
12249 + mac_dev->speed = phy2speed[mac_dev->phy_if];
12250 + mac_dev->max_speed = mac_dev->speed;
12251 + mac_dev->if_support = DTSEC_SUPPORTED;
12252 + /* We don't support half-duplex in SGMII mode */
12253 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
12254 + strstr(char_prop, "sgmii-2500"))
12255 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
12256 + SUPPORTED_100baseT_Half);
12257 +
12258 + /* Gigabit support (no half-duplex) */
12259 + if (mac_dev->max_speed == SPEED_1000 ||
12260 + mac_dev->max_speed == SPEED_2500)
12261 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
12262 +
12263 + /* The 10G interface only supports one mode */
12264 + if (strstr(char_prop, "xgmii"))
12265 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
12266 +
12267 + /* Get the rest of the PHY information */
12268 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
12269 + if (!mac_dev->phy_node) {
12270 + struct phy_device *phy;
12271 +
12272 + if (!of_phy_is_fixed_link(mac_node)) {
12273 + dev_err(dev, "Wrong PHY information of mac node %s\n",
12274 + mac_node->full_name);
12275 + goto _return_dev_set_drvdata;
12276 + }
12277 +
12278 + _errno = of_phy_register_fixed_link(mac_node);
12279 + if (_errno)
12280 + goto _return_dev_set_drvdata;
12281 +
12282 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
12283 + sizeof(*mac_dev->fixed_link),
12284 + GFP_KERNEL);
12285 + if (!mac_dev->fixed_link)
12286 + goto _return_dev_set_drvdata;
12287 +
12288 + mac_dev->phy_node = of_node_get(mac_node);
12289 + phy = of_phy_find_device(mac_dev->phy_node);
12290 + if (!phy)
12291 + goto _return_dev_set_drvdata;
12292 +
12293 + mac_dev->fixed_link->link = phy->link;
12294 + mac_dev->fixed_link->speed = phy->speed;
12295 + mac_dev->fixed_link->duplex = phy->duplex;
12296 + mac_dev->fixed_link->pause = phy->pause;
12297 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
12298 + }
12299 +
12300 + _errno = mac_dev->init(mac_dev);
12301 + if (unlikely(_errno < 0)) {
12302 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
12303 + goto _return_dev_set_drvdata;
12304 + }
12305 +
12306 + /* pause frame autonegotiation enabled*/
12307 + mac_dev->autoneg_pause = true;
12308 +
12309 + /* by intializing the values to false, force FMD to enable PAUSE frames
12310 + * on RX and TX
12311 + */
12312 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
12313 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
12314 + _errno = set_mac_active_pause(mac_dev, true, true);
12315 + if (unlikely(_errno < 0))
12316 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
12317 +
12318 + dev_info(dev,
12319 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
12320 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
12321 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
12322 +
12323 + goto _return;
12324 +
12325 +_return_of_node_put:
12326 + of_node_put(dev_node);
12327 +_return_dev_set_drvdata:
12328 + dev_set_drvdata(dev, NULL);
12329 +_return:
12330 + return _errno;
12331 +}
12332 +
12333 +static int __cold mac_remove(struct platform_device *of_dev)
12334 +{
12335 + int i, _errno;
12336 + struct device *dev;
12337 + struct mac_device *mac_dev;
12338 +
12339 + dev = &of_dev->dev;
12340 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
12341 +
12342 + for_each_port_device(i, mac_dev->port_dev)
12343 + fm_port_unbind(mac_dev->port_dev[i]);
12344 +
12345 + fm_unbind(mac_dev->fm_dev);
12346 +
12347 + _errno = free_macdev(mac_dev);
12348 +
12349 + return _errno;
12350 +}
12351 +
12352 +static struct platform_driver mac_driver = {
12353 + .driver = {
12354 + .name = KBUILD_MODNAME,
12355 + .of_match_table = mac_match,
12356 + .owner = THIS_MODULE,
12357 + },
12358 + .probe = mac_probe,
12359 + .remove = mac_remove
12360 +};
12361 +
12362 +static int __init __cold mac_load(void)
12363 +{
12364 + int _errno;
12365 +
12366 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12367 + KBUILD_BASENAME".c", __func__);
12368 +
12369 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
12370 +
12371 + _errno = platform_driver_register(&mac_driver);
12372 + if (unlikely(_errno < 0)) {
12373 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
12374 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
12375 + goto _return;
12376 + }
12377 +
12378 + goto _return;
12379 +
12380 +_return:
12381 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12382 + KBUILD_BASENAME".c", __func__);
12383 +
12384 + return _errno;
12385 +}
12386 +module_init(mac_load);
12387 +
12388 +static void __exit __cold mac_unload(void)
12389 +{
12390 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12391 + KBUILD_BASENAME".c", __func__);
12392 +
12393 + platform_driver_unregister(&mac_driver);
12394 +
12395 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12396 + KBUILD_BASENAME".c", __func__);
12397 +}
12398 +module_exit(mac_unload);
12399 --- /dev/null
12400 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12401 @@ -0,0 +1,135 @@
12402 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
12403 + *
12404 + * Redistribution and use in source and binary forms, with or without
12405 + * modification, are permitted provided that the following conditions are met:
12406 + * * Redistributions of source code must retain the above copyright
12407 + * notice, this list of conditions and the following disclaimer.
12408 + * * Redistributions in binary form must reproduce the above copyright
12409 + * notice, this list of conditions and the following disclaimer in the
12410 + * documentation and/or other materials provided with the distribution.
12411 + * * Neither the name of Freescale Semiconductor nor the
12412 + * names of its contributors may be used to endorse or promote products
12413 + * derived from this software without specific prior written permission.
12414 + *
12415 + *
12416 + * ALTERNATIVELY, this software may be distributed under the terms of the
12417 + * GNU General Public License ("GPL") as published by the Free Software
12418 + * Foundation, either version 2 of that License or (at your option) any
12419 + * later version.
12420 + *
12421 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12422 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12423 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12424 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12425 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12426 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12427 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12428 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12429 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12430 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12431 + */
12432 +
12433 +#ifndef __MAC_H
12434 +#define __MAC_H
12435 +
12436 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
12437 +#include <linux/if_ether.h> /* ETH_ALEN */
12438 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
12439 +#include <linux/list.h>
12440 +
12441 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
12442 +
12443 +enum {DTSEC, XGMAC, MEMAC};
12444 +
12445 +struct mac_device {
12446 + struct device *dev;
12447 + void *priv;
12448 + uint8_t cell_index;
12449 + struct resource *res;
12450 + void __iomem *vaddr;
12451 + uint8_t addr[ETH_ALEN];
12452 + bool promisc;
12453 +
12454 + struct fm *fm_dev;
12455 + struct fm_port *port_dev[2];
12456 +
12457 + phy_interface_t phy_if;
12458 + u32 if_support;
12459 + bool link;
12460 + bool half_duplex;
12461 + uint16_t speed;
12462 + uint16_t max_speed;
12463 + struct device_node *phy_node;
12464 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
12465 + struct device_node *tbi_node;
12466 + struct phy_device *phy_dev;
12467 + void *fm;
12468 + /* List of multicast addresses */
12469 + struct list_head mc_addr_list;
12470 + struct fixed_phy_status *fixed_link;
12471 +
12472 + bool autoneg_pause;
12473 + bool rx_pause_req;
12474 + bool tx_pause_req;
12475 + bool rx_pause_active;
12476 + bool tx_pause_active;
12477 +
12478 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
12479 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
12480 + int (*init)(struct mac_device *mac_dev);
12481 + int (*start)(struct mac_device *mac_dev);
12482 + int (*stop)(struct mac_device *mac_dev);
12483 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
12484 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
12485 + int (*set_multi)(struct net_device *net_dev,
12486 + struct mac_device *mac_dev);
12487 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
12488 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
12489 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
12490 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12491 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12492 + int (*fm_rtc_enable)(struct fm *fm_dev);
12493 + int (*fm_rtc_disable)(struct fm *fm_dev);
12494 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
12495 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
12496 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
12497 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
12498 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
12499 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
12500 + uint64_t fiper);
12501 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
12502 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
12503 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
12504 +#endif
12505 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
12506 + bool en);
12507 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
12508 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
12509 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
12510 +};
12511 +
12512 +struct mac_address {
12513 + uint8_t addr[ETH_ALEN];
12514 + struct list_head list;
12515 +};
12516 +
12517 +#define get_fm_handle(net_dev) \
12518 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
12519 +
12520 +#define for_each_port_device(i, port_dev) \
12521 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
12522 +
12523 +static inline __attribute((nonnull)) void *macdev_priv(
12524 + const struct mac_device *mac_dev)
12525 +{
12526 + return (void *)mac_dev + sizeof(*mac_dev);
12527 +}
12528 +
12529 +extern const char *mac_driver_description;
12530 +extern const size_t mac_sizeof_priv[];
12531 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
12532 +
12533 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
12534 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
12535 +
12536 +#endif /* __MAC_H */
12537 --- /dev/null
12538 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12539 @@ -0,0 +1,848 @@
12540 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
12541 + *
12542 + * Redistribution and use in source and binary forms, with or without
12543 + * modification, are permitted provided that the following conditions are met:
12544 + * * Redistributions of source code must retain the above copyright
12545 + * notice, this list of conditions and the following disclaimer.
12546 + * * Redistributions in binary form must reproduce the above copyright
12547 + * notice, this list of conditions and the following disclaimer in the
12548 + * documentation and/or other materials provided with the distribution.
12549 + * * Neither the name of Freescale Semiconductor nor the
12550 + * names of its contributors may be used to endorse or promote products
12551 + * derived from this software without specific prior written permission.
12552 + *
12553 + *
12554 + * ALTERNATIVELY, this software may be distributed under the terms of the
12555 + * GNU General Public License ("GPL") as published by the Free Software
12556 + * Foundation, either version 2 of that License or (at your option) any
12557 + * later version.
12558 + *
12559 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12560 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12561 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12562 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12563 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12564 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12565 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12566 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12567 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12568 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12569 + */
12570 +
12571 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
12572 + * Validates device-tree configuration and sets up the offline ports.
12573 + */
12574 +
12575 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12576 +#define pr_fmt(fmt) \
12577 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12578 + KBUILD_BASENAME".c", __LINE__, __func__
12579 +#else
12580 +#define pr_fmt(fmt) \
12581 + KBUILD_MODNAME ": " fmt
12582 +#endif
12583 +
12584 +
12585 +#include <linux/init.h>
12586 +#include <linux/module.h>
12587 +#include <linux/of_platform.h>
12588 +#include <linux/fsl_qman.h>
12589 +
12590 +#include "offline_port.h"
12591 +#include "dpaa_eth.h"
12592 +#include "dpaa_eth_common.h"
12593 +
12594 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
12595 +/* Manip extra space and data alignment for fragmentation */
12596 +#define FRAG_MANIP_SPACE 128
12597 +#define FRAG_DATA_ALIGN 64
12598 +
12599 +
12600 +MODULE_LICENSE("Dual BSD/GPL");
12601 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
12602 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
12603 +
12604 +
12605 +static const struct of_device_id oh_port_match_table[] = {
12606 + {
12607 + .compatible = "fsl,dpa-oh"
12608 + },
12609 + {
12610 + .compatible = "fsl,dpa-oh-shared"
12611 + },
12612 + {}
12613 +};
12614 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
12615 +
12616 +#ifdef CONFIG_PM
12617 +
12618 +static int oh_suspend(struct device *dev)
12619 +{
12620 + struct dpa_oh_config_s *oh_config;
12621 +
12622 + oh_config = dev_get_drvdata(dev);
12623 + return fm_port_suspend(oh_config->oh_port);
12624 +}
12625 +
12626 +static int oh_resume(struct device *dev)
12627 +{
12628 + struct dpa_oh_config_s *oh_config;
12629 +
12630 + oh_config = dev_get_drvdata(dev);
12631 + return fm_port_resume(oh_config->oh_port);
12632 +}
12633 +
12634 +static const struct dev_pm_ops oh_pm_ops = {
12635 + .suspend = oh_suspend,
12636 + .resume = oh_resume,
12637 +};
12638 +
12639 +#define OH_PM_OPS (&oh_pm_ops)
12640 +
12641 +#else /* CONFIG_PM */
12642 +
12643 +#define OH_PM_OPS NULL
12644 +
12645 +#endif /* CONFIG_PM */
12646 +
12647 +/* Creates Frame Queues */
12648 +static uint32_t oh_fq_create(struct qman_fq *fq,
12649 + uint32_t fq_id, uint16_t channel,
12650 + uint16_t wq_id)
12651 +{
12652 + struct qm_mcc_initfq fq_opts;
12653 + uint32_t create_flags, init_flags;
12654 + uint32_t ret = 0;
12655 +
12656 + if (fq == NULL)
12657 + return 1;
12658 +
12659 + /* Set flags for FQ create */
12660 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
12661 +
12662 + /* Create frame queue */
12663 + ret = qman_create_fq(fq_id, create_flags, fq);
12664 + if (ret != 0)
12665 + return 1;
12666 +
12667 + /* Set flags for FQ init */
12668 + init_flags = QMAN_INITFQ_FLAG_SCHED;
12669 +
12670 + /* Set FQ init options. Specify destination WQ ID and channel */
12671 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
12672 + fq_opts.fqd.dest.wq = wq_id;
12673 + fq_opts.fqd.dest.channel = channel;
12674 +
12675 + /* Initialize frame queue */
12676 + ret = qman_init_fq(fq, init_flags, &fq_opts);
12677 + if (ret != 0) {
12678 + qman_destroy_fq(fq, 0);
12679 + return 1;
12680 + }
12681 +
12682 + return 0;
12683 +}
12684 +
12685 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
12686 +{
12687 + if (channel) {
12688 + /* display fqs with a valid (!= 0) destination channel */
12689 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
12690 + }
12691 +}
12692 +
12693 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
12694 + int fqs_count, uint16_t channel_id)
12695 +{
12696 + int i;
12697 + for (i = 0; i < fqs_count; i++)
12698 + dump_fq(dev, (fqs + i)->fqid, channel_id);
12699 +}
12700 +
12701 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
12702 +{
12703 + struct list_head *fq_list;
12704 + struct fq_duple *fqd;
12705 + int i;
12706 +
12707 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
12708 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
12709 +
12710 + /* TX queues (old initialization) */
12711 + dev_info(dev, "Initialized queues:");
12712 + for (i = 0; i < conf->egress_cnt; i++)
12713 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
12714 + conf->channel);
12715 +
12716 + /* initialized ingress queues */
12717 + list_for_each(fq_list, &conf->fqs_ingress_list) {
12718 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12719 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12720 + }
12721 +
12722 + /* initialized egress queues */
12723 + list_for_each(fq_list, &conf->fqs_egress_list) {
12724 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12725 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12726 + }
12727 +}
12728 +
12729 +/* Destroys Frame Queues */
12730 +static void oh_fq_destroy(struct qman_fq *fq)
12731 +{
12732 + int _errno = 0;
12733 +
12734 + _errno = qman_retire_fq(fq, NULL);
12735 + if (unlikely(_errno < 0))
12736 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
12737 + KBUILD_BASENAME".c", __LINE__, __func__,
12738 + qman_fq_fqid(fq), _errno);
12739 +
12740 + _errno = qman_oos_fq(fq);
12741 + if (unlikely(_errno < 0)) {
12742 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
12743 + KBUILD_BASENAME".c", __LINE__, __func__,
12744 + qman_fq_fqid(fq), _errno);
12745 + }
12746 +
12747 + qman_destroy_fq(fq, 0);
12748 +}
12749 +
12750 +/* Allocation code for the OH port's PCD frame queues */
12751 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
12752 + uint32_t num,
12753 + uint8_t alignment,
12754 + uint32_t *base_fqid)
12755 +{
12756 + dev_crit(dev, "callback not implemented!\n");
12757 + BUG();
12758 +
12759 + return 0;
12760 +}
12761 +
12762 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
12763 +{
12764 + dev_crit(dev, "callback not implemented!\n");
12765 + BUG();
12766 +
12767 + return 0;
12768 +}
12769 +
12770 +static void oh_set_buffer_layout(struct fm_port *port,
12771 + struct dpa_buffer_layout_s *layout)
12772 +{
12773 + struct fm_port_params params;
12774 +
12775 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
12776 + layout->parse_results = true;
12777 + layout->hash_results = true;
12778 + layout->time_stamp = false;
12779 +
12780 + fm_port_get_buff_layout_ext_params(port, &params);
12781 + layout->manip_extra_space = params.manip_extra_space;
12782 + layout->data_align = params.data_align;
12783 +}
12784 +
12785 +static int
12786 +oh_port_probe(struct platform_device *_of_dev)
12787 +{
12788 + struct device *dpa_oh_dev;
12789 + struct device_node *dpa_oh_node;
12790 + int lenp, _errno = 0, fq_idx, duple_idx;
12791 + int n_size, i, j, ret, duples_count;
12792 + struct platform_device *oh_of_dev;
12793 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
12794 + struct device *oh_dev;
12795 + struct dpa_oh_config_s *oh_config = NULL;
12796 + const __be32 *oh_all_queues;
12797 + const __be32 *channel_ids;
12798 + const __be32 *oh_tx_queues;
12799 + uint32_t queues_count;
12800 + uint32_t crt_fqid_base;
12801 + uint32_t crt_fq_count;
12802 + bool frag_enabled = false;
12803 + struct fm_port_params oh_port_tx_params;
12804 + struct fm_port_pcd_param oh_port_pcd_params;
12805 + struct dpa_buffer_layout_s buf_layout;
12806 +
12807 + /* True if the current partition owns the OH port. */
12808 + bool init_oh_port;
12809 +
12810 + const struct of_device_id *match;
12811 + int crt_ext_pools_count;
12812 + u32 ext_pool_size;
12813 + u32 port_id;
12814 + u32 channel_id;
12815 +
12816 + int channel_ids_count;
12817 + int channel_idx;
12818 + struct fq_duple *fqd;
12819 + struct list_head *fq_list, *fq_list_tmp;
12820 +
12821 + const __be32 *bpool_cfg;
12822 + uint32_t bpid;
12823 +
12824 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
12825 + dpa_oh_dev = &_of_dev->dev;
12826 + dpa_oh_node = dpa_oh_dev->of_node;
12827 + BUG_ON(dpa_oh_node == NULL);
12828 +
12829 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
12830 + if (!match)
12831 + return -EINVAL;
12832 +
12833 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
12834 +
12835 + /* Find the referenced OH node */
12836 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
12837 + if (oh_node == NULL) {
12838 + dev_err(dpa_oh_dev,
12839 + "Can't find OH node referenced from node %s\n",
12840 + dpa_oh_node->full_name);
12841 + return -EINVAL;
12842 + }
12843 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
12844 + match->compatible);
12845 +
12846 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
12847 + if (_errno) {
12848 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
12849 + dpa_oh_node->full_name);
12850 + goto return_kfree;
12851 + }
12852 +
12853 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
12854 + &channel_id);
12855 + if (_errno) {
12856 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
12857 + dpa_oh_node->full_name);
12858 + goto return_kfree;
12859 + }
12860 +
12861 + oh_of_dev = of_find_device_by_node(oh_node);
12862 + BUG_ON(oh_of_dev == NULL);
12863 + oh_dev = &oh_of_dev->dev;
12864 +
12865 + /* The OH port must be initialized exactly once.
12866 + * The following scenarios are of interest:
12867 + * - the node is Linux-private (will always initialize it);
12868 + * - the node is shared between two Linux partitions
12869 + * (only one of them will initialize it);
12870 + * - the node is shared between a Linux and a LWE partition
12871 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
12872 + */
12873 +
12874 + /* Check if the current partition owns the OH port
12875 + * and ought to initialize it. It may be the case that we leave this
12876 + * to another (also Linux) partition.
12877 + */
12878 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
12879 +
12880 + /* If we aren't the "owner" of the OH node, we're done here. */
12881 + if (!init_oh_port) {
12882 + dev_dbg(dpa_oh_dev,
12883 + "Not owning the shared OH port %s, will not initialize it.\n",
12884 + oh_node->full_name);
12885 + of_node_put(oh_node);
12886 + return 0;
12887 + }
12888 +
12889 + /* Allocate OH dev private data */
12890 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
12891 + if (oh_config == NULL) {
12892 + dev_err(dpa_oh_dev,
12893 + "Can't allocate private data for OH node %s referenced from node %s!\n",
12894 + oh_node->full_name, dpa_oh_node->full_name);
12895 + _errno = -ENOMEM;
12896 + goto return_kfree;
12897 + }
12898 +
12899 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
12900 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
12901 +
12902 + /* FQs that enter OH port */
12903 + lenp = 0;
12904 + oh_all_queues = of_get_property(dpa_oh_node,
12905 + "fsl,qman-frame-queues-ingress", &lenp);
12906 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12907 + dev_warn(dpa_oh_dev,
12908 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
12909 + oh_node->full_name, dpa_oh_node->full_name);
12910 + /* just ignore the last unpaired value */
12911 + }
12912 +
12913 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12914 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
12915 + duples_count);
12916 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12917 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12918 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12919 +
12920 + fqd = devm_kzalloc(dpa_oh_dev,
12921 + sizeof(struct fq_duple), GFP_KERNEL);
12922 + if (!fqd) {
12923 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12924 + oh_node->full_name,
12925 + dpa_oh_node->full_name);
12926 + _errno = -ENOMEM;
12927 + goto return_kfree;
12928 + }
12929 +
12930 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
12931 + crt_fq_count * sizeof(struct qman_fq),
12932 + GFP_KERNEL);
12933 + if (!fqd->fqs) {
12934 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
12935 + oh_node->full_name,
12936 + dpa_oh_node->full_name);
12937 + _errno = -ENOMEM;
12938 + goto return_kfree;
12939 + }
12940 +
12941 + for (j = 0; j < crt_fq_count; j++)
12942 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
12943 + fqd->fqs_count = crt_fq_count;
12944 + fqd->channel_id = (uint16_t)channel_id;
12945 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
12946 + }
12947 +
12948 + /* create the ingress queues */
12949 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
12950 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12951 +
12952 + for (j = 0; j < fqd->fqs_count; j++) {
12953 + ret = oh_fq_create(fqd->fqs + j,
12954 + (fqd->fqs + j)->fqid,
12955 + fqd->channel_id, 3);
12956 + if (ret != 0) {
12957 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
12958 + (fqd->fqs + j)->fqid,
12959 + oh_node->full_name,
12960 + dpa_oh_node->full_name);
12961 + _errno = -EINVAL;
12962 + goto return_kfree;
12963 + }
12964 + }
12965 + }
12966 +
12967 + /* FQs that exit OH port */
12968 + lenp = 0;
12969 + oh_all_queues = of_get_property(dpa_oh_node,
12970 + "fsl,qman-frame-queues-egress", &lenp);
12971 + if (lenp % (2 * sizeof(*oh_all_queues))) {
12972 + dev_warn(dpa_oh_dev,
12973 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
12974 + oh_node->full_name, dpa_oh_node->full_name);
12975 + /* just ignore the last unpaired value */
12976 + }
12977 +
12978 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
12979 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
12980 + duples_count);
12981 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
12982 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
12983 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
12984 +
12985 + fqd = devm_kzalloc(dpa_oh_dev,
12986 + sizeof(struct fq_duple), GFP_KERNEL);
12987 + if (!fqd) {
12988 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
12989 + oh_node->full_name,
12990 + dpa_oh_node->full_name);
12991 + _errno = -ENOMEM;
12992 + goto return_kfree;
12993 + }
12994 +
12995 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
12996 + crt_fq_count * sizeof(struct qman_fq),
12997 + GFP_KERNEL);
12998 + if (!fqd->fqs) {
12999 + dev_err(dpa_oh_dev,
13000 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13001 + oh_node->full_name,
13002 + dpa_oh_node->full_name);
13003 + _errno = -ENOMEM;
13004 + goto return_kfree;
13005 + }
13006 +
13007 + for (j = 0; j < crt_fq_count; j++)
13008 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13009 + fqd->fqs_count = crt_fq_count;
13010 + /* channel ID is specified in another attribute */
13011 + fqd->channel_id = 0;
13012 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
13013 +
13014 + /* allocate the queue */
13015 +
13016 + }
13017 +
13018 + /* channel_ids for FQs that exit OH port */
13019 + lenp = 0;
13020 + channel_ids = of_get_property(dpa_oh_node,
13021 + "fsl,qman-channel-ids-egress", &lenp);
13022 +
13023 + channel_ids_count = lenp / (sizeof(*channel_ids));
13024 + if (channel_ids_count != duples_count) {
13025 + dev_warn(dpa_oh_dev,
13026 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
13027 + oh_node->full_name, dpa_oh_node->full_name);
13028 + /* just ignore the queues that do not have a Channel ID */
13029 + }
13030 +
13031 + channel_idx = 0;
13032 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13033 + if (channel_idx + 1 > channel_ids_count)
13034 + break;
13035 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13036 + fqd->channel_id =
13037 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
13038 + }
13039 +
13040 + /* create egress queues */
13041 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13042 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13043 +
13044 + if (fqd->channel_id == 0) {
13045 + /* missing channel id in dts */
13046 + continue;
13047 + }
13048 +
13049 + for (j = 0; j < fqd->fqs_count; j++) {
13050 + ret = oh_fq_create(fqd->fqs + j,
13051 + (fqd->fqs + j)->fqid,
13052 + fqd->channel_id, 3);
13053 + if (ret != 0) {
13054 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
13055 + (fqd->fqs + j)->fqid,
13056 + oh_node->full_name,
13057 + dpa_oh_node->full_name);
13058 + _errno = -EINVAL;
13059 + goto return_kfree;
13060 + }
13061 + }
13062 + }
13063 +
13064 + /* Read FQ ids/nums for the DPA OH node */
13065 + oh_all_queues = of_get_property(dpa_oh_node,
13066 + "fsl,qman-frame-queues-oh", &lenp);
13067 + if (oh_all_queues == NULL) {
13068 + dev_err(dpa_oh_dev,
13069 + "No frame queues have been defined for OH node %s referenced from node %s\n",
13070 + oh_node->full_name, dpa_oh_node->full_name);
13071 + _errno = -EINVAL;
13072 + goto return_kfree;
13073 + }
13074 +
13075 + /* Check that the OH error and default FQs are there */
13076 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
13077 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
13078 + if (queues_count != 2) {
13079 + dev_err(dpa_oh_dev,
13080 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
13081 + oh_node->full_name, dpa_oh_node->full_name);
13082 + _errno = -EINVAL;
13083 + goto return_kfree;
13084 + }
13085 +
13086 + /* Read the FQIDs defined for this OH port */
13087 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
13088 + fq_idx = 0;
13089 +
13090 + /* Error FQID - must be present */
13091 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13092 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13093 + if (crt_fq_count != 1) {
13094 + dev_err(dpa_oh_dev,
13095 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
13096 + oh_node->full_name, dpa_oh_node->full_name,
13097 + crt_fq_count);
13098 + _errno = -EINVAL;
13099 + goto return_kfree;
13100 + }
13101 + oh_config->error_fqid = crt_fqid_base;
13102 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
13103 + oh_config->error_fqid, oh_node->full_name);
13104 +
13105 + /* Default FQID - must be present */
13106 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13107 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13108 + if (crt_fq_count != 1) {
13109 + dev_err(dpa_oh_dev,
13110 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
13111 + oh_node->full_name, dpa_oh_node->full_name,
13112 + crt_fq_count);
13113 + _errno = -EINVAL;
13114 + goto return_kfree;
13115 + }
13116 + oh_config->default_fqid = crt_fqid_base;
13117 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
13118 + oh_config->default_fqid, oh_node->full_name);
13119 +
13120 + /* TX FQID - presence is optional */
13121 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
13122 + &lenp);
13123 + if (oh_tx_queues == NULL) {
13124 + dev_dbg(dpa_oh_dev,
13125 + "No tx queues have been defined for OH node %s referenced from node %s\n",
13126 + oh_node->full_name, dpa_oh_node->full_name);
13127 + goto config_port;
13128 + }
13129 +
13130 + /* Check that queues-tx has only a base and a count defined */
13131 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
13132 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
13133 + if (queues_count != 1) {
13134 + dev_err(dpa_oh_dev,
13135 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
13136 + oh_node->full_name, dpa_oh_node->full_name);
13137 + _errno = -EINVAL;
13138 + goto return_kfree;
13139 + }
13140 +
13141 + fq_idx = 0;
13142 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
13143 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
13144 + oh_config->egress_cnt = crt_fq_count;
13145 +
13146 + /* Allocate TX queues */
13147 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
13148 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
13149 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
13150 + if (oh_config->egress_fqs == NULL) {
13151 + dev_err(dpa_oh_dev,
13152 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
13153 + oh_node->full_name, dpa_oh_node->full_name);
13154 + _errno = -ENOMEM;
13155 + goto return_kfree;
13156 + }
13157 +
13158 + /* Create TX queues */
13159 + for (i = 0; i < crt_fq_count; i++) {
13160 + ret = oh_fq_create(oh_config->egress_fqs + i,
13161 + crt_fqid_base + i, (uint16_t)channel_id, 3);
13162 + if (ret != 0) {
13163 + dev_err(dpa_oh_dev,
13164 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
13165 + crt_fqid_base + i, oh_node->full_name,
13166 + dpa_oh_node->full_name);
13167 + _errno = -EINVAL;
13168 + goto return_kfree;
13169 + }
13170 + }
13171 +
13172 +config_port:
13173 + /* Get a handle to the fm_port so we can set
13174 + * its configuration params
13175 + */
13176 + oh_config->oh_port = fm_port_bind(oh_dev);
13177 + if (oh_config->oh_port == NULL) {
13178 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
13179 + oh_node->full_name);
13180 + _errno = -EINVAL;
13181 + goto return_kfree;
13182 + }
13183 +
13184 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
13185 +
13186 + /* read the pool handlers */
13187 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
13188 + "fsl,bman-buffer-pools", NULL);
13189 + if (crt_ext_pools_count <= 0) {
13190 + dev_info(dpa_oh_dev,
13191 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
13192 + oh_node->full_name);
13193 + goto init_port;
13194 + }
13195 +
13196 + /* used for reading ext_pool_size*/
13197 + root_node = of_find_node_by_path("/");
13198 + if (root_node == NULL) {
13199 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
13200 + _errno = -EINVAL;
13201 + goto return_kfree;
13202 + }
13203 +
13204 + n_size = of_n_size_cells(root_node);
13205 + of_node_put(root_node);
13206 +
13207 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
13208 + crt_ext_pools_count);
13209 +
13210 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
13211 +
13212 + for (i = 0; i < crt_ext_pools_count; i++) {
13213 + bpool_node = of_parse_phandle(dpa_oh_node,
13214 + "fsl,bman-buffer-pools", i);
13215 + if (bpool_node == NULL) {
13216 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
13217 + _errno = -EINVAL;
13218 + goto return_kfree;
13219 + }
13220 +
13221 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
13222 + if (_errno) {
13223 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
13224 + _errno = -EINVAL;
13225 + goto return_kfree;
13226 + }
13227 +
13228 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
13229 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
13230 +
13231 + bpool_cfg = of_get_property(bpool_node,
13232 + "fsl,bpool-ethernet-cfg", &lenp);
13233 + if (bpool_cfg == NULL) {
13234 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
13235 + _errno = -EINVAL;
13236 + goto return_kfree;
13237 + }
13238 +
13239 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
13240 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
13241 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
13242 + ext_pool_size);
13243 + of_node_put(bpool_node);
13244 +
13245 + }
13246 +
13247 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
13248 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
13249 + goto init_port;
13250 +
13251 + frag_enabled = true;
13252 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
13253 + port_id);
13254 +
13255 +init_port:
13256 + of_node_put(oh_node);
13257 + /* Set Tx params */
13258 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
13259 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
13260 + frag_enabled);
13261 + /* Set PCD params */
13262 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
13263 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
13264 + oh_port_pcd_params.dev = dpa_oh_dev;
13265 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
13266 +
13267 + dev_set_drvdata(dpa_oh_dev, oh_config);
13268 +
13269 + /* Enable the OH port */
13270 + _errno = fm_port_enable(oh_config->oh_port);
13271 + if (_errno)
13272 + goto return_kfree;
13273 +
13274 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
13275 +
13276 + /* print of all referenced & created queues */
13277 + dump_oh_config(dpa_oh_dev, oh_config);
13278 +
13279 + return 0;
13280 +
13281 +return_kfree:
13282 + if (bpool_node)
13283 + of_node_put(bpool_node);
13284 + if (oh_node)
13285 + of_node_put(oh_node);
13286 + if (oh_config && oh_config->egress_fqs)
13287 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
13288 +
13289 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
13290 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13291 + list_del(fq_list);
13292 + devm_kfree(dpa_oh_dev, fqd->fqs);
13293 + devm_kfree(dpa_oh_dev, fqd);
13294 + }
13295 +
13296 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
13297 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13298 + list_del(fq_list);
13299 + devm_kfree(dpa_oh_dev, fqd->fqs);
13300 + devm_kfree(dpa_oh_dev, fqd);
13301 + }
13302 +
13303 + devm_kfree(dpa_oh_dev, oh_config);
13304 + return _errno;
13305 +}
13306 +
13307 +static int __cold oh_port_remove(struct platform_device *_of_dev)
13308 +{
13309 + int _errno = 0, i;
13310 + struct dpa_oh_config_s *oh_config;
13311 +
13312 + pr_info("Removing OH port...\n");
13313 +
13314 + oh_config = dev_get_drvdata(&_of_dev->dev);
13315 + if (oh_config == NULL) {
13316 + pr_err(KBUILD_MODNAME
13317 + ": %s:%hu:%s(): No OH config in device private data!\n",
13318 + KBUILD_BASENAME".c", __LINE__, __func__);
13319 + _errno = -ENODEV;
13320 + goto return_error;
13321 + }
13322 +
13323 + if (oh_config->egress_fqs)
13324 + for (i = 0; i < oh_config->egress_cnt; i++)
13325 + oh_fq_destroy(oh_config->egress_fqs + i);
13326 +
13327 + if (oh_config->oh_port == NULL) {
13328 + pr_err(KBUILD_MODNAME
13329 + ": %s:%hu:%s(): No fm port in device private data!\n",
13330 + KBUILD_BASENAME".c", __LINE__, __func__);
13331 + _errno = -EINVAL;
13332 + goto free_egress_fqs;
13333 + }
13334 +
13335 + _errno = fm_port_disable(oh_config->oh_port);
13336 +
13337 +free_egress_fqs:
13338 + if (oh_config->egress_fqs)
13339 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
13340 + devm_kfree(&_of_dev->dev, oh_config);
13341 + dev_set_drvdata(&_of_dev->dev, NULL);
13342 +
13343 +return_error:
13344 + return _errno;
13345 +}
13346 +
13347 +static struct platform_driver oh_port_driver = {
13348 + .driver = {
13349 + .name = KBUILD_MODNAME,
13350 + .of_match_table = oh_port_match_table,
13351 + .owner = THIS_MODULE,
13352 + .pm = OH_PM_OPS,
13353 + },
13354 + .probe = oh_port_probe,
13355 + .remove = oh_port_remove
13356 +};
13357 +
13358 +static int __init __cold oh_port_load(void)
13359 +{
13360 + int _errno;
13361 +
13362 + pr_info(OH_MOD_DESCRIPTION "\n");
13363 +
13364 + _errno = platform_driver_register(&oh_port_driver);
13365 + if (_errno < 0) {
13366 + pr_err(KBUILD_MODNAME
13367 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
13368 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13369 + }
13370 +
13371 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13372 + KBUILD_BASENAME".c", __func__);
13373 + return _errno;
13374 +}
13375 +module_init(oh_port_load);
13376 +
13377 +static void __exit __cold oh_port_unload(void)
13378 +{
13379 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13380 + KBUILD_BASENAME".c", __func__);
13381 +
13382 + platform_driver_unregister(&oh_port_driver);
13383 +
13384 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13385 + KBUILD_BASENAME".c", __func__);
13386 +}
13387 +module_exit(oh_port_unload);
13388 --- /dev/null
13389 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13390 @@ -0,0 +1,59 @@
13391 +/* Copyright 2011 Freescale Semiconductor Inc.
13392 + *
13393 + * Redistribution and use in source and binary forms, with or without
13394 + * modification, are permitted provided that the following conditions are met:
13395 + * * Redistributions of source code must retain the above copyright
13396 + * notice, this list of conditions and the following disclaimer.
13397 + * * Redistributions in binary form must reproduce the above copyright
13398 + * notice, this list of conditions and the following disclaimer in the
13399 + * documentation and/or other materials provided with the distribution.
13400 + * * Neither the name of Freescale Semiconductor nor the
13401 + * names of its contributors may be used to endorse or promote products
13402 + * derived from this software without specific prior written permission.
13403 + *
13404 + *
13405 + * ALTERNATIVELY, this software may be distributed under the terms of the
13406 + * GNU General Public License ("GPL") as published by the Free Software
13407 + * Foundation, either version 2 of that License or (at your option) any
13408 + * later version.
13409 + *
13410 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13411 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13412 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13413 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13414 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13415 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13416 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13417 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13418 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13419 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13420 + */
13421 +
13422 +#ifndef __OFFLINE_PORT_H
13423 +#define __OFFLINE_PORT_H
13424 +
13425 +struct fm_port;
13426 +struct qman_fq;
13427 +
13428 +/* fqs are defined in duples (base_fq, fq_count) */
13429 +struct fq_duple {
13430 + struct qman_fq *fqs;
13431 + int fqs_count;
13432 + uint16_t channel_id;
13433 + struct list_head fq_list;
13434 +};
13435 +
13436 +/* OH port configuration */
13437 +struct dpa_oh_config_s {
13438 + uint32_t error_fqid;
13439 + uint32_t default_fqid;
13440 + struct fm_port *oh_port;
13441 + uint32_t egress_cnt;
13442 + struct qman_fq *egress_fqs;
13443 + uint16_t channel;
13444 +
13445 + struct list_head fqs_ingress_list;
13446 + struct list_head fqs_egress_list;
13447 +};
13448 +
13449 +#endif /* __OFFLINE_PORT_H */
13450 --- /dev/null
13451 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13452 @@ -0,0 +1,153 @@
13453 +menu "Frame Manager support"
13454 +
13455 +menuconfig FSL_SDK_FMAN
13456 + bool "Freescale Frame Manager (datapath) support - SDK driver"
13457 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
13458 + default y
13459 + ---help---
13460 + If unsure, say Y.
13461 +
13462 +if FSL_SDK_FMAN
13463 +
13464 +config FSL_SDK_FMAN_TEST
13465 + bool "FMan test module"
13466 + default n
13467 + select FSL_DPAA_HOOKS
13468 + ---help---
13469 + This option compiles test code for FMan.
13470 +
13471 +menu "FMAN Processor support"
13472 +choice
13473 + depends on FSL_SDK_FMAN
13474 + prompt "Processor Type"
13475 +
13476 +config FMAN_ARM
13477 + bool "LS1043"
13478 + depends on ARM64 || ARM
13479 + ---help---
13480 + Choose "LS1043" for the ARM platforms:
13481 + LS1043
13482 +
13483 +config FMAN_P3040_P4080_P5020
13484 + bool "P3040 P4080 5020"
13485 +
13486 +config FMAN_P1023
13487 + bool "P1023"
13488 +
13489 +config FMAN_V3H
13490 + bool "FmanV3H"
13491 + ---help---
13492 + Choose "FmanV3H" for Fman rev3H:
13493 + B4860, T4240, T4160, etc
13494 +
13495 +config FMAN_V3L
13496 + bool "FmanV3L"
13497 + ---help---
13498 + Choose "FmanV3L" for Fman rev3L:
13499 + T1040, T1042, T1020, T1022, T1023, T1024, etc
13500 +
13501 +endchoice
13502 +endmenu
13503 +
13504 +config FMAN_MIB_CNT_OVF_IRQ_EN
13505 + bool "Enable the dTSEC MIB counters overflow interrupt"
13506 + default n
13507 + ---help---
13508 + Enable the dTSEC MIB counters overflow interrupt to get
13509 + accurate MIB counters values. Enabled it compensates
13510 + for the counters overflow but reduces performance and
13511 + triggers error messages in HV setups.
13512 +
13513 +config FSL_FM_MAX_FRAME_SIZE
13514 + int "Maximum L2 frame size"
13515 + depends on FSL_SDK_FMAN
13516 + range 64 9600
13517 + default "1522"
13518 + help
13519 + Configure this in relation to the maximum possible MTU of your
13520 + network configuration. In particular, one would need to
13521 + increase this value in order to use jumbo frames.
13522 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
13523 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
13524 + excess of the desired L3 MTU.
13525 +
13526 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
13527 + than the actual MTU) may lead to buffer exhaustion, especially
13528 + in the case of badly fragmented datagrams on the Rx path.
13529 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
13530 + MTU will lead to frames being dropped.
13531 +
13532 + This can be overridden by specifying "fsl_fm_max_frm" in
13533 + the kernel bootargs:
13534 + * in Hypervisor-based scenarios, by adding a "chosen" node
13535 + with the "bootargs" property specifying
13536 + "fsl_fm_max_frm=<YourValue>";
13537 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13538 + modifying the "bootargs" env variable.
13539 +
13540 +config FSL_FM_RX_EXTRA_HEADROOM
13541 + int "Add extra headroom at beginning of data buffers"
13542 + depends on FSL_SDK_FMAN
13543 + range 16 384
13544 + default "64"
13545 + help
13546 + Configure this to tell the Frame Manager to reserve some extra
13547 + space at the beginning of a data buffer on the receive path,
13548 + before Internal Context fields are copied. This is in addition
13549 + to the private data area already reserved for driver internal
13550 + use. The provided value must be a multiple of 16.
13551 +
13552 + This setting can be overridden by specifying
13553 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
13554 + * in Hypervisor-based scenarios, by adding a "chosen" node
13555 + with the "bootargs" property specifying
13556 + "fsl_fm_rx_extra_headroom=<YourValue>";
13557 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13558 + modifying the "bootargs" env variable.
13559 +
13560 +config FMAN_PFC
13561 + bool "FMan PFC support (EXPERIMENTAL)"
13562 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
13563 + default n
13564 + help
13565 + This option enables PFC support on FMan v3 ports.
13566 + Data Center Bridging defines Classes of Service that are
13567 + flow-controlled using PFC pause frames.
13568 +
13569 +if FMAN_PFC
13570 +config FMAN_PFC_COS_COUNT
13571 + int "Number of PFC Classes of Service"
13572 + depends on FMAN_PFC && FSL_SDK_FMAN
13573 + range 1 4
13574 + default "3"
13575 + help
13576 + The number of Classes of Service controlled by PFC.
13577 +
13578 +config FMAN_PFC_QUANTA_0
13579 + int "The pause quanta for PFC CoS 0"
13580 + depends on FMAN_PFC && FSL_SDK_FMAN
13581 + range 0 65535
13582 + default "65535"
13583 +
13584 +config FMAN_PFC_QUANTA_1
13585 + int "The pause quanta for PFC CoS 1"
13586 + depends on FMAN_PFC && FSL_SDK_FMAN
13587 + range 0 65535
13588 + default "65535"
13589 +
13590 +config FMAN_PFC_QUANTA_2
13591 + int "The pause quanta for PFC CoS 2"
13592 + depends on FMAN_PFC && FSL_SDK_FMAN
13593 + range 0 65535
13594 + default "65535"
13595 +
13596 +config FMAN_PFC_QUANTA_3
13597 + int "The pause quanta for PFC CoS 3"
13598 + depends on FMAN_PFC && FSL_SDK_FMAN
13599 + range 0 65535
13600 + default "65535"
13601 +endif
13602 +
13603 +endif # FSL_SDK_FMAN
13604 +
13605 +endmenu
13606 --- /dev/null
13607 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13608 @@ -0,0 +1,11 @@
13609 +#
13610 +# Makefile for the Freescale Ethernet controllers
13611 +#
13612 +ccflags-y += -DVERSION=\"\"
13613 +#
13614 +#Include netcomm SW specific definitions
13615 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13616 +#
13617 +obj-y += etc/
13618 +obj-y += Peripherals/FM/
13619 +obj-y += src/
13620 --- /dev/null
13621 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13622 @@ -0,0 +1,15 @@
13623 +#
13624 +# Makefile for the Freescale Ethernet controllers
13625 +#
13626 +ccflags-y += -DVERSION=\"\"
13627 +#
13628 +#Include netcomm SW specific definitions
13629 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13630 +
13631 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
13632 +
13633 +ccflags-y += -I$(NCSW_FM_INC)
13634 +
13635 +obj-y += fsl-ncsw-Hc.o
13636 +
13637 +fsl-ncsw-Hc-objs := hc.o
13638 --- /dev/null
13639 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13640 @@ -0,0 +1,1232 @@
13641 +/*
13642 + * Copyright 2008-2012 Freescale Semiconductor Inc.
13643 + *
13644 + * Redistribution and use in source and binary forms, with or without
13645 + * modification, are permitted provided that the following conditions are met:
13646 + * * Redistributions of source code must retain the above copyright
13647 + * notice, this list of conditions and the following disclaimer.
13648 + * * Redistributions in binary form must reproduce the above copyright
13649 + * notice, this list of conditions and the following disclaimer in the
13650 + * documentation and/or other materials provided with the distribution.
13651 + * * Neither the name of Freescale Semiconductor nor the
13652 + * names of its contributors may be used to endorse or promote products
13653 + * derived from this software without specific prior written permission.
13654 + *
13655 + *
13656 + * ALTERNATIVELY, this software may be distributed under the terms of the
13657 + * GNU General Public License ("GPL") as published by the Free Software
13658 + * Foundation, either version 2 of that License or (at your option) any
13659 + * later version.
13660 + *
13661 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13662 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13663 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13664 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13665 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13666 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13667 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13668 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13669 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13670 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13671 + */
13672 +
13673 +
13674 +#include "std_ext.h"
13675 +#include "error_ext.h"
13676 +#include "sprint_ext.h"
13677 +#include "string_ext.h"
13678 +
13679 +#include "fm_common.h"
13680 +#include "fm_hc.h"
13681 +
13682 +
13683 +/**************************************************************************//**
13684 + @Description defaults
13685 +*//***************************************************************************/
13686 +#define DEFAULT_dataMemId 0
13687 +
13688 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
13689 +#define HC_HCOR_OPCODE_KG_SCM 0x1
13690 +#define HC_HCOR_OPCODE_SYNC 0x2
13691 +#define HC_HCOR_OPCODE_CC 0x3
13692 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
13693 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
13694 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
13695 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
13696 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
13697 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
13698 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
13699 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
13700 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
13701 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
13702 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
13703 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
13704 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
13705 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
13706 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
13707 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
13708 +
13709 +#define HC_HCOR_GBL 0x20000000
13710 +
13711 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
13712 +
13713 +#if (DPAA_VERSION == 10)
13714 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
13715 +#else
13716 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
13717 +#endif /* (DPAA_VERSION == 10) */
13718 +
13719 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
13720 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
13721 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
13722 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
13723 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
13724 +
13725 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
13726 +
13727 +#define BUILD_FD(len) \
13728 +do { \
13729 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
13730 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
13731 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
13732 + DPAA_FD_SET_LENGTH(&fmFd, len); \
13733 +} while (0)
13734 +
13735 +
13736 +#if defined(__MWERKS__) && !defined(__GNUC__)
13737 +#pragma pack(push,1)
13738 +#endif /* defined(__MWERKS__) && ... */
13739 +
13740 +typedef struct t_FmPcdKgPortRegs {
13741 + volatile uint32_t spReg;
13742 + volatile uint32_t cppReg;
13743 +} t_FmPcdKgPortRegs;
13744 +
13745 +typedef struct t_HcFrame {
13746 + volatile uint32_t opcode;
13747 + volatile uint32_t actionReg;
13748 + volatile uint32_t extraReg;
13749 + volatile uint32_t commandSequence;
13750 + union {
13751 + struct fman_kg_scheme_regs schemeRegs;
13752 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
13753 + t_FmPcdPlcrProfileRegs profileRegs;
13754 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
13755 + t_FmPcdKgPortRegs portRegsForRead;
13756 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
13757 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
13758 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
13759 + } hcSpecificData;
13760 +} t_HcFrame;
13761 +
13762 +#if defined(__MWERKS__) && !defined(__GNUC__)
13763 +#pragma pack(pop)
13764 +#endif /* defined(__MWERKS__) && ... */
13765 +
13766 +
13767 +typedef struct t_FmHc {
13768 + t_Handle h_FmPcd;
13769 + t_Handle h_HcPortDev;
13770 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
13771 + t_Handle h_QmArg; /**< A handle to the QM module */
13772 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
13773 +
13774 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
13775 + taking buffer */
13776 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
13777 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
13778 + and not confirmed yet */
13779 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
13780 +} t_FmHc;
13781 +
13782 +
13783 +static t_Error FillBufPool(t_FmHc *p_FmHc)
13784 +{
13785 + uint32_t i;
13786 +
13787 + ASSERT_COND(p_FmHc);
13788 +
13789 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13790 + {
13791 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
13792 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
13793 + p_FmHc->dataMemId,
13794 + 16);
13795 +#else
13796 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
13797 + p_FmHc->dataMemId,
13798 + 16);
13799 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
13800 + if (!p_FmHc->p_Frm[i])
13801 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
13802 + }
13803 +
13804 + /* Initialize FIFO of seqNum to use during GetBuf */
13805 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13806 + {
13807 + p_FmHc->seqNum[i] = i;
13808 + }
13809 + p_FmHc->nextSeqNumLocation = 0;
13810 +
13811 + return E_OK;
13812 +}
13813 +
13814 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
13815 +{
13816 + uint32_t intFlags;
13817 +
13818 + ASSERT_COND(p_FmHc);
13819 +
13820 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13821 +
13822 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
13823 + {
13824 + /* No more buffers */
13825 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13826 + return NULL;
13827 + }
13828 +
13829 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
13830 + p_FmHc->nextSeqNumLocation++;
13831 +
13832 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13833 + return p_FmHc->p_Frm[*p_SeqNum];
13834 +}
13835 +
13836 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
13837 +{
13838 + uint32_t intFlags;
13839 +
13840 + UNUSED(p_Buf);
13841 +
13842 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13843 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
13844 + p_FmHc->nextSeqNumLocation--;
13845 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
13846 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13847 +}
13848 +
13849 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
13850 +{
13851 + t_Error err = E_OK;
13852 + uint32_t intFlags;
13853 + uint32_t timeout=100;
13854 +
13855 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
13856 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
13857 + p_FmHc->enqueued[seqNum] = TRUE;
13858 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
13859 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
13860 + seqNum,
13861 + DPAA_FD_GET_ADDR(p_FmFd),
13862 + DPAA_FD_GET_OFFSET(p_FmFd)));
13863 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
13864 + if (err)
13865 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
13866 +
13867 + while (p_FmHc->enqueued[seqNum] && --timeout)
13868 + XX_UDelay(100);
13869 +
13870 + if (!timeout)
13871 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
13872 +
13873 + return err;
13874 +}
13875 +
13876 +
13877 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
13878 +{
13879 + t_FmHc *p_FmHc;
13880 + t_FmPortParams fmPortParam;
13881 + t_Error err;
13882 +
13883 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
13884 + if (!p_FmHc)
13885 + {
13886 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
13887 + return NULL;
13888 + }
13889 + memset(p_FmHc,0,sizeof(t_FmHc));
13890 +
13891 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
13892 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
13893 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
13894 + p_FmHc->dataMemId = DEFAULT_dataMemId;
13895 +
13896 + err = FillBufPool(p_FmHc);
13897 + if (err != E_OK)
13898 + {
13899 + REPORT_ERROR(MAJOR, err, NO_MSG);
13900 + FmHcFree(p_FmHc);
13901 + return NULL;
13902 + }
13903 +
13904 + if (!FmIsMaster(p_FmHcParams->h_Fm))
13905 + return (t_Handle)p_FmHc;
13906 +
13907 + memset(&fmPortParam, 0, sizeof(fmPortParam));
13908 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
13909 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
13910 + fmPortParam.portId = p_FmHcParams->params.portId;
13911 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
13912 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
13913 +
13914 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
13915 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
13916 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
13917 +
13918 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
13919 + if (!p_FmHc->h_HcPortDev)
13920 + {
13921 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
13922 + XX_Free(p_FmHc);
13923 + return NULL;
13924 + }
13925 +
13926 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
13927 + (uint16_t)sizeof(t_HcFrame));
13928 +
13929 + if (err != E_OK)
13930 + {
13931 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
13932 + FmHcFree(p_FmHc);
13933 + return NULL;
13934 + }
13935 +
13936 + /* final init */
13937 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
13938 + if (err != E_OK)
13939 + {
13940 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
13941 + FmHcFree(p_FmHc);
13942 + return NULL;
13943 + }
13944 +
13945 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
13946 + if (err != E_OK)
13947 + {
13948 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
13949 + FmHcFree(p_FmHc);
13950 + return NULL;
13951 + }
13952 +
13953 + return (t_Handle)p_FmHc;
13954 +}
13955 +
13956 +void FmHcFree(t_Handle h_FmHc)
13957 +{
13958 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13959 + int i;
13960 +
13961 + if (!p_FmHc)
13962 + return;
13963 +
13964 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
13965 + if (p_FmHc->p_Frm[i])
13966 + XX_FreeSmart(p_FmHc->p_Frm[i]);
13967 + else
13968 + break;
13969 +
13970 + if (p_FmHc->h_HcPortDev)
13971 + FM_PORT_Free(p_FmHc->h_HcPortDev);
13972 +
13973 + XX_Free(p_FmHc);
13974 +}
13975 +
13976 +/*****************************************************************************/
13977 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
13978 + uint8_t memId)
13979 +{
13980 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13981 + int i;
13982 +
13983 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
13984 +
13985 + p_FmHc->dataMemId = memId;
13986 +
13987 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
13988 + if (p_FmHc->p_Frm[i])
13989 + XX_FreeSmart(p_FmHc->p_Frm[i]);
13990 +
13991 + return FillBufPool(p_FmHc);
13992 +}
13993 +
13994 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
13995 +{
13996 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
13997 + t_HcFrame *p_HcFrame;
13998 + uint32_t intFlags;
13999 +
14000 + ASSERT_COND(p_FmHc);
14001 +
14002 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14003 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
14004 +
14005 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
14006 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
14007 +
14008 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
14009 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
14010 + else
14011 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
14012 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14013 +}
14014 +
14015 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
14016 + t_Handle h_Scheme,
14017 + struct fman_kg_scheme_regs *p_SchemeRegs,
14018 + bool updateCounter)
14019 +{
14020 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14021 + t_Error err = E_OK;
14022 + t_HcFrame *p_HcFrame;
14023 + t_DpaaFD fmFd;
14024 + uint8_t physicalSchemeId;
14025 + uint32_t seqNum;
14026 +
14027 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14028 + if (!p_HcFrame)
14029 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14030 +
14031 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14032 +
14033 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14034 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14035 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
14036 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14037 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
14038 + if (!updateCounter)
14039 + {
14040 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
14041 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
14042 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
14043 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
14044 + }
14045 + p_HcFrame->commandSequence = seqNum;
14046 +
14047 + BUILD_FD(sizeof(t_HcFrame));
14048 +
14049 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14050 +
14051 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14052 +
14053 + if (err != E_OK)
14054 + RETURN_ERROR(MINOR, err, NO_MSG);
14055 +
14056 + return E_OK;
14057 +}
14058 +
14059 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
14060 +{
14061 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14062 + t_Error err = E_OK;
14063 + t_HcFrame *p_HcFrame;
14064 + t_DpaaFD fmFd;
14065 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14066 + uint32_t seqNum;
14067 +
14068 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14069 + if (!p_HcFrame)
14070 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14071 +
14072 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14073 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14074 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14075 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14076 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
14077 + p_HcFrame->commandSequence = seqNum;
14078 +
14079 + BUILD_FD(sizeof(t_HcFrame));
14080 +
14081 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14082 +
14083 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14084 +
14085 + if (err != E_OK)
14086 + RETURN_ERROR(MINOR, err, NO_MSG);
14087 +
14088 + return E_OK;
14089 +}
14090 +
14091 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
14092 +{
14093 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14094 + t_Error err = E_OK;
14095 + t_HcFrame *p_HcFrame;
14096 + t_DpaaFD fmFd;
14097 + uint8_t relativeSchemeId;
14098 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14099 + uint32_t tmpReg32 = 0;
14100 + uint32_t seqNum;
14101 +
14102 + /* Scheme is locked by calling routine */
14103 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14104 + * "kgse_mode" or "kgse_om" without locking scheme !
14105 + */
14106 +
14107 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14108 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14109 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14110 +
14111 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
14112 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
14113 + {
14114 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14115 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
14116 + {
14117 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
14118 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
14119 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
14120 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
14121 + if (err)
14122 + RETURN_ERROR(MAJOR, err, NO_MSG);
14123 + }
14124 + else /* From here we deal with KG-Schemes only */
14125 + {
14126 + /* Pre change general code */
14127 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14128 + if (!p_HcFrame)
14129 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14130 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14131 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14132 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14133 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14134 + p_HcFrame->commandSequence = seqNum;
14135 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14136 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14137 + {
14138 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14139 + RETURN_ERROR(MINOR, err, NO_MSG);
14140 + }
14141 +
14142 + /* specific change */
14143 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14144 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
14145 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
14146 + {
14147 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14148 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
14149 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14150 + }
14151 +
14152 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
14153 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
14154 + {
14155 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14156 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
14157 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
14158 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
14159 + }
14160 +
14161 + if (requiredAction & UPDATE_KG_OPT_MODE)
14162 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
14163 +
14164 + if (requiredAction & UPDATE_KG_NIA)
14165 + {
14166 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14167 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
14168 + tmpReg32 |= value;
14169 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
14170 + }
14171 +
14172 + /* Post change general code */
14173 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14174 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
14175 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14176 +
14177 + BUILD_FD(sizeof(t_HcFrame));
14178 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14179 +
14180 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14181 +
14182 + if (err != E_OK)
14183 + RETURN_ERROR(MINOR, err, NO_MSG);
14184 + }
14185 + }
14186 +
14187 + return E_OK;
14188 +}
14189 +
14190 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
14191 +{
14192 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14193 + t_Error err;
14194 + t_HcFrame *p_HcFrame;
14195 + t_DpaaFD fmFd;
14196 + uint32_t retVal;
14197 + uint8_t relativeSchemeId;
14198 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14199 + uint32_t seqNum;
14200 +
14201 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14202 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14203 + {
14204 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14205 + return 0;
14206 + }
14207 +
14208 + /* first read scheme and check that it is valid */
14209 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14210 + if (!p_HcFrame)
14211 + {
14212 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14213 + return 0;
14214 + }
14215 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14216 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14217 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14218 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14219 + p_HcFrame->commandSequence = seqNum;
14220 +
14221 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14222 +
14223 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14224 + if (err != E_OK)
14225 + {
14226 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14227 + REPORT_ERROR(MINOR, err, NO_MSG);
14228 + return 0;
14229 + }
14230 +
14231 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
14232 + {
14233 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14234 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
14235 + return 0;
14236 + }
14237 +
14238 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
14239 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14240 +
14241 + return retVal;
14242 +}
14243 +
14244 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
14245 +{
14246 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14247 + t_Error err = E_OK;
14248 + t_HcFrame *p_HcFrame;
14249 + t_DpaaFD fmFd;
14250 + uint8_t relativeSchemeId, physicalSchemeId;
14251 + uint32_t seqNum;
14252 +
14253 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14254 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14255 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14256 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14257 +
14258 + /* first read scheme and check that it is valid */
14259 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14260 + if (!p_HcFrame)
14261 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14262 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14263 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14264 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14265 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
14266 + /* write counter */
14267 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14268 + p_HcFrame->commandSequence = seqNum;
14269 +
14270 + BUILD_FD(sizeof(t_HcFrame));
14271 +
14272 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14273 +
14274 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14275 + return err;
14276 +}
14277 +
14278 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
14279 +{
14280 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14281 + t_HcFrame *p_HcFrame;
14282 + t_DpaaFD fmFd;
14283 + uint8_t i, idx;
14284 + uint32_t seqNum;
14285 + t_Error err = E_OK;
14286 +
14287 + ASSERT_COND(p_FmHc);
14288 +
14289 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14290 + if (!p_HcFrame)
14291 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14292 +
14293 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
14294 + {
14295 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14296 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14297 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
14298 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14299 +
14300 + idx = (uint8_t)(i - p_Set->baseEntry);
14301 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
14302 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
14303 + p_HcFrame->commandSequence = seqNum;
14304 +
14305 + BUILD_FD(sizeof(t_HcFrame));
14306 +
14307 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14308 + {
14309 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14310 + RETURN_ERROR(MINOR, err, NO_MSG);
14311 + }
14312 + }
14313 +
14314 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14315 + return err;
14316 +}
14317 +
14318 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
14319 +{
14320 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14321 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
14322 +
14323 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
14324 + if (!p_ClsPlanSet)
14325 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
14326 +
14327 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
14328 +
14329 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
14330 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
14331 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
14332 +
14333 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
14334 + {
14335 + XX_Free(p_ClsPlanSet);
14336 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
14337 + }
14338 +
14339 + XX_Free(p_ClsPlanSet);
14340 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
14341 +
14342 + return E_OK;
14343 +}
14344 +
14345 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
14346 +{
14347 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14348 + t_HcFrame *p_HcFrame;
14349 + t_DpaaFD fmFd;
14350 + t_Error err;
14351 + uint32_t seqNum;
14352 +
14353 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14354 +
14355 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14356 + if (!p_HcFrame)
14357 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14358 +
14359 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14360 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
14361 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
14362 + p_HcFrame->commandSequence = seqNum;
14363 + BUILD_FD(sizeof(t_HcFrame));
14364 +
14365 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14366 +
14367 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14368 + return err;
14369 +}
14370 +
14371 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
14372 +{
14373 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14374 + t_HcFrame *p_HcFrame;
14375 + t_DpaaFD fmFd;
14376 + t_Error err;
14377 + uint32_t seqNum;
14378 +
14379 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14380 +
14381 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14382 + if (!p_HcFrame)
14383 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14384 +
14385 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14386 +
14387 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
14388 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
14389 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
14390 + if (fill == TRUE)
14391 + {
14392 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
14393 + }
14394 + p_HcFrame->commandSequence = seqNum;
14395 +
14396 + BUILD_FD(sizeof(t_HcFrame));
14397 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14398 + {
14399 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14400 + RETURN_ERROR(MINOR, err, NO_MSG);
14401 + }
14402 +
14403 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
14404 +
14405 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14406 + return E_OK;
14407 +}
14408 +
14409 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
14410 +{
14411 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14412 + t_HcFrame *p_HcFrame;
14413 + t_DpaaFD fmFd;
14414 + t_Error err;
14415 + uint32_t seqNum;
14416 +
14417 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14418 +
14419 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14420 + if (!p_HcFrame)
14421 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14422 +
14423 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14424 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
14425 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
14426 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
14427 + p_HcFrame->commandSequence = seqNum;
14428 +
14429 + BUILD_FD(sizeof(t_HcFrame));
14430 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14431 + {
14432 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14433 + RETURN_ERROR(MINOR, err, NO_MSG);
14434 + }
14435 +
14436 + *p_Result = (uint8_t)
14437 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
14438 +
14439 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14440 + return E_OK;
14441 +}
14442 +
14443 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
14444 +{
14445 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14446 + t_HcFrame *p_HcFrame;
14447 + t_DpaaFD fmFd;
14448 + t_Error err;
14449 + uint32_t tmpReg32 = 0;
14450 + uint32_t requiredActionTmp, requiredActionFlag;
14451 + uint32_t seqNum;
14452 +
14453 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14454 +
14455 + /* Profile is locked by calling routine */
14456 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14457 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
14458 + */
14459 +
14460 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
14461 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
14462 +
14463 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
14464 + {
14465 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
14466 + {
14467 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14468 + if (!p_HcFrame)
14469 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14470 + /* first read scheme and check that it is valid */
14471 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14472 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14473 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14474 + p_HcFrame->extraReg = 0x00008000;
14475 + p_HcFrame->commandSequence = seqNum;
14476 +
14477 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14478 +
14479 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14480 + {
14481 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14482 + RETURN_ERROR(MINOR, err, NO_MSG);
14483 + }
14484 +
14485 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
14486 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14487 + {
14488 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14489 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
14490 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14491 + }
14492 +
14493 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14494 +
14495 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14496 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14497 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
14498 + p_HcFrame->extraReg = 0x00008000;
14499 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14500 +
14501 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14502 +
14503 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14504 + {
14505 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14506 + RETURN_ERROR(MINOR, err, NO_MSG);
14507 + }
14508 +
14509 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
14510 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14511 + {
14512 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14513 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14514 + }
14515 +
14516 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14517 +
14518 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14519 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14520 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
14521 + p_HcFrame->extraReg = 0x00008000;
14522 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14523 +
14524 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14525 +
14526 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14527 + {
14528 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14529 + RETURN_ERROR(MINOR, err, NO_MSG);
14530 + }
14531 +
14532 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
14533 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14534 + {
14535 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14536 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14537 + }
14538 +
14539 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14540 +
14541 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14542 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14543 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
14544 + p_HcFrame->extraReg = 0x00008000;
14545 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14546 +
14547 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14548 +
14549 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14550 + {
14551 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14552 + RETURN_ERROR(MINOR, err, NO_MSG);
14553 + }
14554 +
14555 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14556 + }
14557 + }
14558 +
14559 + return E_OK;
14560 +}
14561 +
14562 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
14563 +{
14564 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14565 + t_Error err = E_OK;
14566 + uint16_t profileIndx;
14567 + t_HcFrame *p_HcFrame;
14568 + t_DpaaFD fmFd;
14569 + uint32_t seqNum;
14570 +
14571 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14572 + if (!p_HcFrame)
14573 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14574 +
14575 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14576 +
14577 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14578 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14579 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
14580 + p_HcFrame->extraReg = 0x00008000;
14581 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
14582 + p_HcFrame->commandSequence = seqNum;
14583 +
14584 + BUILD_FD(sizeof(t_HcFrame));
14585 +
14586 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14587 +
14588 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14589 +
14590 + if (err != E_OK)
14591 + RETURN_ERROR(MINOR, err, NO_MSG);
14592 +
14593 + return E_OK;
14594 +}
14595 +
14596 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
14597 +{
14598 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14599 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14600 + t_Error err = E_OK;
14601 + t_HcFrame *p_HcFrame;
14602 + t_DpaaFD fmFd;
14603 + uint32_t seqNum;
14604 +
14605 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14606 + if (!p_HcFrame)
14607 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14608 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14609 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14610 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14611 + p_HcFrame->actionReg |= 0x00008000;
14612 + p_HcFrame->extraReg = 0x00008000;
14613 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
14614 + p_HcFrame->commandSequence = seqNum;
14615 +
14616 + BUILD_FD(sizeof(t_HcFrame));
14617 +
14618 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14619 +
14620 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14621 +
14622 + if (err != E_OK)
14623 + RETURN_ERROR(MINOR, err, NO_MSG);
14624 +
14625 + return E_OK;
14626 +}
14627 +
14628 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
14629 +{
14630 +
14631 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14632 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14633 + t_Error err = E_OK;
14634 + t_HcFrame *p_HcFrame;
14635 + t_DpaaFD fmFd;
14636 + uint32_t seqNum;
14637 +
14638 + /* first read scheme and check that it is valid */
14639 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14640 + if (!p_HcFrame)
14641 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14642 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14643 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14644 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14645 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
14646 + p_HcFrame->extraReg = 0x00008000;
14647 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14648 + p_HcFrame->commandSequence = seqNum;
14649 +
14650 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14651 +
14652 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14653 +
14654 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14655 +
14656 + if (err != E_OK)
14657 + RETURN_ERROR(MINOR, err, NO_MSG);
14658 +
14659 + return E_OK;
14660 +}
14661 +
14662 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
14663 +{
14664 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14665 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14666 + t_Error err;
14667 + t_HcFrame *p_HcFrame;
14668 + t_DpaaFD fmFd;
14669 + uint32_t retVal = 0;
14670 + uint32_t seqNum;
14671 +
14672 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14673 +
14674 + /* first read scheme and check that it is valid */
14675 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14676 + if (!p_HcFrame)
14677 + {
14678 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14679 + return 0;
14680 + }
14681 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14682 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14683 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14684 + p_HcFrame->extraReg = 0x00008000;
14685 + p_HcFrame->commandSequence = seqNum;
14686 +
14687 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14688 +
14689 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14690 + if (err != E_OK)
14691 + {
14692 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14693 + REPORT_ERROR(MINOR, err, NO_MSG);
14694 + return 0;
14695 + }
14696 +
14697 + switch (counter)
14698 + {
14699 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
14700 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
14701 + break;
14702 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
14703 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
14704 + break;
14705 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
14706 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
14707 + break;
14708 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
14709 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
14710 + break;
14711 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
14712 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
14713 + break;
14714 + default:
14715 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
14716 + }
14717 +
14718 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14719 + return retVal;
14720 +}
14721 +
14722 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
14723 +{
14724 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14725 + t_HcFrame *p_HcFrame;
14726 + t_DpaaFD fmFd;
14727 + t_Error err = E_OK;
14728 + uint32_t seqNum;
14729 +
14730 + ASSERT_COND(p_FmHc);
14731 +
14732 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14733 + if (!p_HcFrame)
14734 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14735 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14736 + /* first read SP register */
14737 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14738 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
14739 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14740 + p_HcFrame->commandSequence = seqNum;
14741 +
14742 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
14743 +
14744 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14745 + {
14746 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14747 + RETURN_ERROR(MINOR, err, NO_MSG);
14748 + }
14749 +
14750 + /* spReg is the first reg, so we can use it both for read and for write */
14751 + if (add)
14752 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
14753 + else
14754 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
14755 +
14756 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
14757 +
14758 + BUILD_FD(sizeof(t_HcFrame));
14759 +
14760 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14761 +
14762 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14763 +
14764 + if (err != E_OK)
14765 + RETURN_ERROR(MINOR, err, NO_MSG);
14766 +
14767 + return E_OK;
14768 +}
14769 +
14770 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
14771 +{
14772 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14773 + t_HcFrame *p_HcFrame;
14774 + t_DpaaFD fmFd;
14775 + t_Error err = E_OK;
14776 + uint32_t seqNum;
14777 +
14778 + ASSERT_COND(p_FmHc);
14779 +
14780 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14781 + if (!p_HcFrame)
14782 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14783 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14784 + /* first read SP register */
14785 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14786 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
14787 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14788 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
14789 + p_HcFrame->commandSequence = seqNum;
14790 +
14791 + BUILD_FD(sizeof(t_HcFrame));
14792 +
14793 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14794 +
14795 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14796 +
14797 + if (err != E_OK)
14798 + RETURN_ERROR(MINOR, err, NO_MSG);
14799 +
14800 + return E_OK;
14801 +}
14802 +
14803 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
14804 +{
14805 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14806 + t_HcFrame *p_HcFrame;
14807 + t_DpaaFD fmFd;
14808 + t_Error err = E_OK;
14809 + uint32_t seqNum;
14810 +
14811 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14812 +
14813 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14814 + if (!p_HcFrame)
14815 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14816 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14817 +
14818 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
14819 + p_HcFrame->actionReg = newAdAddrOffset;
14820 + p_HcFrame->actionReg |= 0xc0000000;
14821 + p_HcFrame->extraReg = oldAdAddrOffset;
14822 + p_HcFrame->commandSequence = seqNum;
14823 +
14824 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14825 +
14826 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14827 +
14828 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14829 +
14830 + if (err != E_OK)
14831 + RETURN_ERROR(MAJOR, err, NO_MSG);
14832 +
14833 + return E_OK;
14834 +}
14835 +
14836 +t_Error FmHcPcdSync(t_Handle h_FmHc)
14837 +{
14838 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14839 + t_HcFrame *p_HcFrame;
14840 + t_DpaaFD fmFd;
14841 + t_Error err = E_OK;
14842 + uint32_t seqNum;
14843 +
14844 + ASSERT_COND(p_FmHc);
14845 +
14846 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14847 + if (!p_HcFrame)
14848 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14849 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14850 + /* first read SP register */
14851 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
14852 + p_HcFrame->actionReg = 0;
14853 + p_HcFrame->extraReg = 0;
14854 + p_HcFrame->commandSequence = seqNum;
14855 +
14856 + BUILD_FD(sizeof(t_HcFrame));
14857 +
14858 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14859 +
14860 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14861 +
14862 + if (err != E_OK)
14863 + RETURN_ERROR(MINOR, err, NO_MSG);
14864 +
14865 + return E_OK;
14866 +}
14867 +
14868 +t_Handle FmHcGetPort(t_Handle h_FmHc)
14869 +{
14870 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14871 + return p_FmHc->h_HcPortDev;
14872 +}
14873 --- /dev/null
14874 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
14875 @@ -0,0 +1,28 @@
14876 +#
14877 +# Makefile for the Freescale Ethernet controllers
14878 +#
14879 +ccflags-y += -DVERSION=\"\"
14880 +#
14881 +#Include netcomm SW specific definitions
14882 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
14883 +
14884 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
14885 +
14886 +ccflags-y += -I$(NCSW_FM_INC)
14887 +
14888 +obj-y += fsl-ncsw-MAC.o
14889 +
14890 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
14891 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
14892 + fman_tgec.o fman_crc32.o
14893 +
14894 +ifeq ($(CONFIG_FMAN_V3H),y)
14895 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14896 +endif
14897 +ifeq ($(CONFIG_FMAN_V3L),y)
14898 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14899 +endif
14900 +ifeq ($(CONFIG_FMAN_ARM),y)
14901 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
14902 +endif
14903 +
14904 --- /dev/null
14905 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
14906 @@ -0,0 +1,1464 @@
14907 +/*
14908 + * Copyright 2008-2013 Freescale Semiconductor Inc.
14909 + *
14910 + * Redistribution and use in source and binary forms, with or without
14911 + * modification, are permitted provided that the following conditions are met:
14912 + * * Redistributions of source code must retain the above copyright
14913 + * notice, this list of conditions and the following disclaimer.
14914 + * * Redistributions in binary form must reproduce the above copyright
14915 + * notice, this list of conditions and the following disclaimer in the
14916 + * documentation and/or other materials provided with the distribution.
14917 + * * Neither the name of Freescale Semiconductor nor the
14918 + * names of its contributors may be used to endorse or promote products
14919 + * derived from this software without specific prior written permission.
14920 + *
14921 + *
14922 + * ALTERNATIVELY, this software may be distributed under the terms of the
14923 + * GNU General Public License ("GPL") as published by the Free Software
14924 + * Foundation, either version 2 of that License or (at your option) any
14925 + * later version.
14926 + *
14927 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14928 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14929 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14930 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14931 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14932 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14933 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14934 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14935 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14936 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14937 + */
14938 +
14939 +/******************************************************************************
14940 + @File dtsec.c
14941 +
14942 + @Description FMan dTSEC driver
14943 +*//***************************************************************************/
14944 +
14945 +#include "std_ext.h"
14946 +#include "error_ext.h"
14947 +#include "string_ext.h"
14948 +#include "xx_ext.h"
14949 +#include "endian_ext.h"
14950 +#include "debug_ext.h"
14951 +#include "crc_mac_addr_ext.h"
14952 +
14953 +#include "fm_common.h"
14954 +#include "dtsec.h"
14955 +#include "fsl_fman_dtsec.h"
14956 +#include "fsl_fman_dtsec_mii_acc.h"
14957 +
14958 +/*****************************************************************************/
14959 +/* Internal routines */
14960 +/*****************************************************************************/
14961 +
14962 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
14963 +{
14964 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
14965 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
14966 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
14967 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
14968 + if (p_Dtsec->addr == 0)
14969 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
14970 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
14971 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
14972 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
14973 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
14974 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
14975 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
14976 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
14977 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
14978 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
14979 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
14980 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
14981 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
14982 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
14983 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
14984 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
14985 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
14986 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
14987 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
14988 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
14989 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
14990 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
14991 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
14992 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
14993 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
14994 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
14995 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
14996 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
14997 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
14998 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
14999 +
15000 + /* If Auto negotiation process is disabled, need to */
15001 + /* Set up the PHY using the MII Management Interface */
15002 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
15003 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
15004 + if (!p_Dtsec->f_Exception)
15005 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
15006 + if (!p_Dtsec->f_Event)
15007 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
15008 +
15009 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
15010 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
15011 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
15012 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
15013 +
15014 + return E_OK;
15015 +}
15016 +
15017 +/* ......................................................................... */
15018 +
15019 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
15020 +{
15021 + uint32_t crc;
15022 +
15023 + /* CRC calculation */
15024 + GET_MAC_ADDR_CRC(ethAddr, crc);
15025 +
15026 + crc = GetMirror32(crc);
15027 +
15028 + return crc;
15029 +}
15030 +
15031 +/* ......................................................................... */
15032 +
15033 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
15034 +{
15035 + uint32_t car1, car2;
15036 +
15037 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
15038 +
15039 + if (car1)
15040 + {
15041 + if (car1 & CAR1_TR64)
15042 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
15043 + if (car1 & CAR1_TR127)
15044 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
15045 + if (car1 & CAR1_TR255)
15046 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
15047 + if (car1 & CAR1_TR511)
15048 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
15049 + if (car1 & CAR1_TRK1)
15050 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
15051 + if (car1 & CAR1_TRMAX)
15052 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
15053 + if (car1 & CAR1_TRMGV)
15054 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
15055 + if (car1 & CAR1_RBYT)
15056 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
15057 + if (car1 & CAR1_RPKT)
15058 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
15059 + if (car1 & CAR1_RMCA)
15060 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
15061 + if (car1 & CAR1_RBCA)
15062 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
15063 + if (car1 & CAR1_RXPF)
15064 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
15065 + if (car1 & CAR1_RALN)
15066 + p_Dtsec->internalStatistics.raln += VAL16BIT;
15067 + if (car1 & CAR1_RFLR)
15068 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
15069 + if (car1 & CAR1_RCDE)
15070 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
15071 + if (car1 & CAR1_RCSE)
15072 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
15073 + if (car1 & CAR1_RUND)
15074 + p_Dtsec->internalStatistics.rund += VAL16BIT;
15075 + if (car1 & CAR1_ROVR)
15076 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
15077 + if (car1 & CAR1_RFRG)
15078 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
15079 + if (car1 & CAR1_RJBR)
15080 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
15081 + if (car1 & CAR1_RDRP)
15082 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
15083 + }
15084 + if (car2)
15085 + {
15086 + if (car2 & CAR2_TFCS)
15087 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
15088 + if (car2 & CAR2_TBYT)
15089 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
15090 + if (car2 & CAR2_TPKT)
15091 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
15092 + if (car2 & CAR2_TMCA)
15093 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
15094 + if (car2 & CAR2_TBCA)
15095 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
15096 + if (car2 & CAR2_TXPF)
15097 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
15098 + if (car2 & CAR2_TDRP)
15099 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
15100 + }
15101 +}
15102 +
15103 +/* .............................................................................. */
15104 +
15105 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
15106 +{
15107 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15108 +
15109 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
15110 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
15111 +
15112 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
15113 +}
15114 +
15115 +/* .............................................................................. */
15116 +
15117 +static void DtsecIsr(t_Handle h_Dtsec)
15118 +{
15119 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15120 + uint32_t event;
15121 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15122 +
15123 + /* do not handle MDIO events */
15124 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
15125 +
15126 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
15127 +
15128 + fman_dtsec_ack_event(p_DtsecMemMap, event);
15129 +
15130 + if (event & DTSEC_IMASK_BREN)
15131 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
15132 + if (event & DTSEC_IMASK_RXCEN)
15133 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
15134 + if (event & DTSEC_IMASK_MSROEN)
15135 + UpdateStatistics(p_Dtsec);
15136 + if (event & DTSEC_IMASK_GTSCEN)
15137 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
15138 + if (event & DTSEC_IMASK_BTEN)
15139 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
15140 + if (event & DTSEC_IMASK_TXCEN)
15141 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
15142 + if (event & DTSEC_IMASK_TXEEN)
15143 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
15144 + if (event & DTSEC_IMASK_LCEN)
15145 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
15146 + if (event & DTSEC_IMASK_CRLEN)
15147 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
15148 + if (event & DTSEC_IMASK_XFUNEN)
15149 + {
15150 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
15151 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15152 + {
15153 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
15154 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
15155 + /* This is a read only regidter */
15156 +
15157 + /* b. Read and save the value of TPKT */
15158 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
15159 +
15160 + /* c. Read the register at dTSEC address offset 0x32C */
15161 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15162 +
15163 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
15164 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
15165 + {
15166 + /* If they are not equal, save the value of this register and wait for at least
15167 + * MAXFRM*16 ns */
15168 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
15169 + }
15170 +
15171 + /* e. Read and save TPKT again and read the register at dTSEC address offset
15172 + 0x32C again*/
15173 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
15174 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15175 +
15176 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
15177 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
15178 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
15179 + the transmit portion of the dTSEC controller is locked up and the user should
15180 + proceed to the recover sequence. */
15181 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
15182 + {
15183 + /* recover sequence */
15184 +
15185 + /* a.Write a 1 to RCTRL[GRS]*/
15186 +
15187 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
15188 +
15189 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
15190 + for (i = 0 ; i < 100 ; i++ )
15191 + {
15192 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15193 + break;
15194 + XX_UDelay(1);
15195 + }
15196 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15197 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
15198 + else
15199 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
15200 +
15201 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
15202 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
15203 +
15204 + /* d.Wait 4 Tx clocks (32 ns) */
15205 + XX_UDelay(1);
15206 +
15207 + /* e.Write a 0 to bit n of FM_RSTC. */
15208 + /* cleared by FMAN */
15209 + }
15210 + }
15211 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
15212 +
15213 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
15214 + }
15215 + if (event & DTSEC_IMASK_MAGEN)
15216 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
15217 + if (event & DTSEC_IMASK_GRSCEN)
15218 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
15219 + if (event & DTSEC_IMASK_TDPEEN)
15220 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
15221 + if (event & DTSEC_IMASK_RDPEEN)
15222 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
15223 +
15224 + /* - masked interrupts */
15225 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
15226 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
15227 +}
15228 +
15229 +static void DtsecMdioIsr(t_Handle h_Dtsec)
15230 +{
15231 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15232 + uint32_t event;
15233 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15234 +
15235 + event = GET_UINT32(p_DtsecMemMap->ievent);
15236 + /* handle only MDIO events */
15237 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
15238 + if (event)
15239 + {
15240 + event &= GET_UINT32(p_DtsecMemMap->imask);
15241 +
15242 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
15243 +
15244 + if (event & DTSEC_IMASK_MMRDEN)
15245 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
15246 + if (event & DTSEC_IMASK_MMWREN)
15247 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
15248 + }
15249 +}
15250 +
15251 +static void Dtsec1588Isr(t_Handle h_Dtsec)
15252 +{
15253 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15254 + uint32_t event;
15255 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15256 +
15257 + if (p_Dtsec->ptpTsuEnabled)
15258 + {
15259 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
15260 +
15261 + if (event)
15262 + {
15263 + ASSERT_COND(event & TMR_PEVENT_TSRE);
15264 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
15265 + }
15266 + }
15267 +}
15268 +
15269 +/* ........................................................................... */
15270 +
15271 +static void FreeInitResources(t_Dtsec *p_Dtsec)
15272 +{
15273 + if (p_Dtsec->mdioIrq != NO_IRQ)
15274 + {
15275 + XX_DisableIntr(p_Dtsec->mdioIrq);
15276 + XX_FreeIntr(p_Dtsec->mdioIrq);
15277 + }
15278 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
15279 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
15280 +
15281 + /* release the driver's group hash table */
15282 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
15283 + p_Dtsec->p_MulticastAddrHash = NULL;
15284 +
15285 + /* release the driver's individual hash table */
15286 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
15287 + p_Dtsec->p_UnicastAddrHash = NULL;
15288 +}
15289 +
15290 +/* ........................................................................... */
15291 +
15292 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
15293 +{
15294 + struct dtsec_regs *p_MemMap;
15295 +
15296 + ASSERT_COND(p_Dtsec);
15297 +
15298 + p_MemMap = p_Dtsec->p_MemMap;
15299 + ASSERT_COND(p_MemMap);
15300 +
15301 + /* Assert the graceful transmit stop bit */
15302 + if (mode & e_COMM_MODE_RX)
15303 + {
15304 + fman_dtsec_stop_rx(p_MemMap);
15305 +
15306 +#ifdef FM_GRS_ERRATA_DTSEC_A002
15307 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15308 + XX_UDelay(100);
15309 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
15310 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
15311 + XX_UDelay(10);
15312 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
15313 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
15314 + }
15315 +
15316 + if (mode & e_COMM_MODE_TX)
15317 +#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
15318 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15319 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
15320 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15321 +#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
15322 + DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
15323 +#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15324 + fman_dtsec_stop_tx(p_MemMap);
15325 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
15326 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
15327 +
15328 + return E_OK;
15329 +}
15330 +
15331 +/* .............................................................................. */
15332 +
15333 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
15334 +{
15335 + struct dtsec_regs *p_MemMap;
15336 +
15337 + ASSERT_COND(p_Dtsec);
15338 + p_MemMap = p_Dtsec->p_MemMap;
15339 + ASSERT_COND(p_MemMap);
15340 +
15341 + /* clear the graceful receive stop bit */
15342 + if (mode & e_COMM_MODE_TX)
15343 + fman_dtsec_start_tx(p_MemMap);
15344 +
15345 + if (mode & e_COMM_MODE_RX)
15346 + fman_dtsec_start_rx(p_MemMap);
15347 +
15348 + return E_OK;
15349 +}
15350 +
15351 +
15352 +/*****************************************************************************/
15353 +/* dTSEC Configs modification functions */
15354 +/*****************************************************************************/
15355 +
15356 +/* .............................................................................. */
15357 +
15358 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
15359 +{
15360 +
15361 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15362 +
15363 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15364 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15365 +
15366 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
15367 +
15368 + return E_OK;
15369 +}
15370 +
15371 +/* .............................................................................. */
15372 +
15373 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
15374 +{
15375 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15376 +
15377 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15378 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15379 +
15380 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
15381 +
15382 + return E_OK;
15383 +}
15384 +
15385 +/* .............................................................................. */
15386 +
15387 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
15388 +{
15389 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15390 +
15391 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15392 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15393 +
15394 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
15395 +
15396 + return E_OK;
15397 +}
15398 +
15399 +/* .............................................................................. */
15400 +
15401 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
15402 +{
15403 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15404 +
15405 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15406 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15407 +
15408 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
15409 +
15410 + return E_OK;
15411 +}
15412 +
15413 +/* .............................................................................. */
15414 +
15415 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
15416 +{
15417 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15418 +
15419 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15420 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15421 +
15422 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
15423 +
15424 + return E_OK;
15425 +}
15426 +
15427 +/* .............................................................................. */
15428 +
15429 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
15430 +{
15431 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15432 +
15433 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15434 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15435 +
15436 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
15437 +
15438 + return E_OK;
15439 +}
15440 +
15441 +/* .............................................................................. */
15442 +
15443 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
15444 +{
15445 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15446 + uint32_t bitMask = 0;
15447 +
15448 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15449 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15450 +
15451 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
15452 + {
15453 + GET_EXCEPTION_FLAG(bitMask, exception);
15454 + if (bitMask)
15455 + {
15456 + if (enable)
15457 + p_Dtsec->exceptions |= bitMask;
15458 + else
15459 + p_Dtsec->exceptions &= ~bitMask;
15460 + }
15461 + else
15462 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
15463 + }
15464 + else
15465 + {
15466 + if (!p_Dtsec->ptpTsuEnabled)
15467 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
15468 +
15469 + if (enable)
15470 + p_Dtsec->enTsuErrExeption = TRUE;
15471 + else
15472 + p_Dtsec->enTsuErrExeption = FALSE;
15473 + }
15474 +
15475 + return E_OK;
15476 +}
15477 +
15478 +
15479 +/*****************************************************************************/
15480 +/* dTSEC Run Time API functions */
15481 +/*****************************************************************************/
15482 +
15483 +/* .............................................................................. */
15484 +
15485 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
15486 +{
15487 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15488 +
15489 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15490 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15491 +
15492 + fman_dtsec_enable(p_Dtsec->p_MemMap,
15493 + (bool)!!(mode & e_COMM_MODE_RX),
15494 + (bool)!!(mode & e_COMM_MODE_TX));
15495 +
15496 + GracefulRestart(p_Dtsec, mode);
15497 +
15498 + return E_OK;
15499 +}
15500 +
15501 +/* .............................................................................. */
15502 +
15503 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
15504 +{
15505 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15506 +
15507 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15508 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15509 +
15510 + GracefulStop(p_Dtsec, mode);
15511 +
15512 + fman_dtsec_disable(p_Dtsec->p_MemMap,
15513 + (bool)!!(mode & e_COMM_MODE_RX),
15514 + (bool)!!(mode & e_COMM_MODE_TX));
15515 +
15516 + return E_OK;
15517 +}
15518 +
15519 +/* .............................................................................. */
15520 +
15521 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
15522 + uint8_t priority,
15523 + uint16_t pauseTime,
15524 + uint16_t threshTime)
15525 +{
15526 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15527 +
15528 + UNUSED(priority);UNUSED(threshTime);
15529 +
15530 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15531 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15532 +
15533 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
15534 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15535 + if (0 < pauseTime && pauseTime <= 320)
15536 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
15537 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
15538 + " value should be greater than 320."));
15539 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
15540 +
15541 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
15542 + return E_OK;
15543 +}
15544 +
15545 +/* .............................................................................. */
15546 +/* backward compatibility. will be removed in the future. */
15547 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
15548 +{
15549 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
15550 +}
15551 +
15552 +/* .............................................................................. */
15553 +
15554 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
15555 +{
15556 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15557 + bool accept_pause = !en;
15558 +
15559 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15560 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15561 +
15562 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
15563 +
15564 + return E_OK;
15565 +}
15566 +
15567 +/* .............................................................................. */
15568 +
15569 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
15570 +{
15571 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15572 +
15573 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15574 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15575 +
15576 + p_Dtsec->ptpTsuEnabled = TRUE;
15577 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
15578 +
15579 + return E_OK;
15580 +}
15581 +
15582 +/* .............................................................................. */
15583 +
15584 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
15585 +{
15586 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15587 +
15588 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15589 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15590 +
15591 + p_Dtsec->ptpTsuEnabled = FALSE;
15592 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
15593 +
15594 + return E_OK;
15595 +}
15596 +
15597 +/* .............................................................................. */
15598 +
15599 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
15600 +{
15601 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15602 + struct dtsec_regs *p_DtsecMemMap;
15603 +
15604 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15605 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15606 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
15607 +
15608 + p_DtsecMemMap = p_Dtsec->p_MemMap;
15609 +
15610 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
15611 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
15612 +
15613 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
15614 +
15615 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
15616 + {
15617 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
15618 + + p_Dtsec->internalStatistics.tr64;
15619 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
15620 + + p_Dtsec->internalStatistics.tr127;
15621 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
15622 + + p_Dtsec->internalStatistics.tr255;
15623 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
15624 + + p_Dtsec->internalStatistics.tr511;
15625 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
15626 + + p_Dtsec->internalStatistics.tr1k;
15627 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
15628 + + p_Dtsec->internalStatistics.trmax;
15629 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
15630 + + p_Dtsec->internalStatistics.trmgv;
15631 +
15632 + /* MIB II */
15633 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
15634 + + p_Dtsec->internalStatistics.rbyt;
15635 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
15636 + + p_Dtsec->internalStatistics.rpkt;
15637 + p_Statistics->ifInUcastPkts = 0;
15638 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
15639 + + p_Dtsec->internalStatistics.rmca;
15640 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
15641 + + p_Dtsec->internalStatistics.rbca;
15642 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
15643 + + p_Dtsec->internalStatistics.tbyt;
15644 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
15645 + + p_Dtsec->internalStatistics.tpkt;
15646 + p_Statistics->ifOutUcastPkts = 0;
15647 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
15648 + + p_Dtsec->internalStatistics.tmca;
15649 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
15650 + + p_Dtsec->internalStatistics.tbca;
15651 + }
15652 +
15653 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
15654 + + p_Dtsec->internalStatistics.rfrg;
15655 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
15656 + + p_Dtsec->internalStatistics.rjbr;
15657 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
15658 + + p_Dtsec->internalStatistics.rdrp;
15659 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
15660 + + p_Dtsec->internalStatistics.raln;
15661 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
15662 + + p_Dtsec->internalStatistics.rund;
15663 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
15664 + + p_Dtsec->internalStatistics.rovr;
15665 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
15666 + + p_Dtsec->internalStatistics.rxpf;
15667 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
15668 + + p_Dtsec->internalStatistics.txpf;
15669 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
15670 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
15671 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
15672 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
15673 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
15674 +
15675 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
15676 + + p_Dtsec->internalStatistics.tdrp;
15677 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
15678 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
15679 + + p_Dtsec->internalStatistics.tfcs;
15680 +
15681 + return E_OK;
15682 +}
15683 +
15684 +/* .............................................................................. */
15685 +
15686 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
15687 +{
15688 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15689 +
15690 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15691 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15692 +
15693 + /* Initialize MAC Station Address registers (1 & 2) */
15694 + /* Station address have to be swapped (big endian to little endian */
15695 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
15696 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
15697 +
15698 + return E_OK;
15699 +}
15700 +
15701 +/* .............................................................................. */
15702 +
15703 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
15704 +{
15705 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15706 +
15707 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15708 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15709 +
15710 + /* clear HW counters */
15711 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
15712 +
15713 + /* clear SW counters holding carries */
15714 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
15715 +
15716 + return E_OK;
15717 +}
15718 +
15719 +/* .............................................................................. */
15720 +
15721 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15722 +{
15723 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15724 + uint64_t ethAddr;
15725 + uint8_t paddrNum;
15726 +
15727 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15728 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15729 +
15730 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15731 +
15732 + if (ethAddr & GROUP_ADDRESS)
15733 + /* Multicast address has no effect in PADDR */
15734 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
15735 +
15736 + /* Make sure no PADDR contains this address */
15737 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15738 + if (p_Dtsec->indAddrRegUsed[paddrNum])
15739 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
15740 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
15741 +
15742 + /* Find first unused PADDR */
15743 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15744 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
15745 + {
15746 + /* mark this PADDR as used */
15747 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
15748 + /* store address */
15749 + p_Dtsec->paddr[paddrNum] = ethAddr;
15750 +
15751 + /* put in hardware */
15752 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
15753 + p_Dtsec->numOfIndAddrInRegs++;
15754 +
15755 + return E_OK;
15756 + }
15757 +
15758 + /* No free PADDR */
15759 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
15760 +}
15761 +
15762 +/* .............................................................................. */
15763 +
15764 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15765 +{
15766 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15767 + uint64_t ethAddr;
15768 + uint8_t paddrNum;
15769 +
15770 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15771 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15772 +
15773 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15774 +
15775 + /* Find used PADDR containing this address */
15776 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15777 + {
15778 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
15779 + (p_Dtsec->paddr[paddrNum] == ethAddr))
15780 + {
15781 + /* mark this PADDR as not used */
15782 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
15783 + /* clear in hardware */
15784 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
15785 + p_Dtsec->numOfIndAddrInRegs--;
15786 +
15787 + return E_OK;
15788 + }
15789 + }
15790 +
15791 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
15792 +}
15793 +
15794 +/* .............................................................................. */
15795 +
15796 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15797 +{
15798 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15799 + t_EthHashEntry *p_HashEntry;
15800 + uint64_t ethAddr;
15801 + int32_t bucket;
15802 + uint32_t crc;
15803 + bool mcast, ghtx;
15804 +
15805 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15806 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15807 +
15808 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15809 +
15810 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15811 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15812 +
15813 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15814 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15815 +
15816 + crc = GetMacAddrHashCode(ethAddr);
15817 +
15818 + /* considering the 9 highest order bits in crc H[8:0]:
15819 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
15820 + * and H[5:1] (next 5 bits) identify the hash bit
15821 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
15822 + * and H[4:0] (next 5 bits) identify the hash bit.
15823 + *
15824 + * In bucket index output the low 5 bits identify the hash register bit,
15825 + * while the higher 4 bits identify the hash register
15826 + */
15827 +
15828 + if (ghtx)
15829 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15830 + else {
15831 + bucket = (int32_t)((crc >> 24) & 0xff);
15832 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15833 + if (mcast)
15834 + bucket += 0x100;
15835 + }
15836 +
15837 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
15838 +
15839 + /* Create element to be added to the driver hash table */
15840 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
15841 + p_HashEntry->addr = ethAddr;
15842 + INIT_LIST(&p_HashEntry->node);
15843 +
15844 + if (ethAddr & MAC_GROUP_ADDRESS)
15845 + /* Group Address */
15846 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
15847 + else
15848 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
15849 +
15850 + return E_OK;
15851 +}
15852 +
15853 +/* .............................................................................. */
15854 +
15855 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15856 +{
15857 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15858 + t_List *p_Pos;
15859 + t_EthHashEntry *p_HashEntry = NULL;
15860 + uint64_t ethAddr;
15861 + int32_t bucket;
15862 + uint32_t crc;
15863 + bool mcast, ghtx;
15864 +
15865 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15866 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15867 +
15868 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15869 +
15870 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
15871 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
15872 +
15873 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
15874 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
15875 +
15876 + crc = GetMacAddrHashCode(ethAddr);
15877 +
15878 + if (ghtx)
15879 + bucket = (int32_t)((crc >> 23) & 0x1ff);
15880 + else {
15881 + bucket = (int32_t)((crc >> 24) & 0xff);
15882 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
15883 + if (mcast)
15884 + bucket += 0x100;
15885 + }
15886 +
15887 + if (ethAddr & MAC_GROUP_ADDRESS)
15888 + {
15889 + /* Group Address */
15890 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15891 + {
15892 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15893 + if (p_HashEntry->addr == ethAddr)
15894 + {
15895 + LIST_DelAndInit(&p_HashEntry->node);
15896 + XX_Free(p_HashEntry);
15897 + break;
15898 + }
15899 + }
15900 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
15901 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15902 + }
15903 + else
15904 + {
15905 + /* Individual Address */
15906 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15907 + {
15908 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
15909 + if (p_HashEntry->addr == ethAddr)
15910 + {
15911 + LIST_DelAndInit(&p_HashEntry->node);
15912 + XX_Free(p_HashEntry);
15913 + break;
15914 + }
15915 + }
15916 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
15917 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
15918 + }
15919 +
15920 + /* address does not exist */
15921 + ASSERT_COND(p_HashEntry != NULL);
15922 +
15923 + return E_OK;
15924 +}
15925 +
15926 +/* .............................................................................. */
15927 +
15928 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
15929 +{
15930 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15931 +
15932 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15933 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15934 +
15935 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
15936 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
15937 +
15938 + return E_OK;
15939 +}
15940 +
15941 +/* .............................................................................. */
15942 +
15943 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
15944 +{
15945 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15946 + t_Error err;
15947 +
15948 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15949 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15950 +
15951 + p_Dtsec->statisticsLevel = statisticsLevel;
15952 +
15953 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
15954 + (enum dtsec_stat_level)statisticsLevel);
15955 + if (err != E_OK)
15956 + return err;
15957 +
15958 + switch (statisticsLevel)
15959 + {
15960 + case (e_FM_MAC_NONE_STATISTICS):
15961 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
15962 + break;
15963 + case (e_FM_MAC_PARTIAL_STATISTICS):
15964 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
15965 + break;
15966 + case (e_FM_MAC_FULL_STATISTICS):
15967 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
15968 + break;
15969 + default:
15970 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
15971 + }
15972 +
15973 + return E_OK;
15974 +}
15975 +
15976 +/* .............................................................................. */
15977 +
15978 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
15979 +{
15980 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15981 +
15982 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15983 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15984 +
15985 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
15986 +
15987 + return E_OK;
15988 +}
15989 +
15990 +/* .............................................................................. */
15991 +
15992 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
15993 +{
15994 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15995 + int err;
15996 + enum enet_interface enet_interface;
15997 + enum enet_speed enet_speed;
15998 +
15999 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16000 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16001 +
16002 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
16003 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16004 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16005 + p_Dtsec->halfDuplex = !fullDuplex;
16006 +
16007 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
16008 +
16009 + if (err == -EINVAL)
16010 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
16011 +
16012 + return (t_Error)err;
16013 +}
16014 +
16015 +/* .............................................................................. */
16016 +
16017 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
16018 +{
16019 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16020 + uint16_t tmpReg16;
16021 +
16022 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16023 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16024 +
16025 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
16026 +
16027 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
16028 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16029 +
16030 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
16031 +
16032 + return E_OK;
16033 +}
16034 +
16035 +/* .............................................................................. */
16036 +
16037 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
16038 +{
16039 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
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 + *macId = p_Dtsec->macId;
16045 +
16046 + return E_OK;
16047 +}
16048 +
16049 +/* .............................................................................. */
16050 +
16051 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
16052 +{
16053 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16054 +
16055 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16056 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16057 +
16058 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
16059 +
16060 + return E_OK;
16061 +}
16062 +
16063 +/* .............................................................................. */
16064 +
16065 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16066 +{
16067 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16068 + uint32_t bitMask = 0;
16069 +
16070 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16071 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16072 +
16073 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16074 + {
16075 + GET_EXCEPTION_FLAG(bitMask, exception);
16076 + if (bitMask)
16077 + {
16078 + if (enable)
16079 + p_Dtsec->exceptions |= bitMask;
16080 + else
16081 + p_Dtsec->exceptions &= ~bitMask;
16082 + }
16083 + else
16084 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16085 +
16086 + if (enable)
16087 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
16088 + else
16089 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
16090 + }
16091 + else
16092 + {
16093 + if (!p_Dtsec->ptpTsuEnabled)
16094 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16095 +
16096 + if (enable)
16097 + {
16098 + p_Dtsec->enTsuErrExeption = TRUE;
16099 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
16100 + }
16101 + else
16102 + {
16103 + p_Dtsec->enTsuErrExeption = FALSE;
16104 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
16105 + }
16106 + }
16107 +
16108 + return E_OK;
16109 +}
16110 +
16111 +
16112 +/*****************************************************************************/
16113 +/* dTSEC Init & Free API */
16114 +/*****************************************************************************/
16115 +
16116 +/* .............................................................................. */
16117 +
16118 +static t_Error DtsecInit(t_Handle h_Dtsec)
16119 +{
16120 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16121 + struct dtsec_cfg *p_DtsecDriverParam;
16122 + t_Error err;
16123 + uint16_t maxFrmLn;
16124 + enum enet_interface enet_interface;
16125 + enum enet_speed enet_speed;
16126 + t_EnetAddr ethAddr;
16127 +
16128 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16129 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16130 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
16131 +
16132 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
16133 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
16134 +
16135 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
16136 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
16137 +
16138 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16139 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16140 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
16141 +
16142 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
16143 + p_DtsecDriverParam,
16144 + enet_interface,
16145 + enet_speed,
16146 + (uint8_t*)ethAddr,
16147 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
16148 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
16149 + p_Dtsec->exceptions);
16150 + if (err)
16151 + {
16152 + FreeInitResources(p_Dtsec);
16153 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
16154 + }
16155 +
16156 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
16157 + {
16158 + uint16_t tmpReg16;
16159 +
16160 + /* Configure the TBI PHY Control Register */
16161 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
16162 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16163 +
16164 + tmpReg16 = PHY_TBICON_CLK_SEL;
16165 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16166 +
16167 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16168 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16169 +
16170 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
16171 + tmpReg16 = PHY_TBIANA_1000X;
16172 + else
16173 + tmpReg16 = PHY_TBIANA_SGMII;
16174 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
16175 +
16176 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16177 +
16178 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16179 + }
16180 +
16181 + /* Max Frame Length */
16182 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16183 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
16184 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
16185 + if (err)
16186 + RETURN_ERROR(MINOR,err, NO_MSG);
16187 +
16188 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
16189 + if (!p_Dtsec->p_MulticastAddrHash) {
16190 + FreeInitResources(p_Dtsec);
16191 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
16192 + }
16193 +
16194 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
16195 + if (!p_Dtsec->p_UnicastAddrHash)
16196 + {
16197 + FreeInitResources(p_Dtsec);
16198 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
16199 + }
16200 +
16201 + /* register err intr handler for dtsec to FPM (err)*/
16202 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16203 + e_FM_MOD_1G_MAC,
16204 + p_Dtsec->macId,
16205 + e_FM_INTR_TYPE_ERR,
16206 + DtsecIsr,
16207 + p_Dtsec);
16208 + /* register 1588 intr handler for TMR to FPM (normal)*/
16209 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16210 + e_FM_MOD_1G_MAC,
16211 + p_Dtsec->macId,
16212 + e_FM_INTR_TYPE_NORMAL,
16213 + Dtsec1588Isr,
16214 + p_Dtsec);
16215 + /* register normal intr handler for dtsec to main interrupt controller. */
16216 + if (p_Dtsec->mdioIrq != NO_IRQ)
16217 + {
16218 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
16219 + XX_EnableIntr(p_Dtsec->mdioIrq);
16220 + }
16221 +
16222 + XX_Free(p_DtsecDriverParam);
16223 + p_Dtsec->p_DtsecDriverParam = NULL;
16224 +
16225 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
16226 + if (err)
16227 + {
16228 + FreeInitResources(p_Dtsec);
16229 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
16230 + }
16231 +
16232 + return E_OK;
16233 +}
16234 +
16235 +/* ........................................................................... */
16236 +
16237 +static t_Error DtsecFree(t_Handle h_Dtsec)
16238 +{
16239 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16240 +
16241 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16242 +
16243 + if (p_Dtsec->p_DtsecDriverParam)
16244 + {
16245 + /* Called after config */
16246 + XX_Free(p_Dtsec->p_DtsecDriverParam);
16247 + p_Dtsec->p_DtsecDriverParam = NULL;
16248 + }
16249 + else
16250 + /* Called after init */
16251 + FreeInitResources(p_Dtsec);
16252 +
16253 + XX_Free(p_Dtsec);
16254 +
16255 + return E_OK;
16256 +}
16257 +
16258 +/* .............................................................................. */
16259 +
16260 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
16261 +{
16262 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
16263 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
16264 +
16265 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
16266 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
16267 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
16268 +
16269 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
16270 +
16271 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
16272 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
16273 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
16274 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
16275 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
16276 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
16277 +
16278 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
16279 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
16280 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
16281 +
16282 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
16283 +
16284 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
16285 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
16286 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
16287 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
16288 +
16289 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
16290 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
16291 +
16292 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
16293 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
16294 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
16295 +
16296 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
16297 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
16298 +
16299 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
16300 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
16301 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
16302 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
16303 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
16304 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
16305 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
16306 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
16307 +
16308 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
16309 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
16310 +
16311 +}
16312 +
16313 +
16314 +/*****************************************************************************/
16315 +/* dTSEC Config Main Entry */
16316 +/*****************************************************************************/
16317 +
16318 +/* .............................................................................. */
16319 +
16320 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
16321 +{
16322 + t_Dtsec *p_Dtsec;
16323 + struct dtsec_cfg *p_DtsecDriverParam;
16324 + uintptr_t baseAddr;
16325 +
16326 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
16327 +
16328 + baseAddr = p_FmMacParam->baseAddr;
16329 +
16330 + /* allocate memory for the UCC GETH data structure. */
16331 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
16332 + if (!p_Dtsec)
16333 + {
16334 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
16335 + return NULL;
16336 + }
16337 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
16338 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
16339 +
16340 + /* allocate memory for the dTSEC driver parameters data structure. */
16341 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
16342 + if (!p_DtsecDriverParam)
16343 + {
16344 + XX_Free(p_Dtsec);
16345 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
16346 + return NULL;
16347 + }
16348 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
16349 +
16350 + /* Plant parameter structure pointer */
16351 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
16352 +
16353 + fman_dtsec_defconfig(p_DtsecDriverParam);
16354 +
16355 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
16356 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
16357 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
16358 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
16359 + p_Dtsec->macId = p_FmMacParam->macId;
16360 + p_Dtsec->exceptions = DEFAULT_exceptions;
16361 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
16362 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
16363 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
16364 + p_Dtsec->h_App = p_FmMacParam->h_App;
16365 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
16366 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
16367 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
16368 +
16369 + return p_Dtsec;
16370 +}
16371 --- /dev/null
16372 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16373 @@ -0,0 +1,228 @@
16374 +/*
16375 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16376 + *
16377 + * Redistribution and use in source and binary forms, with or without
16378 + * modification, are permitted provided that the following conditions are met:
16379 + * * Redistributions of source code must retain the above copyright
16380 + * notice, this list of conditions and the following disclaimer.
16381 + * * Redistributions in binary form must reproduce the above copyright
16382 + * notice, this list of conditions and the following disclaimer in the
16383 + * documentation and/or other materials provided with the distribution.
16384 + * * Neither the name of Freescale Semiconductor nor the
16385 + * names of its contributors may be used to endorse or promote products
16386 + * derived from this software without specific prior written permission.
16387 + *
16388 + *
16389 + * ALTERNATIVELY, this software may be distributed under the terms of the
16390 + * GNU General Public License ("GPL") as published by the Free Software
16391 + * Foundation, either version 2 of that License or (at your option) any
16392 + * later version.
16393 + *
16394 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16395 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16396 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16397 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16398 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16399 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16400 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16401 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16402 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16403 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16404 + */
16405 +
16406 +/******************************************************************************
16407 + @File dtsec.h
16408 +
16409 + @Description FM dTSEC ...
16410 +*//***************************************************************************/
16411 +#ifndef __DTSEC_H
16412 +#define __DTSEC_H
16413 +
16414 +#include "std_ext.h"
16415 +#include "error_ext.h"
16416 +#include "list_ext.h"
16417 +#include "enet_ext.h"
16418 +
16419 +#include "dtsec_mii_acc.h"
16420 +#include "fm_mac.h"
16421 +
16422 +
16423 +#define DEFAULT_exceptions \
16424 + ((uint32_t)(DTSEC_IMASK_BREN | \
16425 + DTSEC_IMASK_RXCEN | \
16426 + DTSEC_IMASK_BTEN | \
16427 + DTSEC_IMASK_TXCEN | \
16428 + DTSEC_IMASK_TXEEN | \
16429 + DTSEC_IMASK_ABRTEN | \
16430 + DTSEC_IMASK_LCEN | \
16431 + DTSEC_IMASK_CRLEN | \
16432 + DTSEC_IMASK_XFUNEN | \
16433 + DTSEC_IMASK_IFERREN | \
16434 + DTSEC_IMASK_MAGEN | \
16435 + DTSEC_IMASK_TDPEEN | \
16436 + DTSEC_IMASK_RDPEEN))
16437 +
16438 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
16439 + case e_FM_MAC_EX_1G_BAB_RX: \
16440 + bitMask = DTSEC_IMASK_BREN; break; \
16441 + case e_FM_MAC_EX_1G_RX_CTL: \
16442 + bitMask = DTSEC_IMASK_RXCEN; break; \
16443 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
16444 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
16445 + case e_FM_MAC_EX_1G_BAB_TX: \
16446 + bitMask = DTSEC_IMASK_BTEN ; break; \
16447 + case e_FM_MAC_EX_1G_TX_CTL: \
16448 + bitMask = DTSEC_IMASK_TXCEN ; break; \
16449 + case e_FM_MAC_EX_1G_TX_ERR: \
16450 + bitMask = DTSEC_IMASK_TXEEN ; break; \
16451 + case e_FM_MAC_EX_1G_LATE_COL: \
16452 + bitMask = DTSEC_IMASK_LCEN ; break; \
16453 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
16454 + bitMask = DTSEC_IMASK_CRLEN ; break; \
16455 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
16456 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
16457 + case e_FM_MAC_EX_1G_MAG_PCKT: \
16458 + bitMask = DTSEC_IMASK_MAGEN ; break; \
16459 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
16460 + bitMask = DTSEC_IMASK_MMRDEN; break; \
16461 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
16462 + bitMask = DTSEC_IMASK_MMWREN ; break; \
16463 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
16464 + bitMask = DTSEC_IMASK_GRSCEN; break; \
16465 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
16466 + bitMask = DTSEC_IMASK_TDPEEN; break; \
16467 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
16468 + bitMask = DTSEC_IMASK_MSROEN ; break; \
16469 + default: bitMask = 0;break;}
16470 +
16471 +
16472 +#define MAX_PACKET_ALIGNMENT 31
16473 +#define MAX_INTER_PACKET_GAP 0x7f
16474 +#define MAX_INTER_PALTERNATE_BEB 0x0f
16475 +#define MAX_RETRANSMISSION 0x0f
16476 +#define MAX_COLLISION_WINDOW 0x03ff
16477 +
16478 +
16479 +/********************* From mac ext ******************************************/
16480 +typedef uint32_t t_ErrorDisable;
16481 +
16482 +#define ERROR_DISABLE_TRANSMIT 0x00400000
16483 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
16484 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
16485 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
16486 +#define ERROR_DISABLE_TxABORT 0x00008000
16487 +#define ERROR_DISABLE_INTERFACE 0x00004000
16488 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
16489 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
16490 +
16491 +/*****************************************************************************/
16492 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
16493 +
16494 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
16495 +
16496 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
16497 +
16498 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
16499 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
16500 +
16501 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
16502 +
16503 +#define MAX_PHYS 32 /* maximum number of phys */
16504 +
16505 +#define VAL32BIT 0x100000000LL
16506 +#define VAL22BIT 0x00400000
16507 +#define VAL16BIT 0x00010000
16508 +#define VAL12BIT 0x00001000
16509 +
16510 +/* CAR1/2 bits */
16511 +#define CAR1_TR64 0x80000000
16512 +#define CAR1_TR127 0x40000000
16513 +#define CAR1_TR255 0x20000000
16514 +#define CAR1_TR511 0x10000000
16515 +#define CAR1_TRK1 0x08000000
16516 +#define CAR1_TRMAX 0x04000000
16517 +#define CAR1_TRMGV 0x02000000
16518 +
16519 +#define CAR1_RBYT 0x00010000
16520 +#define CAR1_RPKT 0x00008000
16521 +#define CAR1_RMCA 0x00002000
16522 +#define CAR1_RBCA 0x00001000
16523 +#define CAR1_RXPF 0x00000400
16524 +#define CAR1_RALN 0x00000100
16525 +#define CAR1_RFLR 0x00000080
16526 +#define CAR1_RCDE 0x00000040
16527 +#define CAR1_RCSE 0x00000020
16528 +#define CAR1_RUND 0x00000010
16529 +#define CAR1_ROVR 0x00000008
16530 +#define CAR1_RFRG 0x00000004
16531 +#define CAR1_RJBR 0x00000002
16532 +#define CAR1_RDRP 0x00000001
16533 +
16534 +#define CAR2_TFCS 0x00040000
16535 +#define CAR2_TBYT 0x00002000
16536 +#define CAR2_TPKT 0x00001000
16537 +#define CAR2_TMCA 0x00000800
16538 +#define CAR2_TBCA 0x00000400
16539 +#define CAR2_TXPF 0x00000200
16540 +#define CAR2_TDRP 0x00000001
16541 +
16542 +typedef struct t_InternalStatistics
16543 +{
16544 + uint64_t tr64;
16545 + uint64_t tr127;
16546 + uint64_t tr255;
16547 + uint64_t tr511;
16548 + uint64_t tr1k;
16549 + uint64_t trmax;
16550 + uint64_t trmgv;
16551 + uint64_t rfrg;
16552 + uint64_t rjbr;
16553 + uint64_t rdrp;
16554 + uint64_t raln;
16555 + uint64_t rund;
16556 + uint64_t rovr;
16557 + uint64_t rxpf;
16558 + uint64_t txpf;
16559 + uint64_t rbyt;
16560 + uint64_t rpkt;
16561 + uint64_t rmca;
16562 + uint64_t rbca;
16563 + uint64_t rflr;
16564 + uint64_t rcde;
16565 + uint64_t rcse;
16566 + uint64_t tbyt;
16567 + uint64_t tpkt;
16568 + uint64_t tmca;
16569 + uint64_t tbca;
16570 + uint64_t tdrp;
16571 + uint64_t tfcs;
16572 +} t_InternalStatistics;
16573 +
16574 +typedef struct {
16575 + t_FmMacControllerDriver fmMacControllerDriver;
16576 + t_Handle h_App; /**< Handle to the upper layer application */
16577 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
16578 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
16579 + uint64_t addr; /**< MAC address of device; */
16580 + e_EnetMode enetMode; /**< Ethernet physical interface */
16581 + t_FmMacExceptionCallback *f_Exception;
16582 + int mdioIrq;
16583 + t_FmMacExceptionCallback *f_Event;
16584 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
16585 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
16586 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
16587 + bool halfDuplex;
16588 + t_InternalStatistics internalStatistics;
16589 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
16590 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
16591 + uint8_t macId;
16592 + uint8_t tbi_phy_addr;
16593 + uint32_t exceptions;
16594 + bool ptpTsuEnabled;
16595 + bool enTsuErrExeption;
16596 + e_FmMacStatisticsLevel statisticsLevel;
16597 + struct dtsec_cfg *p_DtsecDriverParam;
16598 +} t_Dtsec;
16599 +
16600 +
16601 +#endif /* __DTSEC_H */
16602 --- /dev/null
16603 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16604 @@ -0,0 +1,97 @@
16605 +/*
16606 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16607 + *
16608 + * Redistribution and use in source and binary forms, with or without
16609 + * modification, are permitted provided that the following conditions are met:
16610 + * * Redistributions of source code must retain the above copyright
16611 + * notice, this list of conditions and the following disclaimer.
16612 + * * Redistributions in binary form must reproduce the above copyright
16613 + * notice, this list of conditions and the following disclaimer in the
16614 + * documentation and/or other materials provided with the distribution.
16615 + * * Neither the name of Freescale Semiconductor nor the
16616 + * names of its contributors may be used to endorse or promote products
16617 + * derived from this software without specific prior written permission.
16618 + *
16619 + *
16620 + * ALTERNATIVELY, this software may be distributed under the terms of the
16621 + * GNU General Public License ("GPL") as published by the Free Software
16622 + * Foundation, either version 2 of that License or (at your option) any
16623 + * later version.
16624 + *
16625 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16626 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16627 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16628 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16629 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16630 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16631 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16632 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16633 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16634 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16635 + */
16636 +
16637 +
16638 +/******************************************************************************
16639 + @File dtsec_mii_acc.c
16640 +
16641 + @Description FM dtsec MII register access MAC ...
16642 +*//***************************************************************************/
16643 +
16644 +#include "error_ext.h"
16645 +#include "std_ext.h"
16646 +#include "fm_mac.h"
16647 +#include "dtsec.h"
16648 +#include "fsl_fman_dtsec_mii_acc.h"
16649 +
16650 +
16651 +/*****************************************************************************/
16652 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
16653 + uint8_t phyAddr,
16654 + uint8_t reg,
16655 + uint16_t data)
16656 +{
16657 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16658 + struct dtsec_mii_reg *miiregs;
16659 + uint16_t dtsec_freq;
16660 + t_Error err;
16661 +
16662 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16663 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16664 +
16665 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16666 + miiregs = p_Dtsec->p_MiiMemMap;
16667 +
16668 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
16669 +
16670 + return err;
16671 +}
16672 +
16673 +/*****************************************************************************/
16674 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
16675 + uint8_t phyAddr,
16676 + uint8_t reg,
16677 + uint16_t *p_Data)
16678 +{
16679 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16680 + struct dtsec_mii_reg *miiregs;
16681 + uint16_t dtsec_freq;
16682 + t_Error err;
16683 +
16684 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16685 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16686 +
16687 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16688 + miiregs = p_Dtsec->p_MiiMemMap;
16689 +
16690 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
16691 +
16692 + if (*p_Data == 0xffff)
16693 + RETURN_ERROR(MINOR, E_NO_DEVICE,
16694 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
16695 + phyAddr, reg));
16696 + if (err)
16697 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
16698 +
16699 + return E_OK;
16700 +}
16701 +
16702 --- /dev/null
16703 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16704 @@ -0,0 +1,42 @@
16705 +/*
16706 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16707 + *
16708 + * Redistribution and use in source and binary forms, with or without
16709 + * modification, are permitted provided that the following conditions are met:
16710 + * * Redistributions of source code must retain the above copyright
16711 + * notice, this list of conditions and the following disclaimer.
16712 + * * Redistributions in binary form must reproduce the above copyright
16713 + * notice, this list of conditions and the following disclaimer in the
16714 + * documentation and/or other materials provided with the distribution.
16715 + * * Neither the name of Freescale Semiconductor nor the
16716 + * names of its contributors may be used to endorse or promote products
16717 + * derived from this software without specific prior written permission.
16718 + *
16719 + *
16720 + * ALTERNATIVELY, this software may be distributed under the terms of the
16721 + * GNU General Public License ("GPL") as published by the Free Software
16722 + * Foundation, either version 2 of that License or (at your option) any
16723 + * later version.
16724 + *
16725 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16726 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16727 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16728 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16729 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16730 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16731 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16732 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16733 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16734 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16735 + */
16736 +
16737 +#ifndef __DTSEC_MII_ACC_H
16738 +#define __DTSEC_MII_ACC_H
16739 +
16740 +#include "std_ext.h"
16741 +
16742 +
16743 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
16744 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
16745 +
16746 +#endif /* __DTSEC_MII_ACC_H */
16747 --- /dev/null
16748 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16749 @@ -0,0 +1,658 @@
16750 +/*
16751 + * Copyright 2008-2012 Freescale Semiconductor Inc.
16752 + *
16753 + * Redistribution and use in source and binary forms, with or without
16754 + * modification, are permitted provided that the following conditions are met:
16755 + * * Redistributions of source code must retain the above copyright
16756 + * notice, this list of conditions and the following disclaimer.
16757 + * * Redistributions in binary form must reproduce the above copyright
16758 + * notice, this list of conditions and the following disclaimer in the
16759 + * documentation and/or other materials provided with the distribution.
16760 + * * Neither the name of Freescale Semiconductor nor the
16761 + * names of its contributors may be used to endorse or promote products
16762 + * derived from this software without specific prior written permission.
16763 + *
16764 + *
16765 + * ALTERNATIVELY, this software may be distributed under the terms of the
16766 + * GNU General Public License ("GPL") as published by the Free Software
16767 + * Foundation, either version 2 of that License or (at your option) any
16768 + * later version.
16769 + *
16770 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16771 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16772 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16773 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16774 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16775 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16776 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16777 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16778 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16779 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16780 + */
16781 +
16782 +
16783 +/******************************************************************************
16784 + @File fm_mac.c
16785 +
16786 + @Description FM MAC ...
16787 +*//***************************************************************************/
16788 +#include "std_ext.h"
16789 +#include "string_ext.h"
16790 +#include "sprint_ext.h"
16791 +#include "error_ext.h"
16792 +#include "fm_ext.h"
16793 +
16794 +#include "fm_common.h"
16795 +#include "fm_mac.h"
16796 +
16797 +
16798 +/* ......................................................................... */
16799 +
16800 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
16801 +{
16802 + t_FmMacControllerDriver *p_FmMacControllerDriver;
16803 + uint16_t fmClkFreq;
16804 +
16805 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
16806 +
16807 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
16808 + if (fmClkFreq == 0)
16809 + {
16810 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
16811 + return NULL;
16812 + }
16813 +
16814 +#if (DPAA_VERSION == 10)
16815 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
16816 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
16817 + else
16818 +#if FM_MAX_NUM_OF_10G_MACS > 0
16819 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
16820 +#else
16821 + p_FmMacControllerDriver = NULL;
16822 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
16823 +#else
16824 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
16825 +#endif /* (DPAA_VERSION == 10) */
16826 +
16827 + if (!p_FmMacControllerDriver)
16828 + return NULL;
16829 +
16830 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
16831 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
16832 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
16833 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
16834 +
16835 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
16836 +
16837 + return (t_Handle)p_FmMacControllerDriver;
16838 +}
16839 +
16840 +/* ......................................................................... */
16841 +
16842 +t_Error FM_MAC_Init (t_Handle h_FmMac)
16843 +{
16844 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16845 +
16846 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16847 +
16848 + if (p_FmMacControllerDriver->resetOnInit &&
16849 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
16850 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
16851 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
16852 + e_FM_MAC_10G : e_FM_MAC_1G),
16853 + p_FmMacControllerDriver->macId) != E_OK))
16854 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
16855 +
16856 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
16857 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
16858 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16859 +}
16860 +
16861 +/* ......................................................................... */
16862 +
16863 +t_Error FM_MAC_Free (t_Handle h_FmMac)
16864 +{
16865 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16866 +
16867 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16868 +
16869 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
16870 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
16871 +
16872 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16873 +}
16874 +
16875 +/* ......................................................................... */
16876 +
16877 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
16878 +{
16879 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16880 +
16881 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16882 +
16883 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
16884 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
16885 +
16886 + p_FmMacControllerDriver->resetOnInit = enable;
16887 +
16888 + return E_OK;
16889 +}
16890 +
16891 +/* ......................................................................... */
16892 +
16893 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
16894 +{
16895 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16896 +
16897 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16898 +
16899 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
16900 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
16901 +
16902 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16903 +}
16904 +
16905 +/* ......................................................................... */
16906 +
16907 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
16908 +{
16909 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16910 +
16911 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16912 +
16913 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
16914 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
16915 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16916 +}
16917 +
16918 +/* ......................................................................... */
16919 +
16920 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
16921 +{
16922 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16923 +
16924 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16925 +
16926 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
16927 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
16928 +
16929 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16930 +}
16931 +
16932 +/* ......................................................................... */
16933 +
16934 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
16935 +{
16936 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16937 +
16938 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16939 +
16940 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
16941 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
16942 +
16943 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16944 +}
16945 +
16946 +/* ......................................................................... */
16947 +
16948 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
16949 +{
16950 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16951 +
16952 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16953 +
16954 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
16955 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
16956 +
16957 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16958 +}
16959 +
16960 +/* ......................................................................... */
16961 +
16962 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
16963 +{
16964 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16965 +
16966 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16967 +
16968 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
16969 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
16970 +
16971 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16972 +}
16973 +
16974 +/* ......................................................................... */
16975 +
16976 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
16977 +{
16978 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16979 +
16980 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16981 +
16982 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
16983 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
16984 +
16985 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
16986 +}
16987 +
16988 +/* ......................................................................... */
16989 +
16990 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
16991 +{
16992 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
16993 +
16994 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
16995 +
16996 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
16997 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
16998 +
16999 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17000 +}
17001 +
17002 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17003 +/* ......................................................................... */
17004 +
17005 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
17006 +{
17007 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17008 +
17009 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17010 +
17011 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
17012 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
17013 +
17014 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17015 +}
17016 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17017 +
17018 +
17019 +/*****************************************************************************/
17020 +/* Run Time Control */
17021 +/*****************************************************************************/
17022 +
17023 +/* ......................................................................... */
17024 +
17025 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
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_Enable)
17032 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
17033 +
17034 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17035 +}
17036 +
17037 +/* ......................................................................... */
17038 +
17039 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
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_Disable)
17046 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
17047 +
17048 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17049 +}
17050 +
17051 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
17052 +{
17053 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17054 +
17055 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17056 +
17057 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
17058 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
17059 +
17060 + return E_OK;
17061 +}
17062 +
17063 +/* ......................................................................... */
17064 +
17065 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
17066 +{
17067 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17068 +
17069 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17070 +
17071 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
17072 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
17073 +
17074 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17075 +}
17076 +
17077 +/* ......................................................................... */
17078 +
17079 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
17080 +{
17081 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17082 +
17083 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17084 +
17085 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
17086 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
17087 +
17088 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17089 +}
17090 +
17091 +/* ......................................................................... */
17092 +
17093 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
17094 + uint16_t pauseTime)
17095 +{
17096 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17097 +
17098 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17099 +
17100 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
17101 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
17102 + pauseTime);
17103 +
17104 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17105 +}
17106 +
17107 +/* ......................................................................... */
17108 +
17109 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
17110 + uint8_t priority,
17111 + uint16_t pauseTime,
17112 + uint16_t threshTime)
17113 +{
17114 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17115 +
17116 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17117 +
17118 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
17119 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
17120 + priority,
17121 + pauseTime,
17122 + threshTime);
17123 +
17124 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
17125 +}
17126 +
17127 +/* ......................................................................... */
17128 +
17129 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
17130 +{
17131 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17132 +
17133 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17134 +
17135 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
17136 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
17137 +
17138 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17139 +}
17140 +
17141 +/* ......................................................................... */
17142 +
17143 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
17144 +{
17145 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17146 +
17147 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17148 +
17149 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
17150 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
17151 +
17152 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17153 +}
17154 +
17155 +/* ......................................................................... */
17156 +
17157 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
17158 +{
17159 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17160 +
17161 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17162 +
17163 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
17164 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
17165 +
17166 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17167 +}
17168 +
17169 +/* ......................................................................... */
17170 +
17171 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17172 +{
17173 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17174 +
17175 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17176 +
17177 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
17178 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
17179 +
17180 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17181 +}
17182 +
17183 +/* ......................................................................... */
17184 +
17185 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
17186 +{
17187 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17188 +
17189 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17190 +
17191 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
17192 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
17193 +
17194 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17195 +}
17196 +
17197 +/* ......................................................................... */
17198 +
17199 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
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_GetStatistics)
17206 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
17207 +
17208 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17209 +}
17210 +
17211 +/* ......................................................................... */
17212 +
17213 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17214 +{
17215 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17216 +
17217 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17218 +
17219 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
17220 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
17221 +
17222 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17223 +}
17224 +
17225 +/* ......................................................................... */
17226 +
17227 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17228 +{
17229 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17230 +
17231 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17232 +
17233 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
17234 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
17235 +
17236 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17237 +}
17238 +
17239 +/* ......................................................................... */
17240 +
17241 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17242 +{
17243 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17244 +
17245 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17246 +
17247 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
17248 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
17249 +
17250 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17251 +}
17252 +
17253 +/* ......................................................................... */
17254 +
17255 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17256 +{
17257 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17258 +
17259 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17260 +
17261 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
17262 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
17263 +
17264 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17265 +}
17266 +
17267 +/* ......................................................................... */
17268 +
17269 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17270 +{
17271 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17272 +
17273 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17274 +
17275 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
17276 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
17277 +
17278 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17279 +}
17280 +
17281 +/* ......................................................................... */
17282 +
17283 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
17284 +{
17285 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17286 +
17287 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17288 +
17289 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
17290 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
17291 +
17292 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17293 +
17294 +}
17295 +
17296 +/* ......................................................................... */
17297 +
17298 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
17299 +{
17300 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17301 +
17302 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17303 +
17304 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
17305 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
17306 +
17307 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17308 +}
17309 +
17310 +/* ......................................................................... */
17311 +
17312 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
17313 +{
17314 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17315 +
17316 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17317 +
17318 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
17319 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
17320 +
17321 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17322 +}
17323 +
17324 +/* ......................................................................... */
17325 +
17326 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
17327 +{
17328 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17329 +
17330 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17331 +
17332 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
17333 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
17334 +
17335 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17336 +}
17337 +
17338 +/* ......................................................................... */
17339 +
17340 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
17341 +{
17342 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17343 +
17344 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17345 +
17346 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
17347 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
17348 +
17349 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17350 +}
17351 +
17352 +/* ......................................................................... */
17353 +
17354 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
17355 +{
17356 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17357 +
17358 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17359 +
17360 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
17361 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
17362 +
17363 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17364 +}
17365 +
17366 +/* ......................................................................... */
17367 +
17368 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
17369 +{
17370 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17371 +
17372 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17373 +
17374 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
17375 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
17376 +
17377 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17378 +}
17379 +
17380 +/* ......................................................................... */
17381 +
17382 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
17383 +{
17384 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17385 +
17386 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
17387 +
17388 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
17389 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
17390 +
17391 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17392 + return 0;
17393 +}
17394 +
17395 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17396 +/*****************************************************************************/
17397 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
17398 +{
17399 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17400 +
17401 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17402 +
17403 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
17404 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
17405 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17406 +}
17407 +#endif /* (defined(DEBUG_ERRORS) && ... */
17408 --- /dev/null
17409 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17410 @@ -0,0 +1,225 @@
17411 +/*
17412 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17413 + *
17414 + * Redistribution and use in source and binary forms, with or without
17415 + * modification, are permitted provided that the following conditions are met:
17416 + * * Redistributions of source code must retain the above copyright
17417 + * notice, this list of conditions and the following disclaimer.
17418 + * * Redistributions in binary form must reproduce the above copyright
17419 + * notice, this list of conditions and the following disclaimer in the
17420 + * documentation and/or other materials provided with the distribution.
17421 + * * Neither the name of Freescale Semiconductor nor the
17422 + * names of its contributors may be used to endorse or promote products
17423 + * derived from this software without specific prior written permission.
17424 + *
17425 + *
17426 + * ALTERNATIVELY, this software may be distributed under the terms of the
17427 + * GNU General Public License ("GPL") as published by the Free Software
17428 + * Foundation, either version 2 of that License or (at your option) any
17429 + * later version.
17430 + *
17431 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17432 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17433 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17434 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17435 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17436 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17437 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17438 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17439 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17440 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17441 + */
17442 +
17443 +
17444 +/******************************************************************************
17445 + @File fm_mac.h
17446 +
17447 + @Description FM MAC ...
17448 +*//***************************************************************************/
17449 +#ifndef __FM_MAC_H
17450 +#define __FM_MAC_H
17451 +
17452 +#include "std_ext.h"
17453 +#include "error_ext.h"
17454 +#include "list_ext.h"
17455 +#include "fm_mac_ext.h"
17456 +#include "fm_common.h"
17457 +
17458 +
17459 +#define __ERR_MODULE__ MODULE_FM_MAC
17460 +
17461 +/**************************************************************************//**
17462 + @Description defaults
17463 +*//***************************************************************************/
17464 +
17465 +
17466 +#define DEFAULT_halfDuplex FALSE
17467 +#define DEFAULT_padAndCrcEnable TRUE
17468 +#define DEFAULT_resetOnInit FALSE
17469 +
17470 +
17471 +typedef struct {
17472 + uint64_t addr; /* Ethernet Address */
17473 + t_List node;
17474 +} t_EthHashEntry;
17475 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
17476 +
17477 +typedef struct {
17478 + uint16_t size;
17479 + t_List *p_Lsts;
17480 +} t_EthHash;
17481 +
17482 +typedef struct {
17483 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
17484 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
17485 +
17486 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
17487 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
17488 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
17489 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
17490 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
17491 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
17492 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
17493 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
17494 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
17495 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
17496 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17497 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
17498 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17499 +
17500 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
17501 +
17502 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
17503 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
17504 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
17505 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
17506 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
17507 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
17508 +
17509 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
17510 + uint16_t pauseTime);
17511 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
17512 + uint8_t priority,
17513 + uint16_t pauseTime,
17514 + uint16_t threshTime);
17515 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
17516 +
17517 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
17518 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
17519 +
17520 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17521 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17522 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17523 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17524 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17525 +
17526 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
17527 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
17528 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
17529 +
17530 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
17531 +
17532 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
17533 +
17534 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
17535 +
17536 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
17537 +
17538 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
17539 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
17540 +
17541 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17542 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
17543 +#endif /* (defined(DEBUG_ERRORS) && ... */
17544 +
17545 + t_Handle h_Fm;
17546 + t_FmRevisionInfo fmRevInfo;
17547 + e_EnetMode enetMode;
17548 + uint8_t macId;
17549 + bool resetOnInit;
17550 + uint16_t clkFreq;
17551 +} t_FmMacControllerDriver;
17552 +
17553 +
17554 +#if (DPAA_VERSION == 10)
17555 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
17556 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
17557 +#else
17558 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
17559 +#endif /* (DPAA_VERSION == 10) */
17560 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
17561 +
17562 +
17563 +/* ........................................................................... */
17564 +
17565 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
17566 +{
17567 + t_EthHashEntry *p_HashEntry = NULL;
17568 + if (!LIST_IsEmpty(p_AddrLst))
17569 + {
17570 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
17571 + LIST_DelAndInit(&p_HashEntry->node);
17572 + }
17573 + return p_HashEntry;
17574 +}
17575 +
17576 +/* ........................................................................... */
17577 +
17578 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
17579 +{
17580 + t_EthHashEntry *p_HashEntry;
17581 + int i = 0;
17582 +
17583 + if (p_Hash)
17584 + {
17585 + if (p_Hash->p_Lsts)
17586 + {
17587 + for (i=0; i<p_Hash->size; i++)
17588 + {
17589 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17590 + while (p_HashEntry)
17591 + {
17592 + XX_Free(p_HashEntry);
17593 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17594 + }
17595 + }
17596 +
17597 + XX_Free(p_Hash->p_Lsts);
17598 + }
17599 +
17600 + XX_Free(p_Hash);
17601 + }
17602 +}
17603 +
17604 +/* ........................................................................... */
17605 +
17606 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
17607 +{
17608 + uint32_t i;
17609 + t_EthHash *p_Hash;
17610 +
17611 + /* Allocate address hash table */
17612 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
17613 + if (!p_Hash)
17614 + {
17615 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17616 + return NULL;
17617 + }
17618 + p_Hash->size = size;
17619 +
17620 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
17621 + if (!p_Hash->p_Lsts)
17622 + {
17623 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17624 + XX_Free(p_Hash);
17625 + return NULL;
17626 + }
17627 +
17628 + for (i=0 ; i<p_Hash->size; i++)
17629 + INIT_LIST(&p_Hash->p_Lsts[i]);
17630 +
17631 + return p_Hash;
17632 +}
17633 +
17634 +
17635 +#endif /* __FM_MAC_H */
17636 --- /dev/null
17637 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17638 @@ -0,0 +1,119 @@
17639 +/*
17640 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17641 + *
17642 + * Redistribution and use in source and binary forms, with or without
17643 + * modification, are permitted provided that the following conditions are met:
17644 + * * Redistributions of source code must retain the above copyright
17645 + * notice, this list of conditions and the following disclaimer.
17646 + * * Redistributions in binary form must reproduce the above copyright
17647 + * notice, this list of conditions and the following disclaimer in the
17648 + * documentation and/or other materials provided with the distribution.
17649 + * * Neither the name of Freescale Semiconductor nor the
17650 + * names of its contributors may be used to endorse or promote products
17651 + * derived from this software without specific prior written permission.
17652 + *
17653 + *
17654 + * ALTERNATIVELY, this software may be distributed under the terms of the
17655 + * GNU General Public License ("GPL") as published by the Free Software
17656 + * Foundation, either version 2 of that License or (at your option) any
17657 + * later version.
17658 + *
17659 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17660 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17661 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17662 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17663 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17664 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17665 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17666 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17667 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17668 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17669 + */
17670 +
17671 +
17672 +#include "fman_crc32.h"
17673 +#include "common/general.h"
17674 +
17675 +
17676 +/* precomputed CRC values for address hashing */
17677 +static const uint32_t crc_tbl[256] = {
17678 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
17679 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
17680 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
17681 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
17682 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
17683 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
17684 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
17685 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17686 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
17687 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
17688 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17689 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
17690 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
17691 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
17692 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17693 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
17694 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
17695 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
17696 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
17697 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
17698 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
17699 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
17700 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
17701 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
17702 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
17703 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
17704 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
17705 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
17706 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
17707 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
17708 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
17709 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
17710 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
17711 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
17712 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
17713 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
17714 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
17715 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
17716 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
17717 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
17718 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
17719 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
17720 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
17721 +};
17722 +
17723 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
17724 +static inline uint8_t get_mirror8(uint8_t n)
17725 +{
17726 + uint8_t mirror[16] = {
17727 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
17728 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
17729 + };
17730 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
17731 +}
17732 +
17733 +static inline uint32_t get_mirror32(uint32_t n)
17734 +{
17735 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
17736 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
17737 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
17738 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
17739 +}
17740 +
17741 +uint32_t get_mac_addr_crc(uint64_t _addr)
17742 +{
17743 + uint32_t i;
17744 + uint8_t data;
17745 + uint32_t crc;
17746 +
17747 + /* CRC calculation */
17748 + crc = 0xffffffff;
17749 + for (i = 0; i < 6; i++) {
17750 + data = (uint8_t)(_addr >> ((5-i)*8));
17751 + crc = crc ^ data;
17752 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
17753 + }
17754 +
17755 + crc = get_mirror32(crc);
17756 + return crc;
17757 +}
17758 --- /dev/null
17759 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17760 @@ -0,0 +1,43 @@
17761 +/*
17762 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17763 + *
17764 + * Redistribution and use in source and binary forms, with or without
17765 + * modification, are permitted provided that the following conditions are met:
17766 + * * Redistributions of source code must retain the above copyright
17767 + * notice, this list of conditions and the following disclaimer.
17768 + * * Redistributions in binary form must reproduce the above copyright
17769 + * notice, this list of conditions and the following disclaimer in the
17770 + * documentation and/or other materials provided with the distribution.
17771 + * * Neither the name of Freescale Semiconductor nor the
17772 + * names of its contributors may be used to endorse or promote products
17773 + * derived from this software without specific prior written permission.
17774 + *
17775 + *
17776 + * ALTERNATIVELY, this software may be distributed under the terms of the
17777 + * GNU General Public License ("GPL") as published by the Free Software
17778 + * Foundation, either version 2 of that License or (at your option) any
17779 + * later version.
17780 + *
17781 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17782 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17783 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17784 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17785 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17786 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17787 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17788 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17789 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17790 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17791 + */
17792 +
17793 +
17794 +#ifndef __FMAN_CRC32_H
17795 +#define __FMAN_CRC32_H
17796 +
17797 +#include "common/general.h"
17798 +
17799 +
17800 +uint32_t get_mac_addr_crc(uint64_t _addr);
17801 +
17802 +
17803 +#endif /* __FMAN_CRC32_H */
17804 --- /dev/null
17805 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
17806 @@ -0,0 +1,845 @@
17807 +/*
17808 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17809 + *
17810 + * Redistribution and use in source and binary forms, with or without
17811 + * modification, are permitted provided that the following conditions are met:
17812 + * * Redistributions of source code must retain the above copyright
17813 + * notice, this list of conditions and the following disclaimer.
17814 + * * Redistributions in binary form must reproduce the above copyright
17815 + * notice, this list of conditions and the following disclaimer in the
17816 + * documentation and/or other materials provided with the distribution.
17817 + * * Neither the name of Freescale Semiconductor nor the
17818 + * names of its contributors may be used to endorse or promote products
17819 + * derived from this software without specific prior written permission.
17820 + *
17821 + *
17822 + * ALTERNATIVELY, this software may be distributed under the terms of the
17823 + * GNU General Public License ("GPL") as published by the Free Software
17824 + * Foundation, either version 2 of that License or (at your option) any
17825 + * later version.
17826 + *
17827 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17828 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17829 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17830 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17831 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17832 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17833 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17834 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17835 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17836 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17837 + */
17838 +
17839 +
17840 +#include "fsl_fman_dtsec.h"
17841 +
17842 +
17843 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
17844 +{
17845 + /* Assert the graceful stop bit */
17846 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
17847 +}
17848 +
17849 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
17850 +{
17851 + /* Assert the graceful stop bit */
17852 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
17853 +}
17854 +
17855 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
17856 +{
17857 + /* clear the graceful stop bit */
17858 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
17859 +}
17860 +
17861 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
17862 +{
17863 + /* clear the graceful stop bit */
17864 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
17865 +}
17866 +
17867 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
17868 +{
17869 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
17870 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
17871 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
17872 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
17873 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
17874 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
17875 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
17876 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
17877 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
17878 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
17879 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
17880 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
17881 + cfg->tx_crc = DEFAULT_TX_CRC;
17882 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
17883 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
17884 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
17885 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
17886 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
17887 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
17888 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
17889 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
17890 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
17891 + cfg->loopback = DEFAULT_LOOPBACK;
17892 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
17893 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
17894 + cfg->rx_flow = DEFAULT_RX_FLOW;
17895 + cfg->tx_flow = DEFAULT_TX_FLOW;
17896 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
17897 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
17898 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
17899 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
17900 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
17901 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
17902 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
17903 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
17904 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
17905 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
17906 +}
17907 +
17908 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
17909 + enum enet_interface iface_mode,
17910 + enum enet_speed iface_speed,
17911 + uint8_t *macaddr,
17912 + uint8_t fm_rev_maj,
17913 + uint8_t fm_rev_min,
17914 + uint32_t exception_mask)
17915 +{
17916 + bool is_rgmii = FALSE;
17917 + bool is_sgmii = FALSE;
17918 + bool is_qsgmii = FALSE;
17919 + int i;
17920 + uint32_t tmp;
17921 +
17922 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
17923 +
17924 + /* let's start with a soft reset */
17925 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
17926 + iowrite32be(0, &regs->maccfg1);
17927 +
17928 + /*************dtsec_id2******************/
17929 + tmp = ioread32be(&regs->tsec_id2);
17930 +
17931 + /* check RGMII support */
17932 + if (iface_mode == E_ENET_IF_RGMII ||
17933 + iface_mode == E_ENET_IF_RMII)
17934 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
17935 + return -EINVAL;
17936 +
17937 + if (iface_mode == E_ENET_IF_SGMII ||
17938 + iface_mode == E_ENET_IF_MII)
17939 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
17940 + return -EINVAL;
17941 +
17942 + /***************ECNTRL************************/
17943 +
17944 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
17945 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
17946 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
17947 +
17948 + tmp = 0;
17949 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
17950 + tmp |= DTSEC_ECNTRL_GMIIM;
17951 + if (is_sgmii)
17952 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
17953 + if (is_qsgmii)
17954 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
17955 + DTSEC_ECNTRL_QSGMIIM);
17956 + if (is_rgmii)
17957 + tmp |= DTSEC_ECNTRL_RPM;
17958 + if (iface_speed == E_ENET_SPEED_100)
17959 + tmp |= DTSEC_ECNTRL_R100M;
17960 +
17961 + iowrite32be(tmp, &regs->ecntrl);
17962 + /***************ECNTRL************************/
17963 +
17964 + /***************TCTRL************************/
17965 + tmp = 0;
17966 + if (cfg->halfdup_on)
17967 + tmp |= DTSEC_TCTRL_THDF;
17968 + if (cfg->tx_time_stamp_en)
17969 + tmp |= DTSEC_TCTRL_TTSE;
17970 +
17971 + iowrite32be(tmp, &regs->tctrl);
17972 +
17973 + /***************TCTRL************************/
17974 +
17975 + /***************PTV************************/
17976 + tmp = 0;
17977 +
17978 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
17979 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
17980 + cfg->tx_pause_time += 2;
17981 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
17982 +
17983 + if (cfg->tx_pause_time)
17984 + tmp |= cfg->tx_pause_time;
17985 + if (cfg->tx_pause_time_extd)
17986 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
17987 + iowrite32be(tmp, &regs->ptv);
17988 +
17989 + /***************RCTRL************************/
17990 + tmp = 0;
17991 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
17992 + if (cfg->rx_ctrl_acc)
17993 + tmp |= RCTRL_CFA;
17994 + if (cfg->rx_group_hash_exd)
17995 + tmp |= RCTRL_GHTX;
17996 + if (cfg->rx_time_stamp_en)
17997 + tmp |= RCTRL_RTSE;
17998 + if (cfg->rx_drop_bcast)
17999 + tmp |= RCTRL_BC_REJ;
18000 + if (cfg->rx_short_frm)
18001 + tmp |= RCTRL_RSF;
18002 + if (cfg->rx_promisc)
18003 + tmp |= RCTRL_PROM;
18004 +
18005 + iowrite32be(tmp, &regs->rctrl);
18006 + /***************RCTRL************************/
18007 +
18008 + /*
18009 + * Assign a Phy Address to the TBI (TBIPA).
18010 + * Done also in cases where TBI is not selected to avoid conflict with
18011 + * the external PHY's Physical address
18012 + */
18013 + iowrite32be(cfg->tbipa, &regs->tbipa);
18014 +
18015 + /***************TMR_CTL************************/
18016 + iowrite32be(0, &regs->tmr_ctrl);
18017 +
18018 + if (cfg->ptp_tsu_en) {
18019 + tmp = 0;
18020 + tmp |= TMR_PEVENT_TSRE;
18021 + iowrite32be(tmp, &regs->tmr_pevent);
18022 +
18023 + if (cfg->ptp_exception_en) {
18024 + tmp = 0;
18025 + tmp |= TMR_PEMASK_TSREEN;
18026 + iowrite32be(tmp, &regs->tmr_pemask);
18027 + }
18028 + }
18029 +
18030 + /***************MACCFG1***********************/
18031 + tmp = 0;
18032 + if (cfg->loopback)
18033 + tmp |= MACCFG1_LOOPBACK;
18034 + if (cfg->rx_flow)
18035 + tmp |= MACCFG1_RX_FLOW;
18036 + if (cfg->tx_flow)
18037 + tmp |= MACCFG1_TX_FLOW;
18038 + iowrite32be(tmp, &regs->maccfg1);
18039 +
18040 + /***************MACCFG1***********************/
18041 +
18042 + /***************MACCFG2***********************/
18043 + tmp = 0;
18044 +
18045 + if (iface_speed < E_ENET_SPEED_1000)
18046 + tmp |= MACCFG2_NIBBLE_MODE;
18047 + else if (iface_speed == E_ENET_SPEED_1000)
18048 + tmp |= MACCFG2_BYTE_MODE;
18049 +
18050 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
18051 + << PREAMBLE_LENGTH_SHIFT;
18052 +
18053 + if (cfg->rx_preamble)
18054 + tmp |= MACCFG2_PRE_AM_Rx_EN;
18055 + if (cfg->tx_preamble)
18056 + tmp |= MACCFG2_PRE_AM_Tx_EN;
18057 + if (cfg->rx_len_check)
18058 + tmp |= MACCFG2_LENGTH_CHECK;
18059 + if (cfg->tx_pad_crc)
18060 + tmp |= MACCFG2_PAD_CRC_EN;
18061 + if (cfg->tx_crc)
18062 + tmp |= MACCFG2_CRC_EN;
18063 + if (!cfg->halfdup_on)
18064 + tmp |= MACCFG2_FULL_DUPLEX;
18065 + iowrite32be(tmp, &regs->maccfg2);
18066 +
18067 + /***************MACCFG2***********************/
18068 +
18069 + /***************IPGIFG************************/
18070 + tmp = (((cfg->non_back_to_back_ipg1 <<
18071 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
18072 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
18073 + | ((cfg->non_back_to_back_ipg2 <<
18074 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
18075 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
18076 + | ((cfg->min_ifg_enforcement <<
18077 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
18078 + & IPGIFG_MIN_IFG_ENFORCEMENT)
18079 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
18080 + iowrite32be(tmp, &regs->ipgifg);
18081 +
18082 + /***************IPGIFG************************/
18083 +
18084 + /***************HAFDUP************************/
18085 + tmp = 0;
18086 +
18087 + if (cfg->halfdup_alt_backoff_en)
18088 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
18089 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
18090 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
18091 + if (cfg->halfdup_bp_no_backoff)
18092 + tmp |= HAFDUP_BP_NO_BACKOFF;
18093 + if (cfg->halfdup_no_backoff)
18094 + tmp |= HAFDUP_NO_BACKOFF;
18095 + if (cfg->halfdup_excess_defer)
18096 + tmp |= HAFDUP_EXCESS_DEFER;
18097 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
18098 + & HAFDUP_RETRANSMISSION_MAX);
18099 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
18100 +
18101 + iowrite32be(tmp, &regs->hafdup);
18102 + /***************HAFDUP************************/
18103 +
18104 + /***************MAXFRM************************/
18105 + /* Initialize MAXFRM */
18106 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
18107 +
18108 + /***************MAXFRM************************/
18109 +
18110 + /***************CAM1************************/
18111 + iowrite32be(0xffffffff, &regs->cam1);
18112 + iowrite32be(0xffffffff, &regs->cam2);
18113 +
18114 + /***************IMASK************************/
18115 + iowrite32be(exception_mask, &regs->imask);
18116 + /***************IMASK************************/
18117 +
18118 + /***************IEVENT************************/
18119 + iowrite32be(0xffffffff, &regs->ievent);
18120 +
18121 + /***************MACSTNADDR1/2*****************/
18122 +
18123 + tmp = (uint32_t)((macaddr[5] << 24) |
18124 + (macaddr[4] << 16) |
18125 + (macaddr[3] << 8) |
18126 + macaddr[2]);
18127 + iowrite32be(tmp, &regs->macstnaddr1);
18128 +
18129 + tmp = (uint32_t)((macaddr[1] << 24) |
18130 + (macaddr[0] << 16));
18131 + iowrite32be(tmp, &regs->macstnaddr2);
18132 +
18133 + /***************MACSTNADDR1/2*****************/
18134 +
18135 + /*****************HASH************************/
18136 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
18137 + /* Initialize IADDRx */
18138 + iowrite32be(0, &regs->igaddr[i]);
18139 + /* Initialize GADDRx */
18140 + iowrite32be(0, &regs->gaddr[i]);
18141 + }
18142 +
18143 + fman_dtsec_reset_stat(regs);
18144 +
18145 + return 0;
18146 +}
18147 +
18148 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
18149 +{
18150 + return (uint16_t)ioread32be(&regs->maxfrm);
18151 +}
18152 +
18153 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
18154 +{
18155 + iowrite32be(length, &regs->maxfrm);
18156 +}
18157 +
18158 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
18159 +{
18160 + uint32_t tmp;
18161 +
18162 + tmp = (uint32_t)((adr[5] << 24) |
18163 + (adr[4] << 16) |
18164 + (adr[3] << 8) |
18165 + adr[2]);
18166 + iowrite32be(tmp, &regs->macstnaddr1);
18167 +
18168 + tmp = (uint32_t)((adr[1] << 24) |
18169 + (adr[0] << 16));
18170 + iowrite32be(tmp, &regs->macstnaddr2);
18171 +}
18172 +
18173 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
18174 +{
18175 + uint32_t tmp1, tmp2;
18176 +
18177 + tmp1 = ioread32be(&regs->macstnaddr1);
18178 + tmp2 = ioread32be(&regs->macstnaddr2);
18179 +
18180 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
18181 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
18182 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
18183 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
18184 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
18185 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
18186 +}
18187 +
18188 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
18189 +{
18190 + int32_t bucket;
18191 + if (ghtx)
18192 + bucket = (int32_t)((crc >> 23) & 0x1ff);
18193 + else {
18194 + bucket = (int32_t)((crc >> 24) & 0xff);
18195 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
18196 + if (mcast)
18197 + bucket += 0x100;
18198 + }
18199 + fman_dtsec_set_bucket(regs, bucket, TRUE);
18200 +}
18201 +
18202 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
18203 +{
18204 + int reg_idx = (bucket >> 5) & 0xf;
18205 + int bit_idx = bucket & 0x1f;
18206 + uint32_t bit_mask = 0x80000000 >> bit_idx;
18207 + uint32_t *reg;
18208 +
18209 + if (reg_idx > 7)
18210 + reg = &regs->gaddr[reg_idx-8];
18211 + else
18212 + reg = &regs->igaddr[reg_idx];
18213 +
18214 + if (enable)
18215 + iowrite32be(ioread32be(reg) | bit_mask, reg);
18216 + else
18217 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
18218 +}
18219 +
18220 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
18221 +{
18222 + int i;
18223 + bool ghtx;
18224 +
18225 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
18226 +
18227 + if (ucast || (ghtx && mcast)) {
18228 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18229 + iowrite32be(0, &regs->igaddr[i]);
18230 + }
18231 + if (mcast) {
18232 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18233 + iowrite32be(0, &regs->gaddr[i]);
18234 + }
18235 +}
18236 +
18237 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
18238 + uint8_t addr)
18239 +{
18240 + if (addr > 0 && addr < 32)
18241 + iowrite32be(addr, &regs->tbipa);
18242 + else
18243 + return -EINVAL;
18244 +
18245 + return 0;
18246 +}
18247 +
18248 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
18249 +{
18250 + uint32_t tmp;
18251 +
18252 + tmp = ioread32be(&regs->maccfg2);
18253 + if (en)
18254 + tmp |= MACCFG2_MAGIC_PACKET_EN;
18255 + else
18256 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
18257 + iowrite32be(tmp, &regs->maccfg2);
18258 +}
18259 +
18260 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
18261 + enum enet_interface iface_mode,
18262 + enum enet_speed speed, bool full_dx)
18263 +{
18264 + uint32_t tmp;
18265 +
18266 + UNUSED(iface_mode);
18267 +
18268 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
18269 + return -EINVAL;
18270 +
18271 + tmp = ioread32be(&regs->maccfg2);
18272 + if (!full_dx)
18273 + tmp &= ~MACCFG2_FULL_DUPLEX;
18274 + else
18275 + tmp |= MACCFG2_FULL_DUPLEX;
18276 +
18277 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
18278 + if (speed < E_ENET_SPEED_1000)
18279 + tmp |= MACCFG2_NIBBLE_MODE;
18280 + else if (speed == E_ENET_SPEED_1000)
18281 + tmp |= MACCFG2_BYTE_MODE;
18282 + iowrite32be(tmp, &regs->maccfg2);
18283 +
18284 + tmp = ioread32be(&regs->ecntrl);
18285 + if (speed == E_ENET_SPEED_100)
18286 + tmp |= DTSEC_ECNTRL_R100M;
18287 + else
18288 + tmp &= ~DTSEC_ECNTRL_R100M;
18289 + iowrite32be(tmp, &regs->ecntrl);
18290 +
18291 + return 0;
18292 +}
18293 +
18294 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
18295 +{
18296 + uint32_t tmp;
18297 +
18298 + tmp = ioread32be(&regs->rctrl);
18299 +
18300 + if (enable)
18301 + tmp |= RCTRL_UPROM;
18302 + else
18303 + tmp &= ~RCTRL_UPROM;
18304 +
18305 + iowrite32be(tmp, &regs->rctrl);
18306 +}
18307 +
18308 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
18309 +{
18310 + uint32_t tmp;
18311 +
18312 + tmp = ioread32be(&regs->rctrl);
18313 +
18314 + if (enable)
18315 + tmp |= RCTRL_MPROM;
18316 + else
18317 + tmp &= ~RCTRL_MPROM;
18318 +
18319 + iowrite32be(tmp, &regs->rctrl);
18320 +}
18321 +
18322 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
18323 + uint32_t *car1, uint32_t *car2)
18324 +{
18325 + /* read carry registers */
18326 + *car1 = ioread32be(&regs->car1);
18327 + *car2 = ioread32be(&regs->car2);
18328 + /* clear carry registers */
18329 + if (*car1)
18330 + iowrite32be(*car1, &regs->car1);
18331 + if (*car2)
18332 + iowrite32be(*car2, &regs->car2);
18333 +
18334 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
18335 +}
18336 +
18337 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
18338 +{
18339 + /* clear HW counters */
18340 + iowrite32be(ioread32be(&regs->ecntrl) |
18341 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
18342 +}
18343 +
18344 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
18345 +{
18346 + switch (level) {
18347 + case E_MAC_STAT_NONE:
18348 + iowrite32be(0xffffffff, &regs->cam1);
18349 + iowrite32be(0xffffffff, &regs->cam2);
18350 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
18351 + &regs->ecntrl);
18352 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
18353 + &regs->imask);
18354 + break;
18355 + case E_MAC_STAT_PARTIAL:
18356 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
18357 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
18358 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18359 + &regs->ecntrl);
18360 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18361 + &regs->imask);
18362 + break;
18363 + case E_MAC_STAT_MIB_GRP1:
18364 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
18365 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
18366 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18367 + &regs->ecntrl);
18368 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18369 + &regs->imask);
18370 + break;
18371 + case E_MAC_STAT_FULL:
18372 + iowrite32be(0, &regs->cam1);
18373 + iowrite32be(0, &regs->cam2);
18374 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18375 + &regs->ecntrl);
18376 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18377 + &regs->imask);
18378 + break;
18379 + default:
18380 + return -EINVAL;
18381 + }
18382 +
18383 + return 0;
18384 +}
18385 +
18386 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
18387 +{
18388 + if (en) {
18389 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
18390 + &regs->rctrl);
18391 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
18392 + &regs->tctrl);
18393 + } else {
18394 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
18395 + &regs->rctrl);
18396 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
18397 + &regs->tctrl);
18398 + }
18399 +}
18400 +
18401 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18402 +{
18403 + uint32_t tmp;
18404 +
18405 + tmp = ioread32be(&regs->maccfg1);
18406 +
18407 + if (apply_rx)
18408 + tmp |= MACCFG1_RX_EN ;
18409 +
18410 + if (apply_tx)
18411 + tmp |= MACCFG1_TX_EN ;
18412 +
18413 + iowrite32be(tmp, &regs->maccfg1);
18414 +}
18415 +
18416 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
18417 +{
18418 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
18419 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
18420 +}
18421 +
18422 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
18423 + uint64_t addr,
18424 + uint8_t paddr_num)
18425 +{
18426 + uint32_t tmp;
18427 +
18428 + tmp = (uint32_t)(addr);
18429 + /* swap */
18430 + tmp = (((tmp & 0x000000FF) << 24) |
18431 + ((tmp & 0x0000FF00) << 8) |
18432 + ((tmp & 0x00FF0000) >> 8) |
18433 + ((tmp & 0xFF000000) >> 24));
18434 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
18435 +
18436 + tmp = (uint32_t)(addr>>32);
18437 + /* swap */
18438 + tmp = (((tmp & 0x000000FF) << 24) |
18439 + ((tmp & 0x0000FF00) << 8) |
18440 + ((tmp & 0x00FF0000) >> 8) |
18441 + ((tmp & 0xFF000000) >> 24));
18442 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
18443 +}
18444 +
18445 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18446 +{
18447 + uint32_t tmp;
18448 +
18449 + tmp = ioread32be(&regs->maccfg1);
18450 +
18451 + if (apply_rx)
18452 + tmp &= ~MACCFG1_RX_EN;
18453 +
18454 + if (apply_tx)
18455 + tmp &= ~MACCFG1_TX_EN;
18456 +
18457 + iowrite32be(tmp, &regs->maccfg1);
18458 +}
18459 +
18460 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
18461 +{
18462 + uint32_t ptv = 0;
18463 +
18464 + /* fixme: don't enable tx pause for half-duplex */
18465 +
18466 + if (time) {
18467 + ptv = ioread32be(&regs->ptv);
18468 + ptv &= 0xffff0000;
18469 + ptv |= time & 0x0000ffff;
18470 + iowrite32be(ptv, &regs->ptv);
18471 +
18472 + /* trigger the transmission of a flow-control pause frame */
18473 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
18474 + &regs->maccfg1);
18475 + } else
18476 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
18477 + &regs->maccfg1);
18478 +}
18479 +
18480 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
18481 +{
18482 + uint32_t tmp;
18483 +
18484 + /* todo: check if mac is set to full-duplex */
18485 +
18486 + tmp = ioread32be(&regs->maccfg1);
18487 + if (en)
18488 + tmp |= MACCFG1_RX_FLOW;
18489 + else
18490 + tmp &= ~MACCFG1_RX_FLOW;
18491 + iowrite32be(tmp, &regs->maccfg1);
18492 +}
18493 +
18494 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
18495 +{
18496 + return ioread32be(&regs->rctrl);
18497 +}
18498 +
18499 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
18500 +{
18501 + return ioread32be(&regs->tsec_id);
18502 +}
18503 +
18504 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
18505 +{
18506 + return ioread32be(&regs->ievent) & ev_mask;
18507 +}
18508 +
18509 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
18510 +{
18511 + iowrite32be(ev_mask, &regs->ievent);
18512 +}
18513 +
18514 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
18515 +{
18516 + return ioread32be(&regs->imask);
18517 +}
18518 +
18519 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
18520 +{
18521 + uint32_t event;
18522 +
18523 + event = ioread32be(&regs->tmr_pevent);
18524 + event &= ioread32be(&regs->tmr_pemask);
18525 +
18526 + if (event)
18527 + iowrite32be(event, &regs->tmr_pevent);
18528 + return event;
18529 +}
18530 +
18531 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
18532 +{
18533 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
18534 + &regs->tmr_pemask);
18535 +}
18536 +
18537 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
18538 +{
18539 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
18540 + &regs->tmr_pemask);
18541 +}
18542 +
18543 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18544 +{
18545 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
18546 +}
18547 +
18548 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18549 +{
18550 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
18551 +}
18552 +
18553 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
18554 + enum dtsec_stat_counters reg_name)
18555 +{
18556 + uint32_t ret_val;
18557 +
18558 + switch (reg_name) {
18559 + case E_DTSEC_STAT_TR64:
18560 + ret_val = ioread32be(&regs->tr64);
18561 + break;
18562 + case E_DTSEC_STAT_TR127:
18563 + ret_val = ioread32be(&regs->tr127);
18564 + break;
18565 + case E_DTSEC_STAT_TR255:
18566 + ret_val = ioread32be(&regs->tr255);
18567 + break;
18568 + case E_DTSEC_STAT_TR511:
18569 + ret_val = ioread32be(&regs->tr511);
18570 + break;
18571 + case E_DTSEC_STAT_TR1K:
18572 + ret_val = ioread32be(&regs->tr1k);
18573 + break;
18574 + case E_DTSEC_STAT_TRMAX:
18575 + ret_val = ioread32be(&regs->trmax);
18576 + break;
18577 + case E_DTSEC_STAT_TRMGV:
18578 + ret_val = ioread32be(&regs->trmgv);
18579 + break;
18580 + case E_DTSEC_STAT_RBYT:
18581 + ret_val = ioread32be(&regs->rbyt);
18582 + break;
18583 + case E_DTSEC_STAT_RPKT:
18584 + ret_val = ioread32be(&regs->rpkt);
18585 + break;
18586 + case E_DTSEC_STAT_RMCA:
18587 + ret_val = ioread32be(&regs->rmca);
18588 + break;
18589 + case E_DTSEC_STAT_RBCA:
18590 + ret_val = ioread32be(&regs->rbca);
18591 + break;
18592 + case E_DTSEC_STAT_RXPF:
18593 + ret_val = ioread32be(&regs->rxpf);
18594 + break;
18595 + case E_DTSEC_STAT_RALN:
18596 + ret_val = ioread32be(&regs->raln);
18597 + break;
18598 + case E_DTSEC_STAT_RFLR:
18599 + ret_val = ioread32be(&regs->rflr);
18600 + break;
18601 + case E_DTSEC_STAT_RCDE:
18602 + ret_val = ioread32be(&regs->rcde);
18603 + break;
18604 + case E_DTSEC_STAT_RCSE:
18605 + ret_val = ioread32be(&regs->rcse);
18606 + break;
18607 + case E_DTSEC_STAT_RUND:
18608 + ret_val = ioread32be(&regs->rund);
18609 + break;
18610 + case E_DTSEC_STAT_ROVR:
18611 + ret_val = ioread32be(&regs->rovr);
18612 + break;
18613 + case E_DTSEC_STAT_RFRG:
18614 + ret_val = ioread32be(&regs->rfrg);
18615 + break;
18616 + case E_DTSEC_STAT_RJBR:
18617 + ret_val = ioread32be(&regs->rjbr);
18618 + break;
18619 + case E_DTSEC_STAT_RDRP:
18620 + ret_val = ioread32be(&regs->rdrp);
18621 + break;
18622 + case E_DTSEC_STAT_TFCS:
18623 + ret_val = ioread32be(&regs->tfcs);
18624 + break;
18625 + case E_DTSEC_STAT_TBYT:
18626 + ret_val = ioread32be(&regs->tbyt);
18627 + break;
18628 + case E_DTSEC_STAT_TPKT:
18629 + ret_val = ioread32be(&regs->tpkt);
18630 + break;
18631 + case E_DTSEC_STAT_TMCA:
18632 + ret_val = ioread32be(&regs->tmca);
18633 + break;
18634 + case E_DTSEC_STAT_TBCA:
18635 + ret_val = ioread32be(&regs->tbca);
18636 + break;
18637 + case E_DTSEC_STAT_TXPF:
18638 + ret_val = ioread32be(&regs->txpf);
18639 + break;
18640 + case E_DTSEC_STAT_TNCL:
18641 + ret_val = ioread32be(&regs->tncl);
18642 + break;
18643 + case E_DTSEC_STAT_TDRP:
18644 + ret_val = ioread32be(&regs->tdrp);
18645 + break;
18646 + default:
18647 + ret_val = 0;
18648 + }
18649 +
18650 + return ret_val;
18651 +}
18652 --- /dev/null
18653 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18654 @@ -0,0 +1,163 @@
18655 +/*
18656 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18657 + *
18658 + * Redistribution and use in source and binary forms, with or without
18659 + * modification, are permitted provided that the following conditions are met:
18660 + * * Redistributions of source code must retain the above copyright
18661 + * notice, this list of conditions and the following disclaimer.
18662 + * * Redistributions in binary form must reproduce the above copyright
18663 + * notice, this list of conditions and the following disclaimer in the
18664 + * documentation and/or other materials provided with the distribution.
18665 + * * Neither the name of Freescale Semiconductor nor the
18666 + * names of its contributors may be used to endorse or promote products
18667 + * derived from this software without specific prior written permission.
18668 + *
18669 + *
18670 + * ALTERNATIVELY, this software may be distributed under the terms of the
18671 + * GNU General Public License ("GPL") as published by the Free Software
18672 + * Foundation, either version 2 of that License or (at your option) any
18673 + * later version.
18674 + *
18675 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18676 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18677 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18678 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18679 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18680 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18681 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18682 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18683 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18684 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18685 + */
18686 +
18687 +
18688 +#include "common/general.h"
18689 +#include "fsl_fman_dtsec_mii_acc.h"
18690 +
18691 +
18692 +/**
18693 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
18694 + * @dtsec_freq: dtsec clock frequency (in Mhz)
18695 + *
18696 + * This function calculates the dtsec mii clock divider that determines
18697 + * the MII MDC clock. MII MDC clock will be set to work in the range
18698 + * of 1.5 to 2.5Mhz
18699 + * The output of this function is the value of MIIMCFG[MgmtClk] which
18700 + * implicitly determines the divider value.
18701 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
18702 + *
18703 + * The table below which reflects dtsec_mii_get_div() functionality
18704 + * shows the relations among dtsec_freq, MgmtClk, actual divider
18705 + * and the MII frequency:
18706 + *
18707 + * dtsec freq MgmtClk div MII freq Mhz
18708 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
18709 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
18710 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
18711 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
18712 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
18713 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
18714 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
18715 + * [560..frq] 7 (1/28)(1/8) [frq/224]
18716 + *
18717 + * Returns: the MIIMCFG[MgmtClk] appropriate value
18718 + */
18719 +
18720 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
18721 +{
18722 + uint16_t mgmt_clk;
18723 +
18724 + if (dtsec_freq < 80) mgmt_clk = 1;
18725 + else if (dtsec_freq < 120) mgmt_clk = 2;
18726 + else if (dtsec_freq < 160) mgmt_clk = 3;
18727 + else if (dtsec_freq < 200) mgmt_clk = 4;
18728 + else if (dtsec_freq < 280) mgmt_clk = 5;
18729 + else if (dtsec_freq < 400) mgmt_clk = 6;
18730 + else mgmt_clk = 7;
18731 +
18732 + return (uint8_t)mgmt_clk;
18733 +}
18734 +
18735 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
18736 +{
18737 + /* Reset the management interface */
18738 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
18739 + &regs->miimcfg);
18740 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
18741 + &regs->miimcfg);
18742 +}
18743 +
18744 +
18745 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18746 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
18747 +{
18748 + uint32_t tmp;
18749 +
18750 + /* Setup the MII Mgmt clock speed */
18751 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18752 + wmb();
18753 +
18754 + /* Stop the MII management read cycle */
18755 + iowrite32be(0, &regs->miimcom);
18756 + /* Dummy read to make sure MIIMCOM is written */
18757 + tmp = ioread32be(&regs->miimcom);
18758 + wmb();
18759 +
18760 + /* Setting up MII Management Address Register */
18761 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18762 + iowrite32be(tmp, &regs->miimadd);
18763 + wmb();
18764 +
18765 + /* Setting up MII Management Control Register with data */
18766 + iowrite32be((uint32_t)data, &regs->miimcon);
18767 + /* Dummy read to make sure MIIMCON is written */
18768 + tmp = ioread32be(&regs->miimcon);
18769 + wmb();
18770 +
18771 + /* Wait until MII management write is complete */
18772 + /* todo: a timeout could be useful here */
18773 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18774 + /* busy wait */;
18775 +
18776 + return 0;
18777 +}
18778 +
18779 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18780 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
18781 +{
18782 + uint32_t tmp;
18783 +
18784 + /* Setup the MII Mgmt clock speed */
18785 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18786 + wmb();
18787 +
18788 + /* Setting up the MII Management Address Register */
18789 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18790 + iowrite32be(tmp, &regs->miimadd);
18791 + wmb();
18792 +
18793 + /* Perform an MII management read cycle */
18794 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
18795 + /* Dummy read to make sure MIIMCOM is written */
18796 + tmp = ioread32be(&regs->miimcom);
18797 + wmb();
18798 +
18799 + /* Wait until MII management read is complete */
18800 + /* todo: a timeout could be useful here */
18801 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
18802 + /* busy wait */;
18803 +
18804 + /* Read MII management status */
18805 + *data = (uint16_t)ioread32be(&regs->miimstat);
18806 + wmb();
18807 +
18808 + iowrite32be(0, &regs->miimcom);
18809 + /* Dummy read to make sure MIIMCOM is written */
18810 + tmp = ioread32be(&regs->miimcom);
18811 +
18812 + if (*data == 0xffff)
18813 + return -ENXIO;
18814 +
18815 + return 0;
18816 +}
18817 +
18818 --- /dev/null
18819 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
18820 @@ -0,0 +1,511 @@
18821 +/*
18822 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18823 + *
18824 + * Redistribution and use in source and binary forms, with or without
18825 + * modification, are permitted provided that the following conditions are met:
18826 + * * Redistributions of source code must retain the above copyright
18827 + * notice, this list of conditions and the following disclaimer.
18828 + * * Redistributions in binary form must reproduce the above copyright
18829 + * notice, this list of conditions and the following disclaimer in the
18830 + * documentation and/or other materials provided with the distribution.
18831 + * * Neither the name of Freescale Semiconductor nor the
18832 + * names of its contributors may be used to endorse or promote products
18833 + * derived from this software without specific prior written permission.
18834 + *
18835 + *
18836 + * ALTERNATIVELY, this software may be distributed under the terms of the
18837 + * GNU General Public License ("GPL") as published by the Free Software
18838 + * Foundation, either version 2 of that License or (at your option) any
18839 + * later version.
18840 + *
18841 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18842 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18843 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18844 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18845 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18846 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18847 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18848 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18849 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18850 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18851 + */
18852 +
18853 +
18854 +#include "fsl_fman_memac.h"
18855 +
18856 +
18857 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
18858 +{
18859 + return ioread32be(&regs->ievent) & ev_mask;
18860 +}
18861 +
18862 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
18863 +{
18864 + return ioread32be(&regs->imask);
18865 +}
18866 +
18867 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
18868 +{
18869 + iowrite32be(ev_mask, &regs->ievent);
18870 +}
18871 +
18872 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
18873 +{
18874 + uint32_t tmp;
18875 +
18876 + tmp = ioread32be(&regs->command_config);
18877 +
18878 + if (val)
18879 + tmp |= CMD_CFG_PROMIS_EN;
18880 + else
18881 + tmp &= ~CMD_CFG_PROMIS_EN;
18882 +
18883 + iowrite32be(tmp, &regs->command_config);
18884 +}
18885 +
18886 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
18887 + uint8_t paddr_num)
18888 +{
18889 + if (paddr_num == 0) {
18890 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
18891 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
18892 + } else {
18893 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
18894 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
18895 + }
18896 +}
18897 +
18898 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
18899 + uint8_t *adr,
18900 + uint8_t paddr_num)
18901 +{
18902 + uint32_t tmp0, tmp1;
18903 +
18904 + tmp0 = (uint32_t)(adr[0] |
18905 + adr[1] << 8 |
18906 + adr[2] << 16 |
18907 + adr[3] << 24);
18908 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
18909 +
18910 + if (paddr_num == 0) {
18911 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
18912 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
18913 + } else {
18914 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
18915 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
18916 + }
18917 +}
18918 +
18919 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
18920 +{
18921 + uint32_t tmp;
18922 +
18923 + tmp = ioread32be(&regs->command_config);
18924 +
18925 + if (apply_rx)
18926 + tmp |= CMD_CFG_RX_EN;
18927 +
18928 + if (apply_tx)
18929 + tmp |= CMD_CFG_TX_EN;
18930 +
18931 + iowrite32be(tmp, &regs->command_config);
18932 +}
18933 +
18934 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
18935 +{
18936 + uint32_t tmp;
18937 +
18938 + tmp = ioread32be(&regs->command_config);
18939 +
18940 + if (apply_rx)
18941 + tmp &= ~CMD_CFG_RX_EN;
18942 +
18943 + if (apply_tx)
18944 + tmp &= ~CMD_CFG_TX_EN;
18945 +
18946 + iowrite32be(tmp, &regs->command_config);
18947 +}
18948 +
18949 +void fman_memac_reset_stat(struct memac_regs *regs)
18950 +{
18951 + uint32_t tmp;
18952 +
18953 + tmp = ioread32be(&regs->statn_config);
18954 +
18955 + tmp |= STATS_CFG_CLR;
18956 +
18957 + iowrite32be(tmp, &regs->statn_config);
18958 +
18959 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
18960 +}
18961 +
18962 +void fman_memac_reset(struct memac_regs *regs)
18963 +{
18964 + uint32_t tmp;
18965 +
18966 + tmp = ioread32be(&regs->command_config);
18967 +
18968 + tmp |= CMD_CFG_SW_RESET;
18969 +
18970 + iowrite32be(tmp, &regs->command_config);
18971 +
18972 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
18973 +}
18974 +
18975 +int fman_memac_init(struct memac_regs *regs,
18976 + struct memac_cfg *cfg,
18977 + enum enet_interface enet_interface,
18978 + enum enet_speed enet_speed,
18979 + bool slow_10g_if,
18980 + uint32_t exceptions)
18981 +{
18982 + uint32_t tmp;
18983 +
18984 + /* Config */
18985 + tmp = 0;
18986 + if (cfg->wan_mode_enable)
18987 + tmp |= CMD_CFG_WAN_MODE;
18988 + if (cfg->promiscuous_mode_enable)
18989 + tmp |= CMD_CFG_PROMIS_EN;
18990 + if (cfg->pause_forward_enable)
18991 + tmp |= CMD_CFG_PAUSE_FWD;
18992 + if (cfg->pause_ignore)
18993 + tmp |= CMD_CFG_PAUSE_IGNORE;
18994 + if (cfg->tx_addr_ins_enable)
18995 + tmp |= CMD_CFG_TX_ADDR_INS;
18996 + if (cfg->loopback_enable)
18997 + tmp |= CMD_CFG_LOOPBACK_EN;
18998 + if (cfg->cmd_frame_enable)
18999 + tmp |= CMD_CFG_CNT_FRM_EN;
19000 + if (cfg->send_idle_enable)
19001 + tmp |= CMD_CFG_SEND_IDLE;
19002 + if (cfg->no_length_check_enable)
19003 + tmp |= CMD_CFG_NO_LEN_CHK;
19004 + if (cfg->rx_sfd_any)
19005 + tmp |= CMD_CFG_SFD_ANY;
19006 + if (cfg->pad_enable)
19007 + tmp |= CMD_CFG_TX_PAD_EN;
19008 + if (cfg->wake_on_lan)
19009 + tmp |= CMD_CFG_MG;
19010 +
19011 + tmp |= CMD_CFG_CRC_FWD;
19012 +
19013 + iowrite32be(tmp, &regs->command_config);
19014 +
19015 + /* Max Frame Length */
19016 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19017 +
19018 + /* Pause Time */
19019 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
19020 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
19021 +
19022 + /* IF_MODE */
19023 + tmp = 0;
19024 + switch (enet_interface) {
19025 + case E_ENET_IF_XGMII:
19026 + case E_ENET_IF_XFI:
19027 + tmp |= IF_MODE_XGMII;
19028 + break;
19029 + default:
19030 + tmp |= IF_MODE_GMII;
19031 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
19032 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
19033 + }
19034 + iowrite32be(tmp, &regs->if_mode);
19035 +
19036 + /* TX_FIFO_SECTIONS */
19037 + tmp = 0;
19038 + if (enet_interface == E_ENET_IF_XGMII ||
19039 + enet_interface == E_ENET_IF_XFI) {
19040 + if(slow_10g_if) {
19041 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
19042 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19043 + } else {
19044 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
19045 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19046 + }
19047 + } else {
19048 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
19049 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
19050 + }
19051 + iowrite32be(tmp, &regs->tx_fifo_sections);
19052 +
19053 + /* clear all pending events and set-up interrupts */
19054 + fman_memac_ack_event(regs, 0xffffffff);
19055 + fman_memac_set_exception(regs, exceptions, TRUE);
19056 +
19057 + return 0;
19058 +}
19059 +
19060 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
19061 +{
19062 + uint32_t tmp;
19063 +
19064 + tmp = ioread32be(&regs->imask);
19065 + if (enable)
19066 + tmp |= val;
19067 + else
19068 + tmp &= ~val;
19069 +
19070 + iowrite32be(tmp, &regs->imask);
19071 +}
19072 +
19073 +void fman_memac_reset_filter_table(struct memac_regs *regs)
19074 +{
19075 + uint32_t i;
19076 + for (i = 0; i < 64; i++)
19077 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19078 +}
19079 +
19080 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
19081 +{
19082 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19083 +}
19084 +
19085 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
19086 +{
19087 + iowrite32be(val, &regs->hashtable_ctrl);
19088 +}
19089 +
19090 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
19091 +{
19092 + uint32_t tmp;
19093 +
19094 + tmp = ioread32be(&regs->maxfrm);
19095 +
19096 + return(uint16_t)tmp;
19097 +}
19098 +
19099 +
19100 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
19101 + uint8_t priority,
19102 + uint16_t pause_time,
19103 + uint16_t thresh_time)
19104 +{
19105 + uint32_t tmp;
19106 +
19107 + tmp = ioread32be(&regs->tx_fifo_sections);
19108 +
19109 + if (priority == 0xff) {
19110 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
19111 + iowrite32be(tmp, &regs->tx_fifo_sections);
19112 +
19113 + tmp = ioread32be(&regs->command_config);
19114 + tmp &= ~CMD_CFG_PFC_MODE;
19115 + priority = 0;
19116 + } else {
19117 + GET_TX_EMPTY_PFC_VALUE(tmp);
19118 + iowrite32be(tmp, &regs->tx_fifo_sections);
19119 +
19120 + tmp = ioread32be(&regs->command_config);
19121 + tmp |= CMD_CFG_PFC_MODE;
19122 + }
19123 +
19124 + iowrite32be(tmp, &regs->command_config);
19125 +
19126 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
19127 + if (priority % 2)
19128 + tmp &= 0x0000FFFF;
19129 + else
19130 + tmp &= 0xFFFF0000;
19131 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
19132 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
19133 +
19134 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
19135 + if (priority % 2)
19136 + tmp &= 0x0000FFFF;
19137 + else
19138 + tmp &= 0xFFFF0000;
19139 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
19140 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
19141 +}
19142 +
19143 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
19144 +{
19145 + uint32_t tmp;
19146 +
19147 + tmp = ioread32be(&regs->command_config);
19148 + if (enable)
19149 + tmp |= CMD_CFG_PAUSE_IGNORE;
19150 + else
19151 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19152 +
19153 + iowrite32be(tmp, &regs->command_config);
19154 +}
19155 +
19156 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
19157 +{
19158 + uint32_t tmp;
19159 +
19160 + tmp = ioread32be(&regs->command_config);
19161 +
19162 + if (enable)
19163 + tmp |= CMD_CFG_MG;
19164 + else
19165 + tmp &= ~CMD_CFG_MG;
19166 +
19167 + iowrite32be(tmp, &regs->command_config);
19168 +}
19169 +
19170 +#define GET_MEMAC_CNTR_64(bn) \
19171 + (ioread32be(&regs->bn ## _l) | \
19172 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
19173 +
19174 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
19175 + enum memac_counters reg_name)
19176 +{
19177 + uint64_t ret_val;
19178 +
19179 + switch (reg_name) {
19180 + case E_MEMAC_COUNTER_R64:
19181 + ret_val = GET_MEMAC_CNTR_64(r64);
19182 + break;
19183 + case E_MEMAC_COUNTER_R127:
19184 + ret_val = GET_MEMAC_CNTR_64(r127);
19185 + break;
19186 + case E_MEMAC_COUNTER_R255:
19187 + ret_val = GET_MEMAC_CNTR_64(r255);
19188 + break;
19189 + case E_MEMAC_COUNTER_R511:
19190 + ret_val = GET_MEMAC_CNTR_64(r511);
19191 + break;
19192 + case E_MEMAC_COUNTER_R1023:
19193 + ret_val = GET_MEMAC_CNTR_64(r1023);
19194 + break;
19195 + case E_MEMAC_COUNTER_R1518:
19196 + ret_val = GET_MEMAC_CNTR_64(r1518);
19197 + break;
19198 + case E_MEMAC_COUNTER_R1519X:
19199 + ret_val = GET_MEMAC_CNTR_64(r1519x);
19200 + break;
19201 + case E_MEMAC_COUNTER_RFRG:
19202 + ret_val = GET_MEMAC_CNTR_64(rfrg);
19203 + break;
19204 + case E_MEMAC_COUNTER_RJBR:
19205 + ret_val = GET_MEMAC_CNTR_64(rjbr);
19206 + break;
19207 + case E_MEMAC_COUNTER_RDRP:
19208 + ret_val = GET_MEMAC_CNTR_64(rdrp);
19209 + break;
19210 + case E_MEMAC_COUNTER_RALN:
19211 + ret_val = GET_MEMAC_CNTR_64(raln);
19212 + break;
19213 + case E_MEMAC_COUNTER_TUND:
19214 + ret_val = GET_MEMAC_CNTR_64(tund);
19215 + break;
19216 + case E_MEMAC_COUNTER_ROVR:
19217 + ret_val = GET_MEMAC_CNTR_64(rovr);
19218 + break;
19219 + case E_MEMAC_COUNTER_RXPF:
19220 + ret_val = GET_MEMAC_CNTR_64(rxpf);
19221 + break;
19222 + case E_MEMAC_COUNTER_TXPF:
19223 + ret_val = GET_MEMAC_CNTR_64(txpf);
19224 + break;
19225 + case E_MEMAC_COUNTER_ROCT:
19226 + ret_val = GET_MEMAC_CNTR_64(roct);
19227 + break;
19228 + case E_MEMAC_COUNTER_RMCA:
19229 + ret_val = GET_MEMAC_CNTR_64(rmca);
19230 + break;
19231 + case E_MEMAC_COUNTER_RBCA:
19232 + ret_val = GET_MEMAC_CNTR_64(rbca);
19233 + break;
19234 + case E_MEMAC_COUNTER_RPKT:
19235 + ret_val = GET_MEMAC_CNTR_64(rpkt);
19236 + break;
19237 + case E_MEMAC_COUNTER_RUCA:
19238 + ret_val = GET_MEMAC_CNTR_64(ruca);
19239 + break;
19240 + case E_MEMAC_COUNTER_RERR:
19241 + ret_val = GET_MEMAC_CNTR_64(rerr);
19242 + break;
19243 + case E_MEMAC_COUNTER_TOCT:
19244 + ret_val = GET_MEMAC_CNTR_64(toct);
19245 + break;
19246 + case E_MEMAC_COUNTER_TMCA:
19247 + ret_val = GET_MEMAC_CNTR_64(tmca);
19248 + break;
19249 + case E_MEMAC_COUNTER_TBCA:
19250 + ret_val = GET_MEMAC_CNTR_64(tbca);
19251 + break;
19252 + case E_MEMAC_COUNTER_TUCA:
19253 + ret_val = GET_MEMAC_CNTR_64(tuca);
19254 + break;
19255 + case E_MEMAC_COUNTER_TERR:
19256 + ret_val = GET_MEMAC_CNTR_64(terr);
19257 + break;
19258 + default:
19259 + ret_val = 0;
19260 + }
19261 +
19262 + return ret_val;
19263 +}
19264 +
19265 +void fman_memac_adjust_link(struct memac_regs *regs,
19266 + enum enet_interface iface_mode,
19267 + enum enet_speed speed, bool full_dx)
19268 +{
19269 + uint32_t tmp;
19270 +
19271 + tmp = ioread32be(&regs->if_mode);
19272 +
19273 + if (full_dx)
19274 + tmp &= ~IF_MODE_HD;
19275 + else
19276 + tmp |= IF_MODE_HD;
19277 +
19278 + if (iface_mode == E_ENET_IF_RGMII) {
19279 + /* Configure RGMII in manual mode */
19280 + tmp &= ~IF_MODE_RGMII_AUTO;
19281 + tmp &= ~IF_MODE_RGMII_SP_MASK;
19282 +
19283 + if (full_dx)
19284 + tmp |= IF_MODE_RGMII_FD;
19285 + else
19286 + tmp &= ~IF_MODE_RGMII_FD;
19287 +
19288 + switch (speed) {
19289 + case E_ENET_SPEED_1000:
19290 + tmp |= IF_MODE_RGMII_1000;
19291 + break;
19292 + case E_ENET_SPEED_100:
19293 + tmp |= IF_MODE_RGMII_100;
19294 + break;
19295 + case E_ENET_SPEED_10:
19296 + tmp |= IF_MODE_RGMII_10;
19297 + break;
19298 + default:
19299 + break;
19300 + }
19301 + }
19302 +
19303 + iowrite32be(tmp, &regs->if_mode);
19304 +}
19305 +
19306 +void fman_memac_defconfig(struct memac_cfg *cfg)
19307 +{
19308 + cfg->reset_on_init = FALSE;
19309 + cfg->wan_mode_enable = FALSE;
19310 + cfg->promiscuous_mode_enable = FALSE;
19311 + cfg->pause_forward_enable = FALSE;
19312 + cfg->pause_ignore = FALSE;
19313 + cfg->tx_addr_ins_enable = FALSE;
19314 + cfg->loopback_enable = FALSE;
19315 + cfg->cmd_frame_enable = FALSE;
19316 + cfg->rx_error_discard = FALSE;
19317 + cfg->send_idle_enable = FALSE;
19318 + cfg->no_length_check_enable = TRUE;
19319 + cfg->lgth_check_nostdr = FALSE;
19320 + cfg->time_stamp_enable = FALSE;
19321 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19322 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
19323 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
19324 + cfg->pad_enable = TRUE;
19325 + cfg->phy_tx_ena_on = FALSE;
19326 + cfg->rx_sfd_any = FALSE;
19327 + cfg->rx_pbl_fwd = FALSE;
19328 + cfg->tx_pbl_fwd = FALSE;
19329 + cfg->debug_mode = FALSE;
19330 + cfg->wake_on_lan = FALSE;
19331 +}
19332 --- /dev/null
19333 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19334 @@ -0,0 +1,213 @@
19335 +/*
19336 + * Copyright 2008-2013 Freescale Semiconductor Inc.
19337 + *
19338 + * Redistribution and use in source and binary forms, with or without
19339 + * modification, are permitted provided that the following conditions are met:
19340 + * * Redistributions of source code must retain the above copyright
19341 + * notice, this list of conditions and the following disclaimer.
19342 + * * Redistributions in binary form must reproduce the above copyright
19343 + * notice, this list of conditions and the following disclaimer in the
19344 + * documentation and/or other materials provided with the distribution.
19345 + * * Neither the name of Freescale Semiconductor nor the
19346 + * names of its contributors may be used to endorse or promote products
19347 + * derived from this software without specific prior written permission.
19348 + *
19349 + *
19350 + * ALTERNATIVELY, this software may be distributed under the terms of the
19351 + * GNU General Public License ("GPL") as published by the Free Software
19352 + * Foundation, either version 2 of that License or (at your option) any
19353 + * later version.
19354 + *
19355 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19356 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19357 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19358 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19359 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19360 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19361 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19362 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19363 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19364 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19365 + */
19366 +
19367 +
19368 +#include "fsl_fman_memac_mii_acc.h"
19369 +
19370 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19371 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19372 +{
19373 + uint32_t tmp_reg;
19374 +
19375 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19376 + /* Leave only MDIO_CLK_DIV bits set on */
19377 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19378 + /* Set maximum MDIO_HOLD value to allow phy to see
19379 + change of data signal */
19380 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19381 + /* Add 10G interface mode */
19382 + tmp_reg |= MDIO_CFG_ENC45;
19383 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19384 +
19385 + /* Wait for command completion */
19386 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19387 + udelay(1);
19388 +
19389 + /* Specify phy and register to be accessed */
19390 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19391 + iowrite32be(reg, &mii_regs->mdio_addr);
19392 + wmb();
19393 +
19394 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19395 + udelay(1);
19396 +
19397 + /* Write data */
19398 + iowrite32be(data, &mii_regs->mdio_data);
19399 + wmb();
19400 +
19401 + /* Wait for write transaction end */
19402 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19403 + udelay(1);
19404 +}
19405 +
19406 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19407 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19408 +{
19409 + uint32_t tmp_reg;
19410 +
19411 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19412 + /* Leave only MDIO_CLK_DIV bits set on */
19413 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19414 + /* Set maximum MDIO_HOLD value to allow phy to see
19415 + change of data signal */
19416 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19417 + /* Add 10G interface mode */
19418 + tmp_reg |= MDIO_CFG_ENC45;
19419 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19420 +
19421 + /* Wait for command completion */
19422 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19423 + udelay(1);
19424 +
19425 + /* Specify phy and register to be accessed */
19426 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19427 + iowrite32be(reg, &mii_regs->mdio_addr);
19428 + wmb();
19429 +
19430 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19431 + udelay(1);
19432 +
19433 + /* Read cycle */
19434 + tmp_reg = phy_addr;
19435 + tmp_reg |= MDIO_CTL_READ;
19436 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19437 + wmb();
19438 +
19439 + /* Wait for data to be available */
19440 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19441 + udelay(1);
19442 +
19443 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19444 +
19445 + /* Check if there was an error */
19446 + return ioread32be(&mii_regs->mdio_cfg);
19447 +}
19448 +
19449 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19450 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19451 +{
19452 + uint32_t tmp_reg;
19453 +
19454 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19455 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19456 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19457 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19458 +
19459 + /* Wait for command completion */
19460 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19461 + udelay(1);
19462 +
19463 + /* Write transaction */
19464 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19465 + tmp_reg |= reg;
19466 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19467 +
19468 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19469 + udelay(1);
19470 +
19471 + iowrite32be(data, &mii_regs->mdio_data);
19472 +
19473 + wmb();
19474 +
19475 + /* Wait for write transaction to end */
19476 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19477 + udelay(1);
19478 +}
19479 +
19480 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19481 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19482 +{
19483 + uint32_t tmp_reg;
19484 +
19485 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19486 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19487 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19488 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19489 +
19490 + /* Wait for command completion */
19491 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19492 + udelay(1);
19493 +
19494 + /* Read transaction */
19495 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19496 + tmp_reg |= reg;
19497 + tmp_reg |= MDIO_CTL_READ;
19498 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19499 +
19500 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19501 + udelay(1);
19502 +
19503 + /* Wait for data to be available */
19504 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19505 + udelay(1);
19506 +
19507 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19508 +
19509 + /* Check error */
19510 + return ioread32be(&mii_regs->mdio_cfg);
19511 +}
19512 +
19513 +/*****************************************************************************/
19514 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19515 + uint8_t phy_addr, uint8_t reg, uint16_t data,
19516 + enum enet_speed enet_speed)
19517 +{
19518 + /* Figure out interface type - 10G vs 1G.
19519 + In 10G interface both phy_addr and devAddr present. */
19520 + if (enet_speed == E_ENET_SPEED_10000)
19521 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
19522 + else
19523 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
19524 +
19525 + return 0;
19526 +}
19527 +
19528 +/*****************************************************************************/
19529 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19530 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
19531 + enum enet_speed enet_speed)
19532 +{
19533 + uint32_t ans;
19534 + /* Figure out interface type - 10G vs 1G.
19535 + In 10G interface both phy_addr and devAddr present. */
19536 + if (enet_speed == E_ENET_SPEED_10000)
19537 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
19538 + else
19539 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
19540 +
19541 + if (ans & MDIO_CFG_READ_ERR)
19542 + return -EINVAL;
19543 + return 0;
19544 +}
19545 +
19546 +/* ......................................................................... */
19547 +
19548 --- /dev/null
19549 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19550 @@ -0,0 +1,367 @@
19551 +/*
19552 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19553 + *
19554 + * Redistribution and use in source and binary forms, with or without
19555 + * modification, are permitted provided that the following conditions are met:
19556 + * * Redistributions of source code must retain the above copyright
19557 + * notice, this list of conditions and the following disclaimer.
19558 + * * Redistributions in binary form must reproduce the above copyright
19559 + * notice, this list of conditions and the following disclaimer in the
19560 + * documentation and/or other materials provided with the distribution.
19561 + * * Neither the name of Freescale Semiconductor nor the
19562 + * names of its contributors may be used to endorse or promote products
19563 + * derived from this software without specific prior written permission.
19564 + *
19565 + *
19566 + * ALTERNATIVELY, this software may be distributed under the terms of the
19567 + * GNU General Public License ("GPL") as published by the Free Software
19568 + * Foundation, either version 2 of that License or (at your option) any
19569 + * later version.
19570 + *
19571 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19572 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19573 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19574 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19575 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19576 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19577 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19578 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19579 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19580 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19581 + */
19582 +
19583 +
19584 +#include "fsl_fman_tgec.h"
19585 +
19586 +
19587 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
19588 +{
19589 + uint32_t tmp0, tmp1;
19590 +
19591 + tmp0 = (uint32_t)(adr[0] |
19592 + adr[1] << 8 |
19593 + adr[2] << 16 |
19594 + adr[3] << 24);
19595 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19596 + iowrite32be(tmp0, &regs->mac_addr_0);
19597 + iowrite32be(tmp1, &regs->mac_addr_1);
19598 +}
19599 +
19600 +void fman_tgec_reset_stat(struct tgec_regs *regs)
19601 +{
19602 + uint32_t tmp;
19603 +
19604 + tmp = ioread32be(&regs->command_config);
19605 +
19606 + tmp |= CMD_CFG_STAT_CLR;
19607 +
19608 + iowrite32be(tmp, &regs->command_config);
19609 +
19610 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
19611 +}
19612 +
19613 +#define GET_TGEC_CNTR_64(bn) \
19614 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
19615 + ioread32be(&regs->bn ## _l))
19616 +
19617 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
19618 +{
19619 + uint64_t ret_val;
19620 +
19621 + switch (reg_name) {
19622 + case E_TGEC_COUNTER_R64:
19623 + ret_val = GET_TGEC_CNTR_64(r64);
19624 + break;
19625 + case E_TGEC_COUNTER_R127:
19626 + ret_val = GET_TGEC_CNTR_64(r127);
19627 + break;
19628 + case E_TGEC_COUNTER_R255:
19629 + ret_val = GET_TGEC_CNTR_64(r255);
19630 + break;
19631 + case E_TGEC_COUNTER_R511:
19632 + ret_val = GET_TGEC_CNTR_64(r511);
19633 + break;
19634 + case E_TGEC_COUNTER_R1023:
19635 + ret_val = GET_TGEC_CNTR_64(r1023);
19636 + break;
19637 + case E_TGEC_COUNTER_R1518:
19638 + ret_val = GET_TGEC_CNTR_64(r1518);
19639 + break;
19640 + case E_TGEC_COUNTER_R1519X:
19641 + ret_val = GET_TGEC_CNTR_64(r1519x);
19642 + break;
19643 + case E_TGEC_COUNTER_TRFRG:
19644 + ret_val = GET_TGEC_CNTR_64(trfrg);
19645 + break;
19646 + case E_TGEC_COUNTER_TRJBR:
19647 + ret_val = GET_TGEC_CNTR_64(trjbr);
19648 + break;
19649 + case E_TGEC_COUNTER_RDRP:
19650 + ret_val = GET_TGEC_CNTR_64(rdrp);
19651 + break;
19652 + case E_TGEC_COUNTER_RALN:
19653 + ret_val = GET_TGEC_CNTR_64(raln);
19654 + break;
19655 + case E_TGEC_COUNTER_TRUND:
19656 + ret_val = GET_TGEC_CNTR_64(trund);
19657 + break;
19658 + case E_TGEC_COUNTER_TROVR:
19659 + ret_val = GET_TGEC_CNTR_64(trovr);
19660 + break;
19661 + case E_TGEC_COUNTER_RXPF:
19662 + ret_val = GET_TGEC_CNTR_64(rxpf);
19663 + break;
19664 + case E_TGEC_COUNTER_TXPF:
19665 + ret_val = GET_TGEC_CNTR_64(txpf);
19666 + break;
19667 + case E_TGEC_COUNTER_ROCT:
19668 + ret_val = GET_TGEC_CNTR_64(roct);
19669 + break;
19670 + case E_TGEC_COUNTER_RMCA:
19671 + ret_val = GET_TGEC_CNTR_64(rmca);
19672 + break;
19673 + case E_TGEC_COUNTER_RBCA:
19674 + ret_val = GET_TGEC_CNTR_64(rbca);
19675 + break;
19676 + case E_TGEC_COUNTER_RPKT:
19677 + ret_val = GET_TGEC_CNTR_64(rpkt);
19678 + break;
19679 + case E_TGEC_COUNTER_RUCA:
19680 + ret_val = GET_TGEC_CNTR_64(ruca);
19681 + break;
19682 + case E_TGEC_COUNTER_RERR:
19683 + ret_val = GET_TGEC_CNTR_64(rerr);
19684 + break;
19685 + case E_TGEC_COUNTER_TOCT:
19686 + ret_val = GET_TGEC_CNTR_64(toct);
19687 + break;
19688 + case E_TGEC_COUNTER_TMCA:
19689 + ret_val = GET_TGEC_CNTR_64(tmca);
19690 + break;
19691 + case E_TGEC_COUNTER_TBCA:
19692 + ret_val = GET_TGEC_CNTR_64(tbca);
19693 + break;
19694 + case E_TGEC_COUNTER_TUCA:
19695 + ret_val = GET_TGEC_CNTR_64(tuca);
19696 + break;
19697 + case E_TGEC_COUNTER_TERR:
19698 + ret_val = GET_TGEC_CNTR_64(terr);
19699 + break;
19700 + default:
19701 + ret_val = 0;
19702 + }
19703 +
19704 + return ret_val;
19705 +}
19706 +
19707 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19708 +{
19709 + uint32_t tmp;
19710 +
19711 + tmp = ioread32be(&regs->command_config);
19712 + if (apply_rx)
19713 + tmp |= CMD_CFG_RX_EN;
19714 + if (apply_tx)
19715 + tmp |= CMD_CFG_TX_EN;
19716 + iowrite32be(tmp, &regs->command_config);
19717 +}
19718 +
19719 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19720 +{
19721 + uint32_t tmp_reg_32;
19722 +
19723 + tmp_reg_32 = ioread32be(&regs->command_config);
19724 + if (apply_rx)
19725 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
19726 + if (apply_tx)
19727 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
19728 + iowrite32be(tmp_reg_32, &regs->command_config);
19729 +}
19730 +
19731 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
19732 +{
19733 + uint32_t tmp;
19734 +
19735 + tmp = ioread32be(&regs->command_config);
19736 + if (val)
19737 + tmp |= CMD_CFG_PROMIS_EN;
19738 + else
19739 + tmp &= ~CMD_CFG_PROMIS_EN;
19740 + iowrite32be(tmp, &regs->command_config);
19741 +}
19742 +
19743 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
19744 +{
19745 + uint32_t i;
19746 + for (i = 0; i < 512; i++)
19747 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19748 +}
19749 +
19750 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
19751 +{
19752 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
19753 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
19754 +}
19755 +
19756 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
19757 +{
19758 + iowrite32be(value, &regs->hashtable_ctrl);
19759 +}
19760 +
19761 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
19762 +{
19763 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
19764 +}
19765 +
19766 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
19767 +{
19768 + uint32_t tmp;
19769 +
19770 + tmp = ioread32be(&regs->command_config);
19771 + if (en)
19772 + tmp |= CMD_CFG_PAUSE_IGNORE;
19773 + else
19774 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19775 + iowrite32be(tmp, &regs->command_config);
19776 +}
19777 +
19778 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
19779 +{
19780 + uint32_t tmp;
19781 +
19782 + tmp = ioread32be(&regs->command_config);
19783 + if (en)
19784 + tmp |= CMD_CFG_EN_TIMESTAMP;
19785 + else
19786 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
19787 + iowrite32be(tmp, &regs->command_config);
19788 +}
19789 +
19790 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
19791 +{
19792 + return ioread32be(&regs->ievent) & ev_mask;
19793 +}
19794 +
19795 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
19796 +{
19797 + iowrite32be(ev_mask, &regs->ievent);
19798 +}
19799 +
19800 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
19801 +{
19802 + return ioread32be(&regs->imask);
19803 +}
19804 +
19805 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
19806 +{
19807 + uint32_t tmp0, tmp1;
19808 +
19809 + tmp0 = (uint32_t)(adr[0] |
19810 + adr[1] << 8 |
19811 + adr[2] << 16 |
19812 + adr[3] << 24);
19813 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19814 + iowrite32be(tmp0, &regs->mac_addr_2);
19815 + iowrite32be(tmp1, &regs->mac_addr_3);
19816 +}
19817 +
19818 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
19819 +{
19820 + iowrite32be(0, &regs->mac_addr_2);
19821 + iowrite32be(0, &regs->mac_addr_3);
19822 +}
19823 +
19824 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
19825 +{
19826 + return ioread32be(&regs->tgec_id);
19827 +}
19828 +
19829 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19830 +{
19831 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
19832 +}
19833 +
19834 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
19835 +{
19836 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
19837 +}
19838 +
19839 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
19840 +{
19841 + return (uint16_t) ioread32be(&regs->maxfrm);
19842 +}
19843 +
19844 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
19845 +{
19846 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
19847 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
19848 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
19849 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
19850 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
19851 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
19852 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
19853 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
19854 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
19855 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
19856 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
19857 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
19858 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19859 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
19860 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
19861 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
19862 + cfg->skip_fman11_workaround = FALSE;
19863 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
19864 +}
19865 +
19866 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
19867 + uint32_t exception_mask)
19868 +{
19869 + uint32_t tmp;
19870 +
19871 + /* Config */
19872 + tmp = 0x40; /* CRC forward */
19873 + if (cfg->wan_mode_enable)
19874 + tmp |= CMD_CFG_WAN_MODE;
19875 + if (cfg->promiscuous_mode_enable)
19876 + tmp |= CMD_CFG_PROMIS_EN;
19877 + if (cfg->pause_forward_enable)
19878 + tmp |= CMD_CFG_PAUSE_FWD;
19879 + if (cfg->pause_ignore)
19880 + tmp |= CMD_CFG_PAUSE_IGNORE;
19881 + if (cfg->tx_addr_ins_enable)
19882 + tmp |= CMD_CFG_TX_ADDR_INS;
19883 + if (cfg->loopback_enable)
19884 + tmp |= CMD_CFG_LOOPBACK_EN;
19885 + if (cfg->cmd_frame_enable)
19886 + tmp |= CMD_CFG_CMD_FRM_EN;
19887 + if (cfg->rx_error_discard)
19888 + tmp |= CMD_CFG_RX_ER_DISC;
19889 + if (cfg->send_idle_enable)
19890 + tmp |= CMD_CFG_SEND_IDLE;
19891 + if (cfg->no_length_check_enable)
19892 + tmp |= CMD_CFG_NO_LEN_CHK;
19893 + if (cfg->time_stamp_enable)
19894 + tmp |= CMD_CFG_EN_TIMESTAMP;
19895 + iowrite32be(tmp, &regs->command_config);
19896 +
19897 + /* Max Frame Length */
19898 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19899 + /* Pause Time */
19900 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
19901 +
19902 + /* clear all pending events and set-up interrupts */
19903 + fman_tgec_ack_event(regs, 0xffffffff);
19904 + fman_tgec_enable_interrupt(regs, exception_mask);
19905 +
19906 + return 0;
19907 +}
19908 +
19909 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
19910 +{
19911 + uint32_t tmp;
19912 +
19913 + /* restore the default tx ipg Length */
19914 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
19915 +
19916 + iowrite32be(tmp, &regs->tx_ipg_len);
19917 +}
19918 --- /dev/null
19919 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
19920 @@ -0,0 +1,1096 @@
19921 +/*
19922 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19923 + *
19924 + * Redistribution and use in source and binary forms, with or without
19925 + * modification, are permitted provided that the following conditions are met:
19926 + * * Redistributions of source code must retain the above copyright
19927 + * notice, this list of conditions and the following disclaimer.
19928 + * * Redistributions in binary form must reproduce the above copyright
19929 + * notice, this list of conditions and the following disclaimer in the
19930 + * documentation and/or other materials provided with the distribution.
19931 + * * Neither the name of Freescale Semiconductor nor the
19932 + * names of its contributors may be used to endorse or promote products
19933 + * derived from this software without specific prior written permission.
19934 + *
19935 + *
19936 + * ALTERNATIVELY, this software may be distributed under the terms of the
19937 + * GNU General Public License ("GPL") as published by the Free Software
19938 + * Foundation, either version 2 of that License or (at your option) any
19939 + * later version.
19940 + *
19941 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19942 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19943 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19944 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19945 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19946 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19947 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19948 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19949 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19950 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19951 + */
19952 +
19953 +
19954 +/******************************************************************************
19955 + @File memac.c
19956 +
19957 + @Description FM mEMAC driver
19958 +*//***************************************************************************/
19959 +
19960 +#include "std_ext.h"
19961 +#include "string_ext.h"
19962 +#include "error_ext.h"
19963 +#include "xx_ext.h"
19964 +#include "endian_ext.h"
19965 +#include "debug_ext.h"
19966 +
19967 +#include "fm_common.h"
19968 +#include "memac.h"
19969 +
19970 +
19971 +/*****************************************************************************/
19972 +/* Internal routines */
19973 +/*****************************************************************************/
19974 +
19975 +/* ......................................................................... */
19976 +
19977 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
19978 +{
19979 + uint64_t mask1, mask2;
19980 + uint32_t xorVal = 0;
19981 + uint8_t i, j;
19982 +
19983 + for (i=0; i<6; i++)
19984 + {
19985 + mask1 = ethAddr & (uint64_t)0x01;
19986 + ethAddr >>= 1;
19987 +
19988 + for (j=0; j<7; j++)
19989 + {
19990 + mask2 = ethAddr & (uint64_t)0x01;
19991 + mask1 ^= mask2;
19992 + ethAddr >>= 1;
19993 + }
19994 +
19995 + xorVal |= (mask1 << (5-i));
19996 + }
19997 +
19998 + return xorVal;
19999 +}
20000 +
20001 +/* ......................................................................... */
20002 +
20003 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
20004 +{
20005 + uint16_t tmpReg16;
20006 + e_EnetMode enetMode;
20007 +
20008 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20009 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20010 + to 1G one, so MII functions can work correctly. */
20011 + enetMode = p_Memac->enetMode;
20012 +
20013 + /* SGMII mode + AN enable */
20014 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
20015 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
20016 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
20017 +
20018 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20019 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20020 +
20021 + /* Device ability according to SGMII specification */
20022 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
20023 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20024 +
20025 + /* Adjust link timer for SGMII -
20026 + According to Cisco SGMII specification the timer should be 1.6 ms.
20027 + The link_timer register is configured in units of the clock.
20028 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20029 + unit = 1 / (125*10^6 Hz) = 8 ns.
20030 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
20031 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20032 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20033 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
20034 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20035 + we always set up here a value of 2.5 SGMII. */
20036 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
20037 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
20038 +
20039 + /* Restart AN */
20040 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20041 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20042 +
20043 + /* Restore original enet mode */
20044 + p_Memac->enetMode = enetMode;
20045 +}
20046 +
20047 +/* ......................................................................... */
20048 +
20049 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
20050 +{
20051 + uint16_t tmpReg16;
20052 + e_EnetMode enetMode;
20053 +
20054 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20055 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20056 + to 1G one, so MII functions can work correctly. */
20057 + enetMode = p_Memac->enetMode;
20058 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20059 +
20060 + /* 1000BaseX mode */
20061 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
20062 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20063 +
20064 + /* AN Device capability */
20065 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
20066 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20067 +
20068 + /* Adjust link timer for SGMII -
20069 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
20070 + The link_timer register is configured in units of the clock.
20071 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20072 + unit = 1 / (125*10^6 Hz) = 8 ns.
20073 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
20074 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20075 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20076 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
20077 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20078 + we always set up here a value of 2.5 SGMII. */
20079 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
20080 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
20081 +
20082 + /* Restart AN */
20083 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20084 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20085 +
20086 + /* Restore original enet mode */
20087 + p_Memac->enetMode = enetMode;
20088 +}
20089 +
20090 +/* ......................................................................... */
20091 +
20092 +static t_Error CheckInitParameters(t_Memac *p_Memac)
20093 +{
20094 + e_FmMacType portType;
20095 +
20096 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20097 +
20098 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
20099 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
20100 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
20101 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
20102 +
20103 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
20104 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
20105 + if (p_Memac->addr == 0)
20106 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
20107 + if (!p_Memac->f_Exception)
20108 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
20109 + if (!p_Memac->f_Event)
20110 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
20111 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
20112 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
20113 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
20114 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
20115 +
20116 + return E_OK;
20117 +}
20118 +
20119 +/* ........................................................................... */
20120 +
20121 +static void MemacErrException(t_Handle h_Memac)
20122 +{
20123 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20124 + uint32_t event, imask;
20125 +
20126 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20127 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20128 +
20129 + /* Imask include both error and notification/event bits.
20130 + Leaving only error bits enabled by imask.
20131 + The imask error bits are shifted by 16 bits offset from
20132 + their corresponding location in the ievent - hence the >> 16 */
20133 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20134 +
20135 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20136 +
20137 + if (event & MEMAC_IEVNT_TS_ECC_ER)
20138 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
20139 + if (event & MEMAC_IEVNT_TX_ECC_ER)
20140 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
20141 + if (event & MEMAC_IEVNT_RX_ECC_ER)
20142 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
20143 +}
20144 +
20145 +static void MemacException(t_Handle h_Memac)
20146 +{
20147 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20148 + uint32_t event, imask;
20149 +
20150 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20151 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20152 +
20153 + /* Imask include both error and notification/event bits.
20154 + Leaving only error bits enabled by imask.
20155 + The imask error bits are shifted by 16 bits offset from
20156 + their corresponding location in the ievent - hence the >> 16 */
20157 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20158 +
20159 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20160 +
20161 + if (event & MEMAC_IEVNT_MGI)
20162 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
20163 +}
20164 +
20165 +/* ......................................................................... */
20166 +
20167 +static void FreeInitResources(t_Memac *p_Memac)
20168 +{
20169 + e_FmMacType portType;
20170 +
20171 + portType =
20172 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20173 +
20174 + if (portType == e_FM_MAC_10G)
20175 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20176 + else
20177 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20178 +
20179 + /* release the driver's group hash table */
20180 + FreeHashTable(p_Memac->p_MulticastAddrHash);
20181 + p_Memac->p_MulticastAddrHash = NULL;
20182 +
20183 + /* release the driver's individual hash table */
20184 + FreeHashTable(p_Memac->p_UnicastAddrHash);
20185 + p_Memac->p_UnicastAddrHash = NULL;
20186 +}
20187 +
20188 +
20189 +/*****************************************************************************/
20190 +/* mEMAC API routines */
20191 +/*****************************************************************************/
20192 +
20193 +/* ......................................................................... */
20194 +
20195 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
20196 +{
20197 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20198 +
20199 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20200 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20201 +
20202 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20203 +
20204 + return E_OK;
20205 +}
20206 +
20207 +/* ......................................................................... */
20208 +
20209 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
20210 +{
20211 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20212 +
20213 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20214 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20215 +
20216 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20217 +
20218 + return E_OK;
20219 +}
20220 +
20221 +/* ......................................................................... */
20222 +
20223 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
20224 +{
20225 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20226 +
20227 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20228 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20229 +
20230 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
20231 +
20232 + return E_OK;
20233 +}
20234 +
20235 +/* .............................................................................. */
20236 +
20237 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
20238 +{
20239 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20240 +
20241 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20242 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20243 +
20244 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
20245 + RETURN_ERROR(MAJOR, E_CONFLICT,
20246 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
20247 +
20248 + fman_memac_adjust_link(p_Memac->p_MemMap,
20249 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
20250 + (enum enet_speed)speed,
20251 + fullDuplex);
20252 + return E_OK;
20253 +}
20254 +
20255 +
20256 +/*****************************************************************************/
20257 +/* Memac Configs modification functions */
20258 +/*****************************************************************************/
20259 +
20260 +/* ......................................................................... */
20261 +
20262 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
20263 +{
20264 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20265 +
20266 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20267 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20268 +
20269 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
20270 +
20271 + return E_OK;
20272 +}
20273 +
20274 +/* ......................................................................... */
20275 +
20276 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
20277 +{
20278 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20279 +
20280 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20281 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20282 +
20283 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
20284 +
20285 + return E_OK;
20286 +}
20287 +
20288 +/* ......................................................................... */
20289 +
20290 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
20291 +{
20292 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20293 +
20294 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20295 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20296 +
20297 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
20298 +
20299 + return E_OK;
20300 +}
20301 +
20302 +/* ......................................................................... */
20303 +
20304 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
20305 +{
20306 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20307 +
20308 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20309 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20310 +
20311 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
20312 +
20313 + return E_OK;
20314 +}
20315 +
20316 +/* ......................................................................... */
20317 +
20318 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
20319 +{
20320 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20321 +
20322 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20323 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20324 +
20325 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
20326 +
20327 + return E_OK;
20328 +}
20329 +
20330 +/* ......................................................................... */
20331 +
20332 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20333 +{
20334 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20335 + uint32_t bitMask = 0;
20336 +
20337 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20338 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20339 +
20340 + GET_EXCEPTION_FLAG(bitMask, exception);
20341 + if (bitMask)
20342 + {
20343 + if (enable)
20344 + p_Memac->exceptions |= bitMask;
20345 + else
20346 + p_Memac->exceptions &= ~bitMask;
20347 + }
20348 + else
20349 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20350 +
20351 + return E_OK;
20352 +}
20353 +
20354 +/* ......................................................................... */
20355 +
20356 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
20357 +{
20358 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20359 +
20360 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20361 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20362 +
20363 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
20364 +
20365 + return E_OK;
20366 +}
20367 +
20368 +
20369 +/*****************************************************************************/
20370 +/* Memac Run Time API functions */
20371 +/*****************************************************************************/
20372 +
20373 +/* ......................................................................... */
20374 +
20375 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
20376 + uint8_t priority,
20377 + uint16_t pauseTime,
20378 + uint16_t threshTime)
20379 +{
20380 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20381 +
20382 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20383 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20384 +
20385 + if (priority != 0xFF)
20386 + {
20387 + bool PortConfigured, PreFetchEnabled;
20388 +
20389 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
20390 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
20391 +
20392 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
20393 + p_Memac->fmMacControllerDriver.macId,
20394 + &PortConfigured,
20395 + &PreFetchEnabled);
20396 +
20397 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
20398 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20399 +
20400 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
20401 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20402 + }
20403 +
20404 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
20405 +
20406 + return E_OK;
20407 +}
20408 +
20409 +/* ......................................................................... */
20410 +
20411 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
20412 + uint16_t pauseTime)
20413 +{
20414 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
20415 +}
20416 +
20417 +/* ......................................................................... */
20418 +
20419 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
20420 +{
20421 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20422 +
20423 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20424 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20425 +
20426 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
20427 +
20428 + return E_OK;
20429 +}
20430 +
20431 +/* ......................................................................... */
20432 +
20433 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
20434 +{
20435 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20436 +
20437 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20438 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20439 +
20440 + fman_memac_set_wol(p_Memac->p_MemMap, en);
20441 +
20442 + return E_OK;
20443 +}
20444 +
20445 +/* .............................................................................. */
20446 +
20447 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
20448 +{
20449 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20450 +
20451 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20452 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20453 +UNUSED(p_Memac);
20454 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
20455 +
20456 + return E_OK;
20457 +}
20458 +
20459 +/* Counters handling */
20460 +/* ......................................................................... */
20461 +
20462 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
20463 +{
20464 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20465 +
20466 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20467 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20468 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
20469 +
20470 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20471 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20472 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20473 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20474 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20475 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20476 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20477 +/* */
20478 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
20479 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
20480 +
20481 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
20482 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
20483 +
20484 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
20485 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
20486 +/* Pause */
20487 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
20488 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
20489 +
20490 +/* MIB II */
20491 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
20492 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
20493 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
20494 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
20495 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
20496 + + p_Statistics->ifInMcastPkts
20497 + + p_Statistics->ifInBcastPkts;
20498 + p_Statistics->ifInDiscards = 0;
20499 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
20500 +
20501 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
20502 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
20503 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
20504 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
20505 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
20506 + + p_Statistics->ifOutMcastPkts
20507 + + p_Statistics->ifOutBcastPkts;
20508 + p_Statistics->ifOutDiscards = 0;
20509 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
20510 +
20511 + return E_OK;
20512 +}
20513 +
20514 +/* ......................................................................... */
20515 +
20516 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
20517 +{
20518 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20519 +
20520 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20521 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20522 +
20523 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
20524 +
20525 + return E_OK;
20526 +}
20527 +
20528 +/* ......................................................................... */
20529 +
20530 +static t_Error MemacResetCounters (t_Handle h_Memac)
20531 +{
20532 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20533 +
20534 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20535 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20536 +
20537 + fman_memac_reset_stat(p_Memac->p_MemMap);
20538 +
20539 + return E_OK;
20540 +}
20541 +
20542 +/* ......................................................................... */
20543 +
20544 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20545 +{
20546 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20547 + uint64_t ethAddr;
20548 + uint8_t paddrNum;
20549 +
20550 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20551 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20552 +
20553 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20554 +
20555 + if (ethAddr & GROUP_ADDRESS)
20556 + /* Multicast address has no effect in PADDR */
20557 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
20558 +
20559 + /* Make sure no PADDR contains this address */
20560 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20561 + if (p_Memac->indAddrRegUsed[paddrNum])
20562 + if (p_Memac->paddr[paddrNum] == ethAddr)
20563 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
20564 +
20565 + /* Find first unused PADDR */
20566 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20567 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
20568 + {
20569 + /* mark this PADDR as used */
20570 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
20571 + /* store address */
20572 + p_Memac->paddr[paddrNum] = ethAddr;
20573 +
20574 + /* put in hardware */
20575 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
20576 + p_Memac->numOfIndAddrInRegs++;
20577 +
20578 + return E_OK;
20579 + }
20580 +
20581 + /* No free PADDR */
20582 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
20583 +}
20584 +
20585 +/* ......................................................................... */
20586 +
20587 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20588 +{
20589 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20590 + uint64_t ethAddr;
20591 + uint8_t paddrNum;
20592 +
20593 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20594 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20595 +
20596 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20597 +
20598 + /* Find used PADDR containing this address */
20599 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20600 + {
20601 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
20602 + (p_Memac->paddr[paddrNum] == ethAddr))
20603 + {
20604 + /* mark this PADDR as not used */
20605 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
20606 + /* clear in hardware */
20607 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
20608 + p_Memac->numOfIndAddrInRegs--;
20609 +
20610 + return E_OK;
20611 + }
20612 + }
20613 +
20614 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
20615 +}
20616 +
20617 +/* ......................................................................... */
20618 +
20619 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
20620 +{
20621 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20622 +
20623 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20624 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20625 +
20626 + *macId = p_Memac->macId;
20627 +
20628 + return E_OK;
20629 +}
20630 +
20631 +/* ......................................................................... */
20632 +
20633 +
20634 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20635 +{
20636 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20637 + t_EthHashEntry *p_HashEntry;
20638 + uint32_t hash;
20639 + uint64_t ethAddr;
20640 +
20641 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20642 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20643 +
20644 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20645 +
20646 + if (!(ethAddr & GROUP_ADDRESS))
20647 + /* Unicast addresses not supported in hash */
20648 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
20649 +
20650 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20651 +
20652 + /* Create element to be added to the driver hash table */
20653 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
20654 + p_HashEntry->addr = ethAddr;
20655 + INIT_LIST(&p_HashEntry->node);
20656 +
20657 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
20658 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
20659 +
20660 + return E_OK;
20661 +}
20662 +
20663 +/* ......................................................................... */
20664 +
20665 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20666 +{
20667 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20668 + t_EthHashEntry *p_HashEntry = NULL;
20669 + t_List *p_Pos;
20670 + uint32_t hash;
20671 + uint64_t ethAddr;
20672 +
20673 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20674 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20675 +
20676 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20677 +
20678 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20679 +
20680 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20681 + {
20682 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
20683 + if (p_HashEntry->addr == ethAddr)
20684 + {
20685 + LIST_DelAndInit(&p_HashEntry->node);
20686 + XX_Free(p_HashEntry);
20687 + break;
20688 + }
20689 + }
20690 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20691 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
20692 +
20693 + return E_OK;
20694 +}
20695 +
20696 +
20697 +/* ......................................................................... */
20698 +
20699 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20700 +{
20701 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20702 + uint32_t bitMask = 0;
20703 +
20704 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20705 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20706 +
20707 + GET_EXCEPTION_FLAG(bitMask, exception);
20708 + if (bitMask)
20709 + {
20710 + if (enable)
20711 + p_Memac->exceptions |= bitMask;
20712 + else
20713 + p_Memac->exceptions &= ~bitMask;
20714 + }
20715 + else
20716 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20717 +
20718 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
20719 +
20720 + return E_OK;
20721 +}
20722 +
20723 +/* ......................................................................... */
20724 +
20725 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
20726 +{
20727 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20728 +
20729 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
20730 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
20731 +
20732 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
20733 +}
20734 +
20735 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
20736 +{
20737 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20738 + uint8_t i, phyAddr;
20739 +
20740 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
20741 + {
20742 + /* Configure internal SGMII PHY */
20743 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20744 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
20745 + else
20746 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
20747 + }
20748 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
20749 + {
20750 + /* Configure 4 internal SGMII PHYs */
20751 + for (i = 0; i < 4; i++)
20752 + {
20753 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
20754 + phyAddress; the lower 2 bits are used to extend
20755 + register address space and access each one of 4
20756 + ports inside QSGMII. */
20757 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
20758 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
20759 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
20760 + else
20761 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
20762 + }
20763 + }
20764 + return E_OK;
20765 +}
20766 +
20767 +/*****************************************************************************/
20768 +/* mEMAC Init & Free API */
20769 +/*****************************************************************************/
20770 +
20771 +/* ......................................................................... */
20772 +void *g_MemacRegs;
20773 +static t_Error MemacInit(t_Handle h_Memac)
20774 +{
20775 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20776 + struct memac_cfg *p_MemacDriverParam;
20777 + enum enet_interface enet_interface;
20778 + enum enet_speed enet_speed;
20779 + t_EnetAddr ethAddr;
20780 + e_FmMacType portType;
20781 + t_Error err;
20782 + bool slow_10g_if = FALSE;
20783 + if (p_Memac->macId == 3) /* This is a quick WA */
20784 + g_MemacRegs = p_Memac->p_MemMap;
20785 +
20786 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20787 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20788 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
20789 +
20790 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20791 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
20792 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
20793 + slow_10g_if = TRUE;
20794 +
20795 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
20796 +
20797 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
20798 +
20799 + portType =
20800 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20801 +
20802 + /* First, reset the MAC if desired. */
20803 + if (p_MemacDriverParam->reset_on_init)
20804 + fman_memac_reset(p_Memac->p_MemMap);
20805 +
20806 + /* MAC Address */
20807 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
20808 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
20809 +
20810 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
20811 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
20812 +
20813 + fman_memac_init(p_Memac->p_MemMap,
20814 + p_Memac->p_MemacDriverParam,
20815 + enet_interface,
20816 + enet_speed,
20817 + slow_10g_if,
20818 + p_Memac->exceptions);
20819 +
20820 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
20821 + {
20822 + uint32_t tmpReg = 0;
20823 +
20824 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
20825 + /* check the FMAN version - the bug exists only in rev1 */
20826 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
20827 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
20828 + {
20829 + /* MAC strips CRC from received frames - this workaround should
20830 + decrease the likelihood of bug appearance
20831 + */
20832 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
20833 + tmpReg &= ~CMD_CFG_CRC_FWD;
20834 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
20835 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
20836 + }
20837 + }
20838 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
20839 +
20840 + MemacInitInternalPhy(h_Memac);
20841 +
20842 + /* Max Frame Length */
20843 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
20844 + portType,
20845 + p_Memac->fmMacControllerDriver.macId,
20846 + p_MemacDriverParam->max_frame_length);
20847 + if (err)
20848 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
20849 +
20850 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20851 + if (!p_Memac->p_MulticastAddrHash)
20852 + {
20853 + FreeInitResources(p_Memac);
20854 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20855 + }
20856 +
20857 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
20858 + if (!p_Memac->p_UnicastAddrHash)
20859 + {
20860 + FreeInitResources(p_Memac);
20861 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
20862 + }
20863 +
20864 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20865 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20866 + p_Memac->macId,
20867 + e_FM_INTR_TYPE_ERR,
20868 + MemacErrException,
20869 + p_Memac);
20870 +
20871 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
20872 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
20873 + p_Memac->macId,
20874 + e_FM_INTR_TYPE_NORMAL,
20875 + MemacException,
20876 + p_Memac);
20877 +
20878 + XX_Free(p_MemacDriverParam);
20879 + p_Memac->p_MemacDriverParam = NULL;
20880 +
20881 + return E_OK;
20882 +}
20883 +
20884 +/* ......................................................................... */
20885 +
20886 +static t_Error MemacFree(t_Handle h_Memac)
20887 +{
20888 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20889 +
20890 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20891 +
20892 + if (p_Memac->p_MemacDriverParam)
20893 + {
20894 + /* Called after config */
20895 + XX_Free(p_Memac->p_MemacDriverParam);
20896 + p_Memac->p_MemacDriverParam = NULL;
20897 + }
20898 + else
20899 + /* Called after init */
20900 + FreeInitResources(p_Memac);
20901 +
20902 + XX_Free(p_Memac);
20903 +
20904 + return E_OK;
20905 +}
20906 +
20907 +/* ......................................................................... */
20908 +
20909 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
20910 +{
20911 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
20912 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
20913 +
20914 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
20915 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
20916 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
20917 +
20918 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
20919 +
20920 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
20921 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
20922 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
20923 +
20924 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
20925 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
20926 +
20927 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
20928 +
20929 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
20930 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
20931 +
20932 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
20933 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
20934 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
20935 +
20936 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
20937 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
20938 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
20939 +
20940 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
20941 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
20942 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
20943 +
20944 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
20945 +
20946 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
20947 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
20948 +
20949 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
20950 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
20951 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
20952 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
20953 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
20954 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
20955 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
20956 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
20957 +
20958 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
20959 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
20960 +}
20961 +
20962 +
20963 +/*****************************************************************************/
20964 +/* mEMAC Config Main Entry */
20965 +/*****************************************************************************/
20966 +
20967 +/* ......................................................................... */
20968 +
20969 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
20970 +{
20971 + t_Memac *p_Memac;
20972 + struct memac_cfg *p_MemacDriverParam;
20973 + uintptr_t baseAddr;
20974 +
20975 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
20976 +
20977 + baseAddr = p_FmMacParam->baseAddr;
20978 + /* Allocate memory for the mEMAC data structure */
20979 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
20980 + if (!p_Memac)
20981 + {
20982 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
20983 + return NULL;
20984 + }
20985 + memset(p_Memac, 0, sizeof(t_Memac));
20986 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
20987 +
20988 + /* Allocate memory for the mEMAC driver parameters data structure */
20989 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
20990 + if (!p_MemacDriverParam)
20991 + {
20992 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
20993 + XX_Free(p_Memac);
20994 + return NULL;
20995 + }
20996 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
20997 +
20998 + /* Plant parameter structure pointer */
20999 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
21000 +
21001 + fman_memac_defconfig(p_MemacDriverParam);
21002 +
21003 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
21004 +
21005 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
21006 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
21007 +
21008 + p_Memac->enetMode = p_FmMacParam->enetMode;
21009 + p_Memac->macId = p_FmMacParam->macId;
21010 + p_Memac->exceptions = MEMAC_default_exceptions;
21011 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
21012 + p_Memac->f_Event = p_FmMacParam->f_Event;
21013 + p_Memac->h_App = p_FmMacParam->h_App;
21014 +
21015 + return p_Memac;
21016 +}
21017 --- /dev/null
21018 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21019 @@ -0,0 +1,110 @@
21020 +/*
21021 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21022 + *
21023 + * Redistribution and use in source and binary forms, with or without
21024 + * modification, are permitted provided that the following conditions are met:
21025 + * * Redistributions of source code must retain the above copyright
21026 + * notice, this list of conditions and the following disclaimer.
21027 + * * Redistributions in binary form must reproduce the above copyright
21028 + * notice, this list of conditions and the following disclaimer in the
21029 + * documentation and/or other materials provided with the distribution.
21030 + * * Neither the name of Freescale Semiconductor nor the
21031 + * names of its contributors may be used to endorse or promote products
21032 + * derived from this software without specific prior written permission.
21033 + *
21034 + *
21035 + * ALTERNATIVELY, this software may be distributed under the terms of the
21036 + * GNU General Public License ("GPL") as published by the Free Software
21037 + * Foundation, either version 2 of that License or (at your option) any
21038 + * later version.
21039 + *
21040 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21041 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21042 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21043 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21044 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21045 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21046 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21047 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21048 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21049 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21050 + */
21051 +
21052 +
21053 +/******************************************************************************
21054 + @File memac.h
21055 +
21056 + @Description FM Multirate Ethernet MAC (mEMAC)
21057 +*//***************************************************************************/
21058 +#ifndef __MEMAC_H
21059 +#define __MEMAC_H
21060 +
21061 +#include "std_ext.h"
21062 +#include "error_ext.h"
21063 +#include "list_ext.h"
21064 +
21065 +#include "fsl_fman_memac_mii_acc.h"
21066 +#include "fm_mac.h"
21067 +#include "fsl_fman_memac.h"
21068 +
21069 +
21070 +#define MEMAC_default_exceptions \
21071 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
21072 +
21073 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
21074 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
21075 + bitMask = MEMAC_IMASK_TECC_ER; break; \
21076 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
21077 + bitMask = MEMAC_IMASK_RECC_ER; break; \
21078 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
21079 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
21080 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
21081 + bitMask = MEMAC_IMASK_MGI; break; \
21082 + default: bitMask = 0;break;}
21083 +
21084 +
21085 +typedef struct
21086 +{
21087 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
21088 + t_Handle h_App; /**< Handle to the upper layer application */
21089 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
21090 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
21091 + uint64_t addr; /**< MAC address of device */
21092 + e_EnetMode enetMode; /**< Ethernet physical interface */
21093 + t_FmMacExceptionCallback *f_Exception;
21094 + int mdioIrq;
21095 + t_FmMacExceptionCallback *f_Event;
21096 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
21097 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
21098 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
21099 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
21100 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
21101 + bool debugMode;
21102 + uint8_t macId;
21103 + uint32_t exceptions;
21104 + struct memac_cfg *p_MemacDriverParam;
21105 +} t_Memac;
21106 +
21107 +
21108 +/* Internal PHY access */
21109 +#define PHY_MDIO_ADDR 0
21110 +
21111 +/* Internal PHY Registers - SGMII */
21112 +#define PHY_SGMII_CR_PHY_RESET 0x8000
21113 +#define PHY_SGMII_CR_RESET_AN 0x0200
21114 +#define PHY_SGMII_CR_DEF_VAL 0x1140
21115 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
21116 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
21117 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
21118 +#define PHY_SGMII_IF_MODE_AN 0x0002
21119 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
21120 +#define PHY_SGMII_IF_MODE_1000X 0x0000
21121 +
21122 +
21123 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
21124 +
21125 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
21126 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
21127 +
21128 +
21129 +#endif /* __MEMAC_H */
21130 --- /dev/null
21131 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21132 @@ -0,0 +1,78 @@
21133 +/*
21134 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21135 + *
21136 + * Redistribution and use in source and binary forms, with or without
21137 + * modification, are permitted provided that the following conditions are met:
21138 + * * Redistributions of source code must retain the above copyright
21139 + * notice, this list of conditions and the following disclaimer.
21140 + * * Redistributions in binary form must reproduce the above copyright
21141 + * notice, this list of conditions and the following disclaimer in the
21142 + * documentation and/or other materials provided with the distribution.
21143 + * * Neither the name of Freescale Semiconductor nor the
21144 + * names of its contributors may be used to endorse or promote products
21145 + * derived from this software without specific prior written permission.
21146 + *
21147 + *
21148 + * ALTERNATIVELY, this software may be distributed under the terms of the
21149 + * GNU General Public License ("GPL") as published by the Free Software
21150 + * Foundation, either version 2 of that License or (at your option) any
21151 + * later version.
21152 + *
21153 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21154 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21155 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21156 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21157 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21158 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21159 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21160 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21161 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21162 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21163 + */
21164 +
21165 +
21166 +#include "error_ext.h"
21167 +#include "std_ext.h"
21168 +#include "fm_mac.h"
21169 +#include "memac.h"
21170 +#include "xx_ext.h"
21171 +
21172 +#include "fm_common.h"
21173 +#include "memac_mii_acc.h"
21174 +
21175 +
21176 +/*****************************************************************************/
21177 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
21178 + uint8_t phyAddr,
21179 + uint8_t reg,
21180 + uint16_t data)
21181 +{
21182 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21183 +
21184 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21185 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21186 +
21187 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
21188 + phyAddr,
21189 + reg,
21190 + data,
21191 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21192 +}
21193 +
21194 +/*****************************************************************************/
21195 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
21196 + uint8_t phyAddr,
21197 + uint8_t reg,
21198 + uint16_t *p_Data)
21199 +{
21200 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21201 +
21202 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21203 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21204 +
21205 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
21206 + phyAddr,
21207 + reg,
21208 + p_Data,
21209 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21210 +}
21211 --- /dev/null
21212 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21213 @@ -0,0 +1,73 @@
21214 +/*
21215 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21216 + *
21217 + * Redistribution and use in source and binary forms, with or without
21218 + * modification, are permitted provided that the following conditions are met:
21219 + * * Redistributions of source code must retain the above copyright
21220 + * notice, this list of conditions and the following disclaimer.
21221 + * * Redistributions in binary form must reproduce the above copyright
21222 + * notice, this list of conditions and the following disclaimer in the
21223 + * documentation and/or other materials provided with the distribution.
21224 + * * Neither the name of Freescale Semiconductor nor the
21225 + * names of its contributors may be used to endorse or promote products
21226 + * derived from this software without specific prior written permission.
21227 + *
21228 + *
21229 + * ALTERNATIVELY, this software may be distributed under the terms of the
21230 + * GNU General Public License ("GPL") as published by the Free Software
21231 + * Foundation, either version 2 of that License or (at your option) any
21232 + * later version.
21233 + *
21234 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21235 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21236 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21237 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21238 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21239 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21240 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21241 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21242 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21243 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21244 + */
21245 +
21246 +
21247 +#ifndef __MEMAC_MII_ACC_H
21248 +#define __MEMAC_MII_ACC_H
21249 +
21250 +#include "std_ext.h"
21251 +
21252 +
21253 +/* MII Management Registers */
21254 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
21255 +#define MDIO_CFG_CLK_DIV_SHIFT 7
21256 +#define MDIO_CFG_HOLD_MASK 0x0000001c
21257 +#define MDIO_CFG_ENC45 0x00000040
21258 +#define MDIO_CFG_READ_ERR 0x00000002
21259 +#define MDIO_CFG_BSY 0x00000001
21260 +
21261 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
21262 +#define MDIO_CTL_READ 0x00008000
21263 +
21264 +#define MDIO_DATA_BSY 0x80000000
21265 +
21266 +#if defined(__MWERKS__) && !defined(__GNUC__)
21267 +#pragma pack(push,1)
21268 +#endif /* defined(__MWERKS__) && ... */
21269 +
21270 +/*----------------------------------------------------*/
21271 +/* MII Configuration Control Memory Map Registers */
21272 +/*----------------------------------------------------*/
21273 +typedef struct t_MemacMiiAccessMemMap
21274 +{
21275 + volatile uint32_t mdio_cfg; /* 0x030 */
21276 + volatile uint32_t mdio_ctrl; /* 0x034 */
21277 + volatile uint32_t mdio_data; /* 0x038 */
21278 + volatile uint32_t mdio_addr; /* 0x03c */
21279 +} t_MemacMiiAccessMemMap ;
21280 +
21281 +#if defined(__MWERKS__) && !defined(__GNUC__)
21282 +#pragma pack(pop)
21283 +#endif /* defined(__MWERKS__) && ... */
21284 +
21285 +
21286 +#endif /* __MEMAC_MII_ACC_H */
21287 --- /dev/null
21288 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21289 @@ -0,0 +1,975 @@
21290 +/*
21291 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21292 + *
21293 + * Redistribution and use in source and binary forms, with or without
21294 + * modification, are permitted provided that the following conditions are met:
21295 + * * Redistributions of source code must retain the above copyright
21296 + * notice, this list of conditions and the following disclaimer.
21297 + * * Redistributions in binary form must reproduce the above copyright
21298 + * notice, this list of conditions and the following disclaimer in the
21299 + * documentation and/or other materials provided with the distribution.
21300 + * * Neither the name of Freescale Semiconductor nor the
21301 + * names of its contributors may be used to endorse or promote products
21302 + * derived from this software without specific prior written permission.
21303 + *
21304 + *
21305 + * ALTERNATIVELY, this software may be distributed under the terms of the
21306 + * GNU General Public License ("GPL") as published by the Free Software
21307 + * Foundation, either version 2 of that License or (at your option) any
21308 + * later version.
21309 + *
21310 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21311 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21312 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21313 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21314 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21315 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21316 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21317 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21318 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21319 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21320 + */
21321 +
21322 +
21323 +/******************************************************************************
21324 + @File tgec.c
21325 +
21326 + @Description FM 10G MAC ...
21327 +*//***************************************************************************/
21328 +
21329 +#include "std_ext.h"
21330 +#include "string_ext.h"
21331 +#include "error_ext.h"
21332 +#include "xx_ext.h"
21333 +#include "endian_ext.h"
21334 +#include "debug_ext.h"
21335 +#include "crc_mac_addr_ext.h"
21336 +
21337 +#include "fm_common.h"
21338 +#include "fsl_fman_tgec.h"
21339 +#include "tgec.h"
21340 +
21341 +
21342 +/*****************************************************************************/
21343 +/* Internal routines */
21344 +/*****************************************************************************/
21345 +
21346 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
21347 +{
21348 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
21349 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
21350 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21351 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
21352 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
21353 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21354 +
21355 + if (p_Tgec->addr == 0)
21356 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
21357 + if (!p_Tgec->f_Exception)
21358 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
21359 + if (!p_Tgec->f_Event)
21360 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
21361 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21362 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
21363 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21364 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21365 + return E_OK;
21366 +}
21367 +
21368 +/* ......................................................................... */
21369 +
21370 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21371 +{
21372 + uint32_t crc;
21373 +
21374 + /* CRC calculation */
21375 + GET_MAC_ADDR_CRC(ethAddr, crc);
21376 +
21377 + crc = GetMirror32(crc);
21378 +
21379 + return crc;
21380 +}
21381 +
21382 +/* ......................................................................... */
21383 +
21384 +static void TgecErrException(t_Handle h_Tgec)
21385 +{
21386 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21387 + uint32_t event;
21388 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21389 +
21390 + /* do not handle MDIO events */
21391 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21392 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21393 +
21394 + fman_tgec_ack_event(p_TgecMemMap, event);
21395 +
21396 + if (event & TGEC_IMASK_REM_FAULT)
21397 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
21398 + if (event & TGEC_IMASK_LOC_FAULT)
21399 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
21400 + if (event & TGEC_IMASK_TX_ECC_ER)
21401 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21402 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
21403 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
21404 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
21405 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
21406 + if (event & TGEC_IMASK_TX_ER)
21407 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
21408 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
21409 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
21410 + if (event & TGEC_IMASK_RX_ECC_ER)
21411 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21412 + if (event & TGEC_IMASK_RX_JAB_FRM)
21413 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
21414 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
21415 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
21416 + if (event & TGEC_IMASK_RX_RUNT_FRM)
21417 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
21418 + if (event & TGEC_IMASK_RX_FRAG_FRM)
21419 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
21420 + if (event & TGEC_IMASK_RX_LEN_ER)
21421 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
21422 + if (event & TGEC_IMASK_RX_CRC_ER)
21423 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
21424 + if (event & TGEC_IMASK_RX_ALIGN_ER)
21425 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
21426 +}
21427 +
21428 +/* ......................................................................... */
21429 +
21430 +static void TgecException(t_Handle h_Tgec)
21431 +{
21432 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21433 + uint32_t event;
21434 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21435 +
21436 + /* handle only MDIO events */
21437 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21438 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21439 +
21440 + fman_tgec_ack_event(p_TgecMemMap, event);
21441 +
21442 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
21443 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
21444 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
21445 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
21446 +}
21447 +
21448 +/* ......................................................................... */
21449 +
21450 +static void FreeInitResources(t_Tgec *p_Tgec)
21451 +{
21452 + if (p_Tgec->mdioIrq != NO_IRQ)
21453 + {
21454 + XX_DisableIntr(p_Tgec->mdioIrq);
21455 + XX_FreeIntr(p_Tgec->mdioIrq);
21456 + }
21457 +
21458 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
21459 +
21460 + /* release the driver's group hash table */
21461 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
21462 + p_Tgec->p_MulticastAddrHash = NULL;
21463 +
21464 + /* release the driver's individual hash table */
21465 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
21466 + p_Tgec->p_UnicastAddrHash = NULL;
21467 +}
21468 +
21469 +
21470 +/*****************************************************************************/
21471 +/* 10G MAC API routines */
21472 +/*****************************************************************************/
21473 +
21474 +/* ......................................................................... */
21475 +
21476 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
21477 +{
21478 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21479 +
21480 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21481 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21482 +
21483 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21484 +
21485 + return E_OK;
21486 +}
21487 +
21488 +/* ......................................................................... */
21489 +
21490 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
21491 +{
21492 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21493 +
21494 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21495 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21496 +
21497 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21498 +
21499 + return E_OK;
21500 +}
21501 +
21502 +/* ......................................................................... */
21503 +
21504 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
21505 +{
21506 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21507 +
21508 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21509 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21510 +
21511 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
21512 +
21513 + return E_OK;
21514 +}
21515 +
21516 +
21517 +/*****************************************************************************/
21518 +/* Tgec Configs modification functions */
21519 +/*****************************************************************************/
21520 +
21521 +/* ......................................................................... */
21522 +
21523 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
21524 +{
21525 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21526 +
21527 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21528 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21529 +
21530 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
21531 +
21532 + return E_OK;
21533 +}
21534 +
21535 +/* ......................................................................... */
21536 +
21537 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
21538 +{
21539 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21540 +
21541 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21542 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21543 +
21544 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
21545 +
21546 + return E_OK;
21547 +}
21548 +
21549 +/* ......................................................................... */
21550 +
21551 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
21552 +{
21553 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21554 +
21555 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21556 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21557 +
21558 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
21559 +
21560 + return E_OK;
21561 +}
21562 +
21563 +/* ......................................................................... */
21564 +
21565 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
21566 +{
21567 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21568 +
21569 + UNUSED(newVal);
21570 +
21571 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21572 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21573 +
21574 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
21575 +
21576 + return E_OK;
21577 +}
21578 +
21579 +/* ......................................................................... */
21580 +
21581 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21582 +{
21583 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21584 + uint32_t bitMask = 0;
21585 +
21586 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21587 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21588 +
21589 + GET_EXCEPTION_FLAG(bitMask, exception);
21590 + if (bitMask)
21591 + {
21592 + if (enable)
21593 + p_Tgec->exceptions |= bitMask;
21594 + else
21595 + p_Tgec->exceptions &= ~bitMask;
21596 + }
21597 + else
21598 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21599 +
21600 + return E_OK;
21601 +}
21602 +
21603 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21604 +/* ......................................................................... */
21605 +
21606 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
21607 +{
21608 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21609 +
21610 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21611 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21612 +
21613 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
21614 +
21615 + return E_OK;
21616 +}
21617 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21618 +
21619 +
21620 +/*****************************************************************************/
21621 +/* Tgec Run Time API functions */
21622 +/*****************************************************************************/
21623 +
21624 +/* ......................................................................... */
21625 +/* backward compatibility. will be removed in the future. */
21626 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
21627 +{
21628 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21629 +
21630 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21631 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21632 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21633 +
21634 +
21635 + return E_OK;
21636 +}
21637 +
21638 +/* ......................................................................... */
21639 +
21640 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
21641 + uint8_t priority,
21642 + uint16_t pauseTime,
21643 + uint16_t threshTime)
21644 +{
21645 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21646 +
21647 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21648 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21649 +
21650 + UNUSED(priority); UNUSED(threshTime);
21651 +
21652 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21653 +
21654 + return E_OK;
21655 +}
21656 +
21657 +/* ......................................................................... */
21658 +
21659 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
21660 +{
21661 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21662 +
21663 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21664 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21665 +
21666 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
21667 +
21668 + return E_OK;
21669 +}
21670 +
21671 +/* ......................................................................... */
21672 +
21673 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
21674 +{
21675 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21676 + struct tgec_regs *p_TgecMemMap;
21677 +
21678 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21679 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21680 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
21681 +
21682 + p_TgecMemMap = p_Tgec->p_MemMap;
21683 +
21684 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21685 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
21686 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
21687 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
21688 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
21689 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
21690 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
21691 +/* */
21692 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
21693 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
21694 +
21695 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
21696 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
21697 +
21698 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
21699 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
21700 +/* Pause */
21701 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
21702 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
21703 +
21704 +/* MIB II */
21705 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
21706 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
21707 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
21708 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
21709 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
21710 + + p_Statistics->ifInMcastPkts
21711 + + p_Statistics->ifInBcastPkts;
21712 + p_Statistics->ifInDiscards = 0;
21713 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
21714 +
21715 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
21716 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
21717 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
21718 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
21719 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
21720 + + p_Statistics->ifOutMcastPkts
21721 + + p_Statistics->ifOutBcastPkts;
21722 + p_Statistics->ifOutDiscards = 0;
21723 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
21724 +
21725 + return E_OK;
21726 +}
21727 +
21728 +/* ......................................................................... */
21729 +
21730 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
21731 +{
21732 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21733 +
21734 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21735 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21736 +
21737 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
21738 +
21739 + return E_OK;
21740 +}
21741 +
21742 +/* ......................................................................... */
21743 +
21744 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
21745 +{
21746 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21747 +
21748 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21749 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21750 +
21751 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
21752 +
21753 + return E_OK;
21754 +}
21755 +
21756 +/* ......................................................................... */
21757 +
21758 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
21759 +{
21760 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21761 +
21762 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21763 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21764 +
21765 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
21766 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
21767 +
21768 + return E_OK;
21769 +}
21770 +
21771 +/* ......................................................................... */
21772 +
21773 +static t_Error TgecResetCounters (t_Handle h_Tgec)
21774 +{
21775 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21776 +
21777 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21778 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21779 +
21780 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
21781 +
21782 + return E_OK;
21783 +}
21784 +
21785 +/* ......................................................................... */
21786 +
21787 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21788 +{
21789 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21790 + uint64_t ethAddr;
21791 + uint8_t paddrNum;
21792 +
21793 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21794 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21795 +
21796 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21797 +
21798 + if (ethAddr & GROUP_ADDRESS)
21799 + /* Multicast address has no effect in PADDR */
21800 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
21801 +
21802 + /* Make sure no PADDR contains this address */
21803 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21804 + if (p_Tgec->indAddrRegUsed[paddrNum])
21805 + if (p_Tgec->paddr[paddrNum] == ethAddr)
21806 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
21807 +
21808 + /* Find first unused PADDR */
21809 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21810 + {
21811 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
21812 + {
21813 + /* mark this PADDR as used */
21814 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
21815 + /* store address */
21816 + p_Tgec->paddr[paddrNum] = ethAddr;
21817 +
21818 + /* put in hardware */
21819 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
21820 + p_Tgec->numOfIndAddrInRegs++;
21821 +
21822 + return E_OK;
21823 + }
21824 + }
21825 +
21826 + /* No free PADDR */
21827 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
21828 +}
21829 +
21830 +/* ......................................................................... */
21831 +
21832 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21833 +{
21834 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
21835 + uint64_t ethAddr;
21836 + uint8_t paddrNum;
21837 +
21838 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21839 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21840 +
21841 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21842 +
21843 + /* Find used PADDR containing this address */
21844 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
21845 + {
21846 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
21847 + (p_Tgec->paddr[paddrNum] == ethAddr))
21848 + {
21849 + /* mark this PADDR as not used */
21850 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
21851 + /* clear in hardware */
21852 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
21853 + p_Tgec->numOfIndAddrInRegs--;
21854 +
21855 + return E_OK;
21856 + }
21857 + }
21858 +
21859 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
21860 +}
21861 +
21862 +/* ......................................................................... */
21863 +
21864 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21865 +{
21866 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21867 + t_EthHashEntry *p_HashEntry;
21868 + uint32_t crc;
21869 + uint32_t hash;
21870 + uint64_t ethAddr;
21871 +
21872 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21873 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21874 +
21875 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
21876 +
21877 + if (!(ethAddr & GROUP_ADDRESS))
21878 + /* Unicast addresses not supported in hash */
21879 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
21880 +
21881 + /* CRC calculation */
21882 + crc = GetMacAddrHashCode(ethAddr);
21883 +
21884 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
21885 +
21886 + /* Create element to be added to the driver hash table */
21887 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
21888 + p_HashEntry->addr = ethAddr;
21889 + INIT_LIST(&p_HashEntry->node);
21890 +
21891 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
21892 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
21893 +
21894 + return E_OK;
21895 +}
21896 +
21897 +/* ......................................................................... */
21898 +
21899 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
21900 +{
21901 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21902 + t_EthHashEntry *p_HashEntry = NULL;
21903 + t_List *p_Pos;
21904 + uint32_t crc;
21905 + uint32_t hash;
21906 + uint64_t ethAddr;
21907 +
21908 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21909 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21910 +
21911 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
21912 +
21913 + /* CRC calculation */
21914 + crc = GetMacAddrHashCode(ethAddr);
21915 +
21916 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
21917 +
21918 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
21919 + {
21920 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
21921 + if (p_HashEntry->addr == ethAddr)
21922 + {
21923 + LIST_DelAndInit(&p_HashEntry->node);
21924 + XX_Free(p_HashEntry);
21925 + break;
21926 + }
21927 + }
21928 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
21929 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
21930 +
21931 + return E_OK;
21932 +}
21933 +
21934 +/* ......................................................................... */
21935 +
21936 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
21937 +{
21938 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21939 +
21940 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21941 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21942 +
21943 + UNUSED(p_Tgec);
21944 + UNUSED(macId);
21945 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
21946 +}
21947 +
21948 +/* ......................................................................... */
21949 +
21950 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
21951 +{
21952 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21953 +
21954 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21955 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21956 +
21957 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
21958 +
21959 + return E_OK;
21960 +}
21961 +
21962 +/* ......................................................................... */
21963 +
21964 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21965 +{
21966 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21967 + uint32_t bitMask = 0;
21968 +
21969 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21970 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21971 +
21972 + GET_EXCEPTION_FLAG(bitMask, exception);
21973 + if (bitMask)
21974 + {
21975 + if (enable)
21976 + p_Tgec->exceptions |= bitMask;
21977 + else
21978 + p_Tgec->exceptions &= ~bitMask;
21979 + }
21980 + else
21981 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21982 +
21983 + if (enable)
21984 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
21985 + else
21986 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
21987 +
21988 + return E_OK;
21989 +}
21990 +
21991 +/* ......................................................................... */
21992 +
21993 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
21994 +{
21995 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21996 +
21997 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
21998 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
21999 +
22000 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
22001 +}
22002 +
22003 +/* ......................................................................... */
22004 +
22005 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22006 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
22007 +{
22008 + t_Error err;
22009 +
22010 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22011 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
22012 +#endif /* (DEBUG_ERRORS > 0) */
22013 + /* enable and set promiscuous */
22014 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
22015 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
22016 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
22017 + /* disable */
22018 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
22019 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
22020 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22021 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
22022 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22023 + if (err)
22024 + XX_Print("FAILED!\n");
22025 + else
22026 + XX_Print("done.\n");
22027 +#endif /* (DEBUG_ERRORS > 0) */
22028 +
22029 + return err;
22030 +}
22031 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22032 +
22033 +/*****************************************************************************/
22034 +/* FM Init & Free API */
22035 +/*****************************************************************************/
22036 +
22037 +/* ......................................................................... */
22038 +
22039 +static t_Error TgecInit(t_Handle h_Tgec)
22040 +{
22041 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22042 + struct tgec_cfg *p_TgecDriverParam;
22043 + t_EnetAddr ethAddr;
22044 + t_Error err;
22045 +
22046 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22047 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22048 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22049 +
22050 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
22051 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
22052 +
22053 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
22054 +
22055 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
22056 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
22057 +
22058 + /* interrupts */
22059 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
22060 + {
22061 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
22062 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
22063 + }
22064 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
22065 +
22066 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22067 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
22068 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
22069 + {
22070 + FreeInitResources(p_Tgec);
22071 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
22072 + }
22073 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22074 +
22075 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
22076 + if (err)
22077 + {
22078 + FreeInitResources(p_Tgec);
22079 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
22080 + }
22081 +
22082 + /* Max Frame Length */
22083 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
22084 + e_FM_MAC_10G,
22085 + p_Tgec->fmMacControllerDriver.macId,
22086 + p_TgecDriverParam->max_frame_length);
22087 + if (err != E_OK)
22088 + {
22089 + FreeInitResources(p_Tgec);
22090 + RETURN_ERROR(MINOR, err, NO_MSG);
22091 + }
22092 +/* we consider having no IPC a non crasher... */
22093 +
22094 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
22095 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
22096 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
22097 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
22098 +
22099 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22100 + if (!p_Tgec->p_MulticastAddrHash)
22101 + {
22102 + FreeInitResources(p_Tgec);
22103 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22104 + }
22105 +
22106 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22107 + if (!p_Tgec->p_UnicastAddrHash)
22108 + {
22109 + FreeInitResources(p_Tgec);
22110 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22111 + }
22112 +
22113 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
22114 + e_FM_MOD_10G_MAC,
22115 + p_Tgec->macId,
22116 + e_FM_INTR_TYPE_ERR,
22117 + TgecErrException,
22118 + p_Tgec);
22119 + if (p_Tgec->mdioIrq != NO_IRQ)
22120 + {
22121 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
22122 + XX_EnableIntr(p_Tgec->mdioIrq);
22123 + }
22124 +
22125 + XX_Free(p_TgecDriverParam);
22126 + p_Tgec->p_TgecDriverParam = NULL;
22127 +
22128 + return E_OK;
22129 +}
22130 +
22131 +/* ......................................................................... */
22132 +
22133 +static t_Error TgecFree(t_Handle h_Tgec)
22134 +{
22135 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22136 +
22137 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22138 +
22139 + if (p_Tgec->p_TgecDriverParam)
22140 + {
22141 + /* Called after config */
22142 + XX_Free(p_Tgec->p_TgecDriverParam);
22143 + p_Tgec->p_TgecDriverParam = NULL;
22144 + }
22145 + else
22146 + /* Called after init */
22147 + FreeInitResources(p_Tgec);
22148 +
22149 + XX_Free(p_Tgec);
22150 +
22151 + return E_OK;
22152 +}
22153 +
22154 +/* ......................................................................... */
22155 +
22156 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22157 +{
22158 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
22159 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
22160 +
22161 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22162 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
22163 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
22164 +
22165 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
22166 +
22167 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
22168 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
22169 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
22170 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
22171 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
22172 +
22173 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22174 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
22175 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22176 +
22177 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
22178 +
22179 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
22180 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
22181 +
22182 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
22183 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
22184 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
22185 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22186 +
22187 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
22188 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
22189 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
22190 +
22191 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
22192 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
22193 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
22194 +
22195 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
22196 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
22197 +
22198 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
22199 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
22200 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
22201 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
22202 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
22203 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
22204 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
22205 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
22206 +
22207 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
22208 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
22209 +}
22210 +
22211 +
22212 +/*****************************************************************************/
22213 +/* Tgec Config Main Entry */
22214 +/*****************************************************************************/
22215 +
22216 +/* ......................................................................... */
22217 +
22218 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
22219 +{
22220 + t_Tgec *p_Tgec;
22221 + struct tgec_cfg *p_TgecDriverParam;
22222 + uintptr_t baseAddr;
22223 +
22224 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22225 +
22226 + baseAddr = p_FmMacParam->baseAddr;
22227 + /* allocate memory for the UCC GETH data structure. */
22228 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
22229 + if (!p_Tgec)
22230 + {
22231 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
22232 + return NULL;
22233 + }
22234 + memset(p_Tgec, 0, sizeof(t_Tgec));
22235 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
22236 +
22237 + /* allocate memory for the 10G MAC driver parameters data structure. */
22238 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
22239 + if (!p_TgecDriverParam)
22240 + {
22241 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
22242 + XX_Free(p_Tgec);
22243 + return NULL;
22244 + }
22245 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
22246 +
22247 + /* Plant parameter structure pointer */
22248 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
22249 +
22250 + fman_tgec_defconfig(p_TgecDriverParam);
22251 +
22252 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
22253 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
22254 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22255 + p_Tgec->enetMode = p_FmMacParam->enetMode;
22256 + p_Tgec->macId = p_FmMacParam->macId;
22257 + p_Tgec->exceptions = DEFAULT_exceptions;
22258 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
22259 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
22260 + p_Tgec->f_Event = p_FmMacParam->f_Event;
22261 + p_Tgec->h_App = p_FmMacParam->h_App;
22262 +
22263 + return p_Tgec;
22264 +}
22265 --- /dev/null
22266 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22267 @@ -0,0 +1,151 @@
22268 +/*
22269 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22270 + *
22271 + * Redistribution and use in source and binary forms, with or without
22272 + * modification, are permitted provided that the following conditions are met:
22273 + * * Redistributions of source code must retain the above copyright
22274 + * notice, this list of conditions and the following disclaimer.
22275 + * * Redistributions in binary form must reproduce the above copyright
22276 + * notice, this list of conditions and the following disclaimer in the
22277 + * documentation and/or other materials provided with the distribution.
22278 + * * Neither the name of Freescale Semiconductor nor the
22279 + * names of its contributors may be used to endorse or promote products
22280 + * derived from this software without specific prior written permission.
22281 + *
22282 + *
22283 + * ALTERNATIVELY, this software may be distributed under the terms of the
22284 + * GNU General Public License ("GPL") as published by the Free Software
22285 + * Foundation, either version 2 of that License or (at your option) any
22286 + * later version.
22287 + *
22288 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22289 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22290 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22291 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22292 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22293 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22294 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22295 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22296 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22297 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22298 + */
22299 +
22300 +
22301 +/******************************************************************************
22302 + @File tgec.h
22303 +
22304 + @Description FM 10G MAC ...
22305 +*//***************************************************************************/
22306 +#ifndef __TGEC_H
22307 +#define __TGEC_H
22308 +
22309 +#include "std_ext.h"
22310 +#include "error_ext.h"
22311 +#include "list_ext.h"
22312 +#include "enet_ext.h"
22313 +
22314 +#include "tgec_mii_acc.h"
22315 +#include "fm_mac.h"
22316 +
22317 +
22318 +#define DEFAULT_exceptions \
22319 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
22320 + TGEC_IMASK_REM_FAULT | \
22321 + TGEC_IMASK_LOC_FAULT | \
22322 + TGEC_IMASK_TX_ECC_ER | \
22323 + TGEC_IMASK_TX_FIFO_UNFL | \
22324 + TGEC_IMASK_TX_FIFO_OVFL | \
22325 + TGEC_IMASK_TX_ER | \
22326 + TGEC_IMASK_RX_FIFO_OVFL | \
22327 + TGEC_IMASK_RX_ECC_ER | \
22328 + TGEC_IMASK_RX_JAB_FRM | \
22329 + TGEC_IMASK_RX_OVRSZ_FRM | \
22330 + TGEC_IMASK_RX_RUNT_FRM | \
22331 + TGEC_IMASK_RX_FRAG_FRM | \
22332 + TGEC_IMASK_RX_CRC_ER | \
22333 + TGEC_IMASK_RX_ALIGN_ER))
22334 +
22335 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22336 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
22337 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
22338 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
22339 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
22340 + case e_FM_MAC_EX_10G_REM_FAULT: \
22341 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
22342 + case e_FM_MAC_EX_10G_LOC_FAULT: \
22343 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
22344 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22345 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
22346 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
22347 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
22348 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
22349 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
22350 + case e_FM_MAC_EX_10G_TX_ER: \
22351 + bitMask = TGEC_IMASK_TX_ER ; break; \
22352 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
22353 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
22354 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22355 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
22356 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
22357 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
22358 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
22359 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
22360 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
22361 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
22362 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
22363 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
22364 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
22365 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
22366 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
22367 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
22368 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
22369 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
22370 + default: bitMask = 0;break;}
22371 +
22372 +#define MAX_PACKET_ALIGNMENT 31
22373 +#define MAX_INTER_PACKET_GAP 0x7f
22374 +#define MAX_INTER_PALTERNATE_BEB 0x0f
22375 +#define MAX_RETRANSMISSION 0x0f
22376 +#define MAX_COLLISION_WINDOW 0x03ff
22377 +
22378 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
22379 +
22380 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
22381 +
22382 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
22383 +
22384 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
22385 +
22386 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
22387 +#define TGEC_ID_ID 0xffff0000
22388 +#define TGEC_ID_MAC_VERSION 0x0000FF00
22389 +#define TGEC_ID_MAC_REV 0x000000ff
22390 +
22391 +
22392 +typedef struct {
22393 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22394 + t_Handle h_App; /**< Handle to the upper layer application */
22395 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
22396 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
22397 + uint64_t addr; /**< MAC address of device; */
22398 + e_EnetMode enetMode; /**< Ethernet physical interface */
22399 + t_FmMacExceptionCallback *f_Exception;
22400 + int mdioIrq;
22401 + t_FmMacExceptionCallback *f_Event;
22402 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22403 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22404 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22405 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
22406 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
22407 + bool debugMode;
22408 + uint8_t macId;
22409 + uint32_t exceptions;
22410 + struct tgec_cfg *p_TgecDriverParam;
22411 +} t_Tgec;
22412 +
22413 +
22414 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
22415 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22416 +
22417 +
22418 +#endif /* __TGEC_H */
22419 --- /dev/null
22420 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22421 @@ -0,0 +1,139 @@
22422 +/*
22423 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22424 + *
22425 + * Redistribution and use in source and binary forms, with or without
22426 + * modification, are permitted provided that the following conditions are met:
22427 + * * Redistributions of source code must retain the above copyright
22428 + * notice, this list of conditions and the following disclaimer.
22429 + * * Redistributions in binary form must reproduce the above copyright
22430 + * notice, this list of conditions and the following disclaimer in the
22431 + * documentation and/or other materials provided with the distribution.
22432 + * * Neither the name of Freescale Semiconductor nor the
22433 + * names of its contributors may be used to endorse or promote products
22434 + * derived from this software without specific prior written permission.
22435 + *
22436 + *
22437 + * ALTERNATIVELY, this software may be distributed under the terms of the
22438 + * GNU General Public License ("GPL") as published by the Free Software
22439 + * Foundation, either version 2 of that License or (at your option) any
22440 + * later version.
22441 + *
22442 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22443 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22444 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22445 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22446 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22447 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22448 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22449 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22450 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22451 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22452 + */
22453 +
22454 +
22455 +
22456 +#include "error_ext.h"
22457 +#include "std_ext.h"
22458 +#include "fm_mac.h"
22459 +#include "tgec.h"
22460 +#include "xx_ext.h"
22461 +
22462 +#include "fm_common.h"
22463 +
22464 +
22465 +/*****************************************************************************/
22466 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
22467 + uint8_t phyAddr,
22468 + uint8_t reg,
22469 + uint16_t data)
22470 +{
22471 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22472 + t_TgecMiiAccessMemMap *p_MiiAccess;
22473 + uint32_t cfgStatusReg;
22474 +
22475 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22476 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22477 +
22478 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22479 +
22480 + /* Configure MII */
22481 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22482 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22483 + /* (one half of fm clock => 2.5Mhz) */
22484 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22485 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22486 +
22487 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22488 + XX_UDelay (1);
22489 +
22490 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22491 +
22492 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22493 +
22494 + CORE_MemoryBarrier();
22495 +
22496 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22497 + XX_UDelay (1);
22498 +
22499 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
22500 +
22501 + CORE_MemoryBarrier();
22502 +
22503 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22504 + XX_UDelay (1);
22505 +
22506 + return E_OK;
22507 +}
22508 +
22509 +/*****************************************************************************/
22510 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
22511 + uint8_t phyAddr,
22512 + uint8_t reg,
22513 + uint16_t *p_Data)
22514 +{
22515 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22516 + t_TgecMiiAccessMemMap *p_MiiAccess;
22517 + uint32_t cfgStatusReg;
22518 +
22519 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22520 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22521 +
22522 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22523 +
22524 + /* Configure MII */
22525 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22526 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22527 + /* (one half of fm clock => 2.5Mhz) */
22528 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22529 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22530 +
22531 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22532 + XX_UDelay (1);
22533 +
22534 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22535 +
22536 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22537 +
22538 + CORE_MemoryBarrier();
22539 +
22540 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22541 + XX_UDelay (1);
22542 +
22543 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
22544 +
22545 + CORE_MemoryBarrier();
22546 +
22547 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22548 + XX_UDelay (1);
22549 +
22550 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
22551 +
22552 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22553 +
22554 + if (cfgStatusReg & MIIMIND_READ_ERROR)
22555 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
22556 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
22557 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
22558 +
22559 + return E_OK;
22560 +}
22561 --- /dev/null
22562 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22563 @@ -0,0 +1,80 @@
22564 +/*
22565 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22566 + *
22567 + * Redistribution and use in source and binary forms, with or without
22568 + * modification, are permitted provided that the following conditions are met:
22569 + * * Redistributions of source code must retain the above copyright
22570 + * notice, this list of conditions and the following disclaimer.
22571 + * * Redistributions in binary form must reproduce the above copyright
22572 + * notice, this list of conditions and the following disclaimer in the
22573 + * documentation and/or other materials provided with the distribution.
22574 + * * Neither the name of Freescale Semiconductor nor the
22575 + * names of its contributors may be used to endorse or promote products
22576 + * derived from this software without specific prior written permission.
22577 + *
22578 + *
22579 + * ALTERNATIVELY, this software may be distributed under the terms of the
22580 + * GNU General Public License ("GPL") as published by the Free Software
22581 + * Foundation, either version 2 of that License or (at your option) any
22582 + * later version.
22583 + *
22584 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22585 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22586 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22587 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22588 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22589 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22590 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22591 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22592 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22593 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22594 + */
22595 +
22596 +
22597 +#ifndef __TGEC_MII_ACC_H
22598 +#define __TGEC_MII_ACC_H
22599 +
22600 +#include "std_ext.h"
22601 +
22602 +
22603 +/* MII Management Command Register */
22604 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
22605 +#define MIIMCOM_READ_CYCLE 0x00008000
22606 +#define MIIMCOM_SCAN_CYCLE 0x00000800
22607 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
22608 +
22609 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
22610 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
22611 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
22612 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
22613 +
22614 +#define MIIMCOM_DIV_MASK 0x0000ff00
22615 +#define MIIMCOM_DIV_SHIFT 8
22616 +
22617 +/* MII Management Indicator Register */
22618 +#define MIIMIND_BUSY 0x00000001
22619 +#define MIIMIND_READ_ERROR 0x00000002
22620 +
22621 +#define MIIDATA_BUSY 0x80000000
22622 +
22623 +#if defined(__MWERKS__) && !defined(__GNUC__)
22624 +#pragma pack(push,1)
22625 +#endif /* defined(__MWERKS__) && ... */
22626 +
22627 +/*----------------------------------------------------*/
22628 +/* MII Configuration Control Memory Map Registers */
22629 +/*----------------------------------------------------*/
22630 +typedef _Packed struct t_TgecMiiAccessMemMap
22631 +{
22632 + volatile uint32_t mdio_cfg_status; /* 0x030 */
22633 + volatile uint32_t mdio_command; /* 0x034 */
22634 + volatile uint32_t mdio_data; /* 0x038 */
22635 + volatile uint32_t mdio_regaddr; /* 0x03c */
22636 +} _PackedType t_TgecMiiAccessMemMap ;
22637 +
22638 +#if defined(__MWERKS__) && !defined(__GNUC__)
22639 +#pragma pack(pop)
22640 +#endif /* defined(__MWERKS__) && ... */
22641 +
22642 +
22643 +#endif /* __TGEC_MII_ACC_H */
22644 --- /dev/null
22645 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
22646 @@ -0,0 +1,15 @@
22647 +#
22648 +# Makefile for the Freescale Ethernet controllers
22649 +#
22650 +ccflags-y += -DVERSION=\"\"
22651 +#
22652 +#Include netcomm SW specific definitions
22653 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
22654 +
22655 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
22656 +
22657 +ccflags-y += -I$(NCSW_FM_INC)
22658 +
22659 +obj-y += fsl-ncsw-macsec.o
22660 +
22661 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
22662 --- /dev/null
22663 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
22664 @@ -0,0 +1,237 @@
22665 +/*
22666 + * Copyright 2008-2015 Freescale Semiconductor Inc.
22667 + *
22668 + * Redistribution and use in source and binary forms, with or without
22669 + * modification, are permitted provided that the following conditions are met:
22670 + * * Redistributions of source code must retain the above copyright
22671 + * notice, this list of conditions and the following disclaimer.
22672 + * * Redistributions in binary form must reproduce the above copyright
22673 + * notice, this list of conditions and the following disclaimer in the
22674 + * documentation and/or other materials provided with the distribution.
22675 + * * Neither the name of Freescale Semiconductor nor the
22676 + * names of its contributors may be used to endorse or promote products
22677 + * derived from this software without specific prior written permission.
22678 + *
22679 + *
22680 + * ALTERNATIVELY, this software may be distributed under the terms of the
22681 + * GNU General Public License ("GPL") as published by the Free Software
22682 + * Foundation, either version 2 of that License or (at your option) any
22683 + * later version.
22684 + *
22685 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22686 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22687 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22688 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22689 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22690 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22691 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22692 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22693 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22694 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22695 + */
22696 +/******************************************************************************
22697 +
22698 + @File fm_macsec.c
22699 +
22700 + @Description FM MACSEC driver routines implementation.
22701 +*//***************************************************************************/
22702 +
22703 +#include "std_ext.h"
22704 +#include "error_ext.h"
22705 +#include "xx_ext.h"
22706 +#include "string_ext.h"
22707 +#include "sprint_ext.h"
22708 +#include "debug_ext.h"
22709 +
22710 +#include "fm_macsec.h"
22711 +
22712 +
22713 +/****************************************/
22714 +/* API Init unit functions */
22715 +/****************************************/
22716 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
22717 +{
22718 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
22719 +
22720 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
22721 +
22722 + if (p_FmMacsecParam->guestMode)
22723 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
22724 + else
22725 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
22726 +
22727 + if (!p_FmMacsecControllerDriver)
22728 + return NULL;
22729 +
22730 + return (t_Handle)p_FmMacsecControllerDriver;
22731 +}
22732 +
22733 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
22734 +{
22735 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22736 +
22737 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22738 +
22739 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
22740 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
22741 +
22742 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22743 +}
22744 +
22745 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
22746 +{
22747 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22748 +
22749 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22750 +
22751 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
22752 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
22753 +
22754 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22755 +}
22756 +
22757 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
22758 +{
22759 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22760 +
22761 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22762 +
22763 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
22764 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
22765 +
22766 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22767 +}
22768 +
22769 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
22770 +{
22771 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22772 +
22773 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22774 +
22775 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
22776 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
22777 +
22778 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22779 +}
22780 +
22781 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
22782 +{
22783 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22784 +
22785 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22786 +
22787 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
22788 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
22789 +
22790 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22791 +}
22792 +
22793 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
22794 +{
22795 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22796 +
22797 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22798 +
22799 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
22800 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
22801 +
22802 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22803 +}
22804 +
22805 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
22806 +{
22807 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22808 +
22809 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22810 +
22811 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
22812 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
22813 +
22814 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22815 +}
22816 +
22817 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
22818 +{
22819 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22820 +
22821 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22822 +
22823 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
22824 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
22825 +
22826 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22827 +}
22828 +
22829 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
22830 +{
22831 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22832 +
22833 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22834 +
22835 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
22836 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
22837 +
22838 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22839 +}
22840 +
22841 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
22842 +{
22843 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22844 +
22845 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22846 +
22847 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
22848 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
22849 +
22850 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22851 +}
22852 +
22853 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
22854 +{
22855 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22856 +
22857 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22858 +
22859 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
22860 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
22861 +
22862 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22863 +}
22864 +
22865 +
22866 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
22867 +{
22868 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22869 +
22870 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22871 +
22872 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
22873 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
22874 +
22875 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22876 +}
22877 +
22878 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
22879 +{
22880 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22881 +
22882 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22883 +
22884 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
22885 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
22886 +
22887 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22888 +}
22889 +
22890 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
22891 +{
22892 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
22893 +
22894 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
22895 +
22896 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
22897 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
22898 +
22899 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
22900 +}
22901 +
22902 --- /dev/null
22903 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
22904 @@ -0,0 +1,203 @@
22905 +/*
22906 + * Copyright 2008-2015 Freescale Semiconductor Inc.
22907 + *
22908 + * Redistribution and use in source and binary forms, with or without
22909 + * modification, are permitted provided that the following conditions are met:
22910 + * * Redistributions of source code must retain the above copyright
22911 + * notice, this list of conditions and the following disclaimer.
22912 + * * Redistributions in binary form must reproduce the above copyright
22913 + * notice, this list of conditions and the following disclaimer in the
22914 + * documentation and/or other materials provided with the distribution.
22915 + * * Neither the name of Freescale Semiconductor nor the
22916 + * names of its contributors may be used to endorse or promote products
22917 + * derived from this software without specific prior written permission.
22918 + *
22919 + *
22920 + * ALTERNATIVELY, this software may be distributed under the terms of the
22921 + * GNU General Public License ("GPL") as published by the Free Software
22922 + * Foundation, either version 2 of that License or (at your option) any
22923 + * later version.
22924 + *
22925 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22926 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22927 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22928 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22929 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22930 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22931 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22932 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22933 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22934 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22935 + */
22936 +
22937 +/******************************************************************************
22938 + @File fm_macsec.h
22939 +
22940 + @Description FM MACSEC internal structures and definitions.
22941 +*//***************************************************************************/
22942 +#ifndef __FM_MACSEC_H
22943 +#define __FM_MACSEC_H
22944 +
22945 +#include "error_ext.h"
22946 +#include "std_ext.h"
22947 +#include "fm_macsec_ext.h"
22948 +
22949 +#include "fm_common.h"
22950 +
22951 +
22952 +#define __ERR_MODULE__ MODULE_FM_MACSEC
22953 +
22954 +
22955 +typedef struct
22956 +{
22957 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
22958 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
22959 +
22960 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
22961 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
22962 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
22963 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
22964 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
22965 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
22966 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
22967 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
22968 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
22969 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
22970 +
22971 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
22972 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
22973 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
22974 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
22975 +
22976 +} t_FmMacsecControllerDriver;
22977 +
22978 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
22979 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
22980 +
22981 +/***********************************************************************/
22982 +/* MACSEC internal routines */
22983 +/***********************************************************************/
22984 +
22985 +/**************************************************************************//**
22986 +
22987 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
22988 +
22989 + @Description FM MACSEC Inter Module functions -
22990 + These are not User API routines but routines that may be called
22991 + from other modules. This will be the case in a single core environment,
22992 + where instead of using the XX messaging mechanism, the routines may be
22993 + called from other modules. In a multicore environment, the other modules may
22994 + be run by other cores and therefore these routines may not be called directly.
22995 +
22996 + @{
22997 +*//***************************************************************************/
22998 +
22999 +#define MAX_NUM_OF_SA_PER_SC 4
23000 +
23001 +typedef enum
23002 +{
23003 + e_SC_RX = 0,
23004 + e_SC_TX
23005 +} e_ScType;
23006 +
23007 +typedef enum
23008 +{
23009 + e_SC_SA_A = 0,
23010 + e_SC_SA_B ,
23011 + e_SC_SA_C ,
23012 + e_SC_SA_D
23013 +} e_ScSaId;
23014 +
23015 +typedef struct
23016 +{
23017 + uint32_t scId;
23018 + macsecSCI_t sci;
23019 + bool replayProtect;
23020 + uint32_t replayWindow;
23021 + e_FmMacsecValidFrameBehavior validateFrames;
23022 + uint16_t confidentialityOffset;
23023 + e_FmMacsecSecYCipherSuite cipherSuite;
23024 +} t_RxScParams;
23025 +
23026 +typedef struct
23027 +{
23028 + uint32_t scId;
23029 + macsecSCI_t sci;
23030 + bool protectFrames;
23031 + e_FmMacsecSciInsertionMode sciInsertionMode;
23032 + bool confidentialityEnable;
23033 + uint16_t confidentialityOffset;
23034 + e_FmMacsecSecYCipherSuite cipherSuite;
23035 +} t_TxScParams;
23036 +
23037 +typedef enum e_FmMacsecGlobalExceptions {
23038 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
23039 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
23040 +} e_FmMacsecGlobalExceptions;
23041 +
23042 +typedef enum e_FmMacsecGlobalEvents {
23043 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
23044 +} e_FmMacsecGlobalEvents;
23045 +
23046 +/**************************************************************************//**
23047 + @Description Enum for inter-module interrupts registration
23048 +*//***************************************************************************/
23049 +typedef enum e_FmMacsecEventModules{
23050 + e_FM_MACSEC_MOD_SC_TX,
23051 + e_FM_MACSEC_MOD_DUMMY_LAST
23052 +} e_FmMacsecEventModules;
23053 +
23054 +typedef enum e_FmMacsecInterModuleEvent {
23055 + e_FM_MACSEC_EV_SC_TX,
23056 + e_FM_MACSEC_EV_ERR_SC_TX,
23057 + e_FM_MACSEC_EV_DUMMY_LAST
23058 +} e_FmMacsecInterModuleEvent;
23059 +
23060 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
23061 +
23062 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
23063 + switch(mod){ \
23064 + case e_FM_MACSEC_MOD_SC_TX: \
23065 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
23066 + e_FM_MACSEC_EV_ERR_SC_TX: \
23067 + e_FM_MACSEC_EV_SC_TX; \
23068 + event += (uint8_t)(2 * id);break; \
23069 + break; \
23070 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
23071 + break;}
23072 +
23073 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23074 + e_FmMacsecEventModules module,
23075 + uint8_t modId,
23076 + e_FmIntrType intrType,
23077 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23078 + t_Handle h_Arg);
23079 +
23080 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23081 + e_FmMacsecEventModules module,
23082 + uint8_t modId,
23083 + e_FmIntrType intrType);
23084 +
23085 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
23086 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
23087 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
23088 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
23089 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
23090 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
23091 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
23092 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
23093 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23094 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23095 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
23096 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
23097 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
23098 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
23099 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
23100 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
23101 +
23102 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
23103 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
23104 +
23105 +
23106 +
23107 +#endif /* __FM_MACSEC_H */
23108 --- /dev/null
23109 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23110 @@ -0,0 +1,59 @@
23111 +/*
23112 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23113 + *
23114 + * Redistribution and use in source and binary forms, with or without
23115 + * modification, are permitted provided that the following conditions are met:
23116 + * * Redistributions of source code must retain the above copyright
23117 + * notice, this list of conditions and the following disclaimer.
23118 + * * Redistributions in binary form must reproduce the above copyright
23119 + * notice, this list of conditions and the following disclaimer in the
23120 + * documentation and/or other materials provided with the distribution.
23121 + * * Neither the name of Freescale Semiconductor nor the
23122 + * names of its contributors may be used to endorse or promote products
23123 + * derived from this software without specific prior written permission.
23124 + *
23125 + *
23126 + * ALTERNATIVELY, this software may be distributed under the terms of the
23127 + * GNU General Public License ("GPL") as published by the Free Software
23128 + * Foundation, either version 2 of that License or (at your option) any
23129 + * later version.
23130 + *
23131 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23132 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23133 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23134 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23135 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23136 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23137 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23138 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23139 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23140 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23141 + */
23142 +
23143 +/******************************************************************************
23144 + @File fm_macsec.c
23145 +
23146 + @Description FM MACSEC driver routines implementation.
23147 +*//***************************************************************************/
23148 +
23149 +#include "std_ext.h"
23150 +#include "error_ext.h"
23151 +#include "xx_ext.h"
23152 +#include "string_ext.h"
23153 +#include "sprint_ext.h"
23154 +#include "debug_ext.h"
23155 +#include "fm_macsec.h"
23156 +
23157 +
23158 +/****************************************/
23159 +/* static functions */
23160 +/****************************************/
23161 +
23162 +/****************************************/
23163 +/* API Init unit functions */
23164 +/****************************************/
23165 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
23166 +{
23167 + UNUSED(p_FmMacsecParam);
23168 + return NULL;
23169 +}
23170 --- /dev/null
23171 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23172 @@ -0,0 +1,1031 @@
23173 +/*
23174 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23175 + *
23176 + * Redistribution and use in source and binary forms, with or without
23177 + * modification, are permitted provided that the following conditions are met:
23178 + * * Redistributions of source code must retain the above copyright
23179 + * notice, this list of conditions and the following disclaimer.
23180 + * * Redistributions in binary form must reproduce the above copyright
23181 + * notice, this list of conditions and the following disclaimer in the
23182 + * documentation and/or other materials provided with the distribution.
23183 + * * Neither the name of Freescale Semiconductor nor the
23184 + * names of its contributors may be used to endorse or promote products
23185 + * derived from this software without specific prior written permission.
23186 + *
23187 + *
23188 + * ALTERNATIVELY, this software may be distributed under the terms of the
23189 + * GNU General Public License ("GPL") as published by the Free Software
23190 + * Foundation, either version 2 of that License or (at your option) any
23191 + * later version.
23192 + *
23193 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23194 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23195 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23196 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23197 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23198 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23199 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23200 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23201 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23202 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23203 + */
23204 +
23205 +/******************************************************************************
23206 + @File fm_macsec.c
23207 +
23208 + @Description FM MACSEC driver routines implementation.
23209 +*//***************************************************************************/
23210 +
23211 +#include "std_ext.h"
23212 +#include "error_ext.h"
23213 +#include "xx_ext.h"
23214 +#include "string_ext.h"
23215 +#include "sprint_ext.h"
23216 +#include "fm_mac_ext.h"
23217 +
23218 +#include "fm_macsec_master.h"
23219 +
23220 +
23221 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
23222 +
23223 +
23224 +/****************************************/
23225 +/* static functions */
23226 +/****************************************/
23227 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
23228 +{
23229 + if (!p_FmMacsec->f_Exception)
23230 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
23231 +
23232 + return E_OK;
23233 +}
23234 +
23235 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
23236 +{
23237 + UNUSED(h_Arg); UNUSED(id);
23238 +
23239 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
23240 +}
23241 +
23242 +static void MacsecEventIsr(t_Handle h_FmMacsec)
23243 +{
23244 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23245 + uint32_t events,event,i;
23246 +
23247 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23248 +
23249 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
23250 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
23251 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
23252 +
23253 + for (i=0; i<NUM_OF_TX_SC; i++)
23254 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
23255 + {
23256 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
23257 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
23258 + }
23259 +}
23260 +
23261 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
23262 +{
23263 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23264 + uint32_t errors,error,i;
23265 +
23266 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23267 +
23268 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
23269 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
23270 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
23271 +
23272 + for (i=0; i<NUM_OF_TX_SC; i++)
23273 + if (errors & FM_MACSEC_EX_TX_SC(i))
23274 + {
23275 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
23276 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
23277 + }
23278 +
23279 + if (errors & FM_MACSEC_EX_ECC)
23280 + {
23281 + uint8_t eccType;
23282 + uint32_t tmpReg;
23283 +
23284 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
23285 + ASSERT_COND(tmpReg & MECC_CAP);
23286 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
23287 +
23288 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
23289 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
23290 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
23291 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
23292 + else
23293 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
23294 + }
23295 +}
23296 +
23297 +static t_Error MacsecInit(t_Handle h_FmMacsec)
23298 +{
23299 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23300 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
23301 + uint32_t tmpReg,i,macId;
23302 +
23303 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23304 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23305 +
23306 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
23307 +
23308 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
23309 +
23310 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
23311 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
23312 +
23313 + tmpReg = 0;
23314 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
23315 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
23316 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
23317 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
23318 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
23319 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
23320 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
23321 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
23322 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
23323 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23324 +
23325 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
23326 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
23327 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
23328 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
23329 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
23330 +
23331 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
23332 +
23333 + if (!p_FmMacsec->userExceptions)
23334 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23335 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23336 +
23337 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
23338 + if (p_FmMacsecDriverParam->reservedSc0)
23339 + p_FmMacsec->numRxScAvailable --;
23340 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
23341 +
23342 + XX_Free(p_FmMacsecDriverParam);
23343 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
23344 +
23345 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23346 + FmRegisterIntr(p_FmMacsec->h_Fm,
23347 + e_FM_MOD_MACSEC,
23348 + (uint8_t)macId,
23349 + e_FM_INTR_TYPE_NORMAL,
23350 + MacsecEventIsr,
23351 + p_FmMacsec);
23352 +
23353 + FmRegisterIntr(p_FmMacsec->h_Fm,
23354 + e_FM_MOD_MACSEC,
23355 + 0,
23356 + e_FM_INTR_TYPE_ERR,
23357 + MacsecErrorIsr,
23358 + p_FmMacsec);
23359 +
23360 + return E_OK;
23361 +}
23362 +
23363 +static t_Error MacsecFree(t_Handle h_FmMacsec)
23364 +{
23365 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23366 + uint32_t macId;
23367 +
23368 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23369 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23370 +
23371 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23372 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23373 + e_FM_MOD_MACSEC,
23374 + (uint8_t)macId,
23375 + e_FM_INTR_TYPE_NORMAL);
23376 +
23377 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23378 + e_FM_MOD_MACSEC,
23379 + 0,
23380 + e_FM_INTR_TYPE_ERR);
23381 +
23382 + if (p_FmMacsec->rxScSpinLock)
23383 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
23384 + if (p_FmMacsec->txScSpinLock)
23385 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
23386 +
23387 + XX_Free(p_FmMacsec);
23388 +
23389 + return E_OK;
23390 +}
23391 +
23392 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23393 +{
23394 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23395 +
23396 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23397 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23398 +
23399 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
23400 +
23401 + return E_OK;
23402 +}
23403 +
23404 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23405 +{
23406 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23407 +
23408 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23409 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23410 +
23411 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
23412 +
23413 + return E_OK;
23414 +}
23415 +
23416 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23417 +{
23418 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23419 +
23420 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23421 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23422 +
23423 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
23424 +
23425 + return E_OK;
23426 +}
23427 +
23428 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23429 +{
23430 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23431 +
23432 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23433 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23434 +
23435 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
23436 +
23437 + return E_OK;
23438 +}
23439 +
23440 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23441 +{
23442 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23443 +
23444 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23445 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23446 +
23447 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
23448 +
23449 + return E_OK;
23450 +}
23451 +
23452 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23453 +{
23454 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23455 +
23456 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23457 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23458 +
23459 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
23460 +
23461 + return E_OK;
23462 +}
23463 +
23464 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23465 +{
23466 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23467 +
23468 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23469 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23470 +
23471 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
23472 +
23473 + return E_OK;
23474 +}
23475 +
23476 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
23477 +{
23478 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23479 +
23480 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23481 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23482 +
23483 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
23484 +
23485 + return E_OK;
23486 +}
23487 +
23488 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23489 +{
23490 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23491 +
23492 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23493 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23494 +
23495 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
23496 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
23497 +
23498 + return E_OK;
23499 +}
23500 +
23501 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23502 +{
23503 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23504 + uint32_t bitMask = 0;
23505 +
23506 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23507 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23508 +
23509 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23510 + if (bitMask)
23511 + {
23512 + if (enable)
23513 + p_FmMacsec->userExceptions |= bitMask;
23514 + else
23515 + p_FmMacsec->userExceptions &= ~bitMask;
23516 + }
23517 + else
23518 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23519 +
23520 + return E_OK;
23521 +}
23522 +
23523 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23524 +{
23525 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23526 +
23527 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23528 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23529 +
23530 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
23531 +
23532 + return E_OK;
23533 +}
23534 +
23535 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
23536 +{
23537 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23538 + uint32_t tmpReg;
23539 +
23540 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23541 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23542 +
23543 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23544 + tmpReg |= CFG_BYPN;
23545 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23546 +
23547 + return E_OK;
23548 +}
23549 +
23550 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
23551 +{
23552 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23553 + uint32_t tmpReg;
23554 +
23555 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23556 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23557 +
23558 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23559 + tmpReg &= ~CFG_BYPN;
23560 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23561 +
23562 + return E_OK;
23563 +}
23564 +
23565 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23566 +{
23567 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23568 + uint32_t bitMask;
23569 +
23570 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23571 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23572 +
23573 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23574 + if (bitMask)
23575 + {
23576 + if (enable)
23577 + p_FmMacsec->userExceptions |= bitMask;
23578 + else
23579 + p_FmMacsec->userExceptions &= ~bitMask;
23580 + }
23581 + else
23582 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23583 +
23584 + if (!p_FmMacsec->userExceptions)
23585 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23586 + else
23587 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
23588 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23589 +
23590 + return E_OK;
23591 +}
23592 +
23593 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
23594 +{
23595 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
23596 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
23597 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
23598 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
23599 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
23600 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
23601 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
23602 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
23603 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
23604 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
23605 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
23606 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
23607 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
23608 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
23609 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
23610 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
23611 +}
23612 +
23613 +/****************************************/
23614 +/* Inter-Module functions */
23615 +/****************************************/
23616 +
23617 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23618 + e_FmMacsecEventModules module,
23619 + uint8_t modId,
23620 + e_FmIntrType intrType,
23621 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23622 + t_Handle h_Arg)
23623 +{
23624 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23625 + uint8_t event= 0;
23626 +
23627 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23628 +
23629 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
23630 +
23631 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23632 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
23633 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
23634 +}
23635 +
23636 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23637 + e_FmMacsecEventModules module,
23638 + uint8_t modId,
23639 + e_FmIntrType intrType)
23640 +{
23641 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23642 + uint8_t event= 0;
23643 +
23644 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23645 +
23646 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
23647 +
23648 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23649 + p_FmMacsec->intrMng[event].f_Isr = NULL;
23650 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
23651 +}
23652 +
23653 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
23654 +{
23655 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23656 + t_Error err = E_OK;
23657 + bool *p_ScTable;
23658 + uint32_t *p_ScAvailable,i;
23659 +
23660 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23661 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23662 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23663 +
23664 + if (type == e_SC_RX)
23665 + {
23666 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23667 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23668 + i = (NUM_OF_RX_SC - 1);
23669 + }
23670 + else
23671 + {
23672 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23673 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23674 + i = (NUM_OF_TX_SC - 1);
23675 +
23676 + }
23677 + if (*p_ScAvailable < numOfScs)
23678 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
23679 +
23680 + if (isPtp)
23681 + {
23682 + i = 0;
23683 + if (p_ScTable[i])
23684 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
23685 + }
23686 +
23687 + for (;numOfScs;i--)
23688 + {
23689 + if (p_ScTable[i])
23690 + continue;
23691 + numOfScs --;
23692 + (*p_ScAvailable)--;
23693 + p_ScIds[numOfScs] = i;
23694 + p_ScTable[i] = TRUE;
23695 + }
23696 +
23697 + return err;
23698 +}
23699 +
23700 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
23701 +{
23702 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23703 + t_Error err = E_OK;
23704 + bool *p_ScTable;
23705 + uint32_t *p_ScAvailable,maxNumOfSc,i;
23706 +
23707 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23708 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
23709 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
23710 +
23711 + if (type == e_SC_RX)
23712 + {
23713 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
23714 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
23715 + maxNumOfSc = NUM_OF_RX_SC;
23716 + }
23717 + else
23718 + {
23719 + p_ScTable = (bool *)p_FmMacsec->txScTable;
23720 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
23721 + maxNumOfSc = NUM_OF_TX_SC;
23722 + }
23723 +
23724 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
23725 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
23726 +
23727 + for (i=0;i<numOfScs;i++)
23728 + {
23729 + p_ScTable[p_ScIds[i]] = FALSE;
23730 + (*p_ScAvailable)++;
23731 + }
23732 +
23733 + return err;
23734 +
23735 +}
23736 +
23737 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
23738 +{
23739 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23740 + uint32_t tmpReg = 0;
23741 +
23742 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23743 +
23744 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23745 + if (enable && (tmpReg & CFG_S0I))
23746 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
23747 +
23748 + if (enable)
23749 + tmpReg |= CFG_S0I;
23750 + else
23751 + tmpReg &= ~CFG_S0I;
23752 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23753 +
23754 + return E_OK;
23755 +}
23756 +
23757 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
23758 +{
23759 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23760 + t_Error err = E_OK;
23761 + uint32_t tmpReg = 0, intFlags;
23762 +
23763 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23764 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
23765 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23766 +
23767 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23768 +
23769 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
23770 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
23771 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
23772 + {
23773 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23774 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
23775 + }
23776 +
23777 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
23778 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
23779 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
23780 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
23781 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
23782 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
23783 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
23784 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23785 +
23786 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
23787 +
23788 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23789 +
23790 + return err;
23791 +}
23792 +
23793 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
23794 +{
23795 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23796 + t_Error err = E_OK;
23797 + uint32_t tmpReg = 0, intFlags;
23798 +
23799 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23800 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23801 +
23802 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23803 +
23804 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
23805 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23806 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
23807 +
23808 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23809 +
23810 + return err;
23811 +}
23812 +
23813 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
23814 +{
23815 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23816 + t_Error err = E_OK;
23817 + uint32_t tmpReg = 0, intFlags;
23818 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
23819 +
23820 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23821 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
23822 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
23823 +
23824 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23825 +
23826 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
23827 +
23828 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
23829 + if (tmpReg & TX_SCCFG_SCE_MASK)
23830 + {
23831 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23832 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
23833 + }
23834 +
23835 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
23836 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
23837 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
23838 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
23839 +
23840 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
23841 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
23842 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
23843 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
23844 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
23845 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
23846 + tmpReg |= TX_SCCFG_SCE_MASK;
23847 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
23848 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
23849 +
23850 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23851 +
23852 + return err;
23853 +}
23854 +
23855 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
23856 +{
23857 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23858 + t_Error err = E_OK;
23859 + uint32_t tmpReg = 0, intFlags;
23860 +
23861 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23862 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
23863 +
23864 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23865 +
23866 + tmpReg &= ~TX_SCCFG_SCE_MASK;
23867 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
23868 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
23869 +
23870 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23871 +
23872 + return err;
23873 +}
23874 +
23875 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
23876 +{
23877 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23878 + t_Error err = E_OK;
23879 + uint32_t tmpReg = 0, intFlags;
23880 +
23881 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23882 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23883 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
23884 +
23885 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23886 +
23887 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23888 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
23889 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
23890 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
23891 +
23892 + tmpReg |= RX_SACFG_ACTIVE;
23893 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
23894 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
23895 +
23896 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23897 +
23898 + return err;
23899 +}
23900 +
23901 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
23902 +{
23903 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23904 + t_Error err = E_OK;
23905 + uint32_t tmpReg = 0, intFlags;
23906 +
23907 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23908 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23909 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
23910 +
23911 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23912 +
23913 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
23914 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
23915 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
23916 +
23917 + tmpReg |= TX_SACFG_ACTIVE;
23918 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
23919 +
23920 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23921 +
23922 + return err;
23923 +}
23924 +
23925 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
23926 +{
23927 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23928 + t_Error err = E_OK;
23929 + uint32_t tmpReg = 0, i, intFlags;
23930 +
23931 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23932 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23933 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
23934 +
23935 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23936 +
23937 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23938 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
23939 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
23940 + for (i=0; i<4; i++)
23941 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
23942 +
23943 + tmpReg |= RX_SACFG_ACTIVE;
23944 + tmpReg &= ~RX_SACFG_EN_MASK;
23945 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
23946 +
23947 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23948 +
23949 + return err;
23950 +}
23951 +
23952 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
23953 +{
23954 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23955 + t_Error err = E_OK;
23956 + uint32_t tmpReg = 0, i, intFlags;
23957 +
23958 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23959 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23960 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
23961 +
23962 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
23963 +
23964 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
23965 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
23966 + for (i=0; i<4; i++)
23967 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
23968 +
23969 + tmpReg |= TX_SACFG_ACTIVE;
23970 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
23971 +
23972 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
23973 +
23974 + return err;
23975 +}
23976 +
23977 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
23978 +{
23979 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23980 + t_Error err = E_OK;
23981 + uint32_t tmpReg = 0, intFlags;
23982 +
23983 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23984 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
23985 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
23986 +
23987 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
23988 +
23989 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
23990 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
23991 + if (enableReceive)
23992 + tmpReg |= RX_SACFG_EN_MASK;
23993 + else
23994 + tmpReg &= ~RX_SACFG_EN_MASK;
23995 +
23996 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
23997 +
23998 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
23999 +
24000 + return err;
24001 +}
24002 +
24003 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
24004 +{
24005 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24006 + t_Error err = E_OK;
24007 + uint32_t intFlags;
24008 +
24009 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24010 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24011 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24012 +
24013 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24014 +
24015 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24016 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
24017 +
24018 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24019 +
24020 + return err;
24021 +}
24022 +
24023 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
24024 +{
24025 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24026 + t_Error err = E_OK;
24027 + uint32_t intFlags;
24028 +
24029 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24030 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24031 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24032 +
24033 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24034 +
24035 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24036 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
24037 +
24038 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24039 +
24040 + return err;
24041 +}
24042 +
24043 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
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_TX_SC, E_INVALID_HANDLE);
24052 +
24053 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24054 +
24055 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24056 +
24057 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24058 +
24059 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
24060 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
24061 +
24062 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24063 +
24064 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24065 +
24066 + return err;
24067 +}
24068 +
24069 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
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(p_An, E_INVALID_HANDLE);
24078 +
24079 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24080 +
24081 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24082 +
24083 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24084 +
24085 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24086 +
24087 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
24088 +
24089 + return err;
24090 +}
24091 +
24092 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
24093 +{
24094 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24095 + uint32_t bitMask;
24096 +
24097 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24098 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24099 +
24100 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
24101 + if (bitMask)
24102 + {
24103 + if (enable)
24104 + p_FmMacsec->exceptions |= bitMask;
24105 + else
24106 + p_FmMacsec->exceptions &= ~bitMask;
24107 + }
24108 + else
24109 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24110 +
24111 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24112 +
24113 + return E_OK;
24114 +}
24115 +
24116 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
24117 +{
24118 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24119 + uint32_t bitMask;
24120 +
24121 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24122 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24123 +
24124 + GET_EVENT_FLAG(bitMask, event, scId);
24125 + if (bitMask)
24126 + {
24127 + if (enable)
24128 + p_FmMacsec->events |= bitMask;
24129 + else
24130 + p_FmMacsec->events &= ~bitMask;
24131 + }
24132 + else
24133 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
24134 +
24135 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
24136 +
24137 + return E_OK;
24138 +}
24139 +
24140 +/****************************************/
24141 +/* API Init unit functions */
24142 +/****************************************/
24143 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
24144 +{
24145 + t_FmMacsec *p_FmMacsec;
24146 + uint32_t macId;
24147 +
24148 + /* Allocate FM MACSEC structure */
24149 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
24150 + if (!p_FmMacsec)
24151 + {
24152 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
24153 + return NULL;
24154 + }
24155 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
24156 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
24157 +
24158 + /* Allocate the FM MACSEC driver's parameters structure */
24159 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
24160 + if (!p_FmMacsec->p_FmMacsecDriverParam)
24161 + {
24162 + XX_Free(p_FmMacsec);
24163 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
24164 + return NULL;
24165 + }
24166 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
24167 +
24168 + /* Initialize FM MACSEC parameters which will be kept by the driver */
24169 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
24170 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
24171 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
24172 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
24173 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
24174 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
24175 + p_FmMacsec->exceptions = DEFAULT_exceptions;
24176 + p_FmMacsec->events = DEFAULT_events;
24177 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
24178 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
24179 +
24180 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
24181 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
24182 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
24183 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
24184 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
24185 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
24186 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
24187 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
24188 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
24189 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
24190 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
24191 + /* build the FM MACSEC master IPC address */
24192 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
24193 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
24194 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
24195 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
24196 + {
24197 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
24198 + XX_Free(p_FmMacsec);
24199 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
24200 + return NULL;
24201 + }
24202 + return p_FmMacsec;
24203 +}
24204 --- /dev/null
24205 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24206 @@ -0,0 +1,479 @@
24207 +/*
24208 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24209 + *
24210 + * Redistribution and use in source and binary forms, with or without
24211 + * modification, are permitted provided that the following conditions are met:
24212 + * * Redistributions of source code must retain the above copyright
24213 + * notice, this list of conditions and the following disclaimer.
24214 + * * Redistributions in binary form must reproduce the above copyright
24215 + * notice, this list of conditions and the following disclaimer in the
24216 + * documentation and/or other materials provided with the distribution.
24217 + * * Neither the name of Freescale Semiconductor nor the
24218 + * names of its contributors may be used to endorse or promote products
24219 + * derived from this software without specific prior written permission.
24220 + *
24221 + *
24222 + * ALTERNATIVELY, this software may be distributed under the terms of the
24223 + * GNU General Public License ("GPL") as published by the Free Software
24224 + * Foundation, either version 2 of that License or (at your option) any
24225 + * later version.
24226 + *
24227 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24228 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24229 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24230 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24231 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24232 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24233 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24234 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24235 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24236 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24237 + */
24238 +
24239 +/******************************************************************************
24240 + @File fm_macsec_master.h
24241 +
24242 + @Description FM MACSEC internal structures and definitions.
24243 +*//***************************************************************************/
24244 +#ifndef __FM_MACSEC_MASTER_H
24245 +#define __FM_MACSEC_MASTER_H
24246 +
24247 +#include "error_ext.h"
24248 +#include "std_ext.h"
24249 +
24250 +#include "fm_macsec.h"
24251 +
24252 +
24253 +#define MACSEC_ICV_SIZE 16
24254 +#define MACSEC_SECTAG_SIZE 16
24255 +#define MACSEC_SCI_SIZE 8
24256 +#define MACSEC_FCS_SIZE 4
24257 +
24258 +/**************************************************************************//**
24259 + @Description Exceptions
24260 +*//***************************************************************************/
24261 +
24262 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
24263 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
24264 +#define FM_MACSEC_EX_ECC 0x00000001
24265 +
24266 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
24267 + case e_FM_MACSEC_EX_TX_SC: \
24268 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
24269 + case e_FM_MACSEC_EX_ECC: \
24270 + bitMask = FM_MACSEC_EX_ECC; break; \
24271 + default: bitMask = 0;break;}
24272 +
24273 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
24274 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
24275 +
24276 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24277 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
24278 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
24279 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
24280 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
24281 + default: bitMask = 0;break;}
24282 +
24283 +/**************************************************************************//**
24284 + @Description Events
24285 +*//***************************************************************************/
24286 +
24287 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
24288 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
24289 +
24290 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
24291 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
24292 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
24293 + default: bitMask = 0;break;}
24294 +
24295 +/**************************************************************************//**
24296 + @Description Defaults
24297 +*//***************************************************************************/
24298 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
24299 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
24300 +
24301 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
24302 + FM_MACSEC_EX_TX_SC(1) |\
24303 + FM_MACSEC_EX_TX_SC(2) |\
24304 + FM_MACSEC_EX_TX_SC(3) |\
24305 + FM_MACSEC_EX_TX_SC(4) |\
24306 + FM_MACSEC_EX_TX_SC(5) |\
24307 + FM_MACSEC_EX_TX_SC(6) |\
24308 + FM_MACSEC_EX_TX_SC(7) |\
24309 + FM_MACSEC_EX_TX_SC(8) |\
24310 + FM_MACSEC_EX_TX_SC(9) |\
24311 + FM_MACSEC_EX_TX_SC(10) |\
24312 + FM_MACSEC_EX_TX_SC(11) |\
24313 + FM_MACSEC_EX_TX_SC(12) |\
24314 + FM_MACSEC_EX_TX_SC(13) |\
24315 + FM_MACSEC_EX_TX_SC(14) |\
24316 + FM_MACSEC_EX_TX_SC(15) |\
24317 + FM_MACSEC_EX_ECC )
24318 +
24319 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
24320 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
24321 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
24322 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
24323 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
24324 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
24325 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
24326 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
24327 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
24328 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
24329 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
24330 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
24331 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
24332 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
24333 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
24334 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
24335 +
24336 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
24337 +#define DEFAULT_invalidTagsFrameTreatment FALSE
24338 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
24339 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
24340 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
24341 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
24342 +#define DEFAULT_keysUnreadable FALSE
24343 +#define DEFAULT_normalMode TRUE
24344 +#define DEFAULT_sc0ReservedForPTP FALSE
24345 +#define DEFAULT_initNextPn 1
24346 +#define DEFAULT_pnExhThr 0xffffffff
24347 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
24348 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
24349 +
24350 +
24351 +/**************************************************************************//**
24352 + @Description Memory Mapped Registers
24353 +*//***************************************************************************/
24354 +
24355 +#if defined(__MWERKS__) && !defined(__GNUC__)
24356 +#pragma pack(push,1)
24357 +#endif /* defined(__MWERKS__) && ... */
24358 +
24359 +typedef _Packed struct
24360 +{
24361 + /* MACsec configuration */
24362 + volatile uint32_t cfg; /**< MACsec configuration */
24363 + volatile uint32_t et; /**< MACsec EtherType */
24364 + volatile uint8_t res1[56]; /**< reserved */
24365 + volatile uint32_t mfl; /**< Maximum Frame Length */
24366 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
24367 + volatile uint8_t res2[56]; /**< reserved */
24368 + volatile uint32_t rxsca; /**< RX SC access select */
24369 + volatile uint8_t res3[60]; /**< reserved */
24370 + volatile uint32_t txsca; /**< TX SC access select */
24371 + volatile uint8_t res4[60]; /**< reserved */
24372 +
24373 + /* RX configuration, status and statistic */
24374 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
24375 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
24376 + volatile uint8_t res5[8]; /**< reserved */
24377 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
24378 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
24379 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
24380 + volatile uint8_t res6[4]; /**< reserved */
24381 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
24382 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
24383 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
24384 + volatile uint32_t rpw; /**< replayWindow */
24385 + volatile uint8_t res7[16]; /**< reserved */
24386 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
24387 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
24388 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
24389 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
24390 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
24391 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
24392 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
24393 + volatile uint8_t res8[4]; /**< reserved */
24394 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
24395 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
24396 + _Packed struct
24397 + {
24398 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
24399 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
24400 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
24401 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
24402 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
24403 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
24404 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
24405 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
24406 + volatile uint8_t res9[8]; /**< reserved */
24407 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
24408 +
24409 + /* TX configuration, status and statistic */
24410 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
24411 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
24412 + volatile uint8_t res10[8]; /**< reserved */
24413 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
24414 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
24415 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
24416 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
24417 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
24418 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
24419 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
24420 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
24421 + volatile uint8_t res11[16]; /**< reserved */
24422 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
24423 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
24424 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
24425 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
24426 + volatile uint8_t res12[48]; /**< reserved */
24427 + _Packed struct
24428 + {
24429 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
24430 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
24431 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
24432 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
24433 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
24434 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
24435 + volatile uint8_t res13[16]; /**< reserved */
24436 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
24437 + volatile uint8_t res14[248]; /**< reserved */
24438 +
24439 + /* Global configuration and status */
24440 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
24441 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
24442 + volatile uint32_t evr; /**< MACsec Event Register */
24443 + volatile uint32_t ever; /**< MACsec Event Enable Register */
24444 + volatile uint32_t evfr; /**< MACsec Event Force Register */
24445 + volatile uint32_t err; /**< MACsec Error Register */
24446 + volatile uint32_t erer; /**< MACsec Error Enable Register */
24447 + volatile uint32_t erfr; /**< MACsec Error Force Register */
24448 + volatile uint8_t res15[40]; /**< reserved */
24449 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
24450 + volatile uint32_t idle; /**< MACsec Idle status Register */
24451 + volatile uint8_t res16[184]; /**< reserved */
24452 + /* DEBUG */
24453 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
24454 + volatile uint8_t res17[28]; /**< reserved */
24455 + volatile uint32_t txec; /**< MACsec TX error capture Register */
24456 + volatile uint8_t res18[220]; /**< reserved */
24457 +
24458 + /* Macsec Rx global statistic */
24459 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
24460 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
24461 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
24462 + volatile uint8_t res19[4]; /**< reserved */
24463 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
24464 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
24465 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
24466 + volatile uint8_t res20[4]; /**< reserved */
24467 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
24468 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
24469 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
24470 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
24471 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
24472 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
24473 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
24474 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
24475 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
24476 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
24477 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
24478 + volatile uint8_t res21[52]; /**< reserved */
24479 +
24480 + /* Macsec Tx global statistic */
24481 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
24482 +#if (DPAA_VERSION >= 11)
24483 + volatile uint8_t res22[124]; /**< reserved */
24484 + _Packed struct
24485 + {
24486 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
24487 + volatile uint8_t res23[32]; /**< reserved */
24488 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
24489 + _Packed struct
24490 + {
24491 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
24492 + volatile uint8_t res24[32]; /**< reserved */
24493 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
24494 +#endif /* (DPAA_VERSION >= 11) */
24495 +} _PackedType t_FmMacsecRegs;
24496 +
24497 +#if defined(__MWERKS__) && !defined(__GNUC__)
24498 +#pragma pack(pop)
24499 +#endif /* defined(__MWERKS__) && ... */
24500 +
24501 +
24502 +/**************************************************************************//**
24503 + @Description General defines
24504 +*//***************************************************************************/
24505 +
24506 +#define SCI_HIGH_MASK 0xffffffff00000000LL
24507 +#define SCI_LOW_MASK 0x00000000ffffffffLL
24508 +
24509 +#define LONG_SHIFT 32
24510 +
24511 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
24512 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
24513 +
24514 +/**************************************************************************//**
24515 + @Description Configuration defines
24516 +*//***************************************************************************/
24517 +
24518 +/* masks */
24519 +#define CFG_UECT 0x00000800
24520 +#define CFG_ESCBT 0x00000400
24521 +#define CFG_USFT 0x00000300
24522 +#define CFG_ITT 0x00000080
24523 +#define CFG_KFT 0x00000040
24524 +#define CFG_UFT 0x00000030
24525 +#define CFG_KSS 0x00000004
24526 +#define CFG_BYPN 0x00000002
24527 +#define CFG_S0I 0x00000001
24528 +
24529 +#define ET_TYPE 0x0000ffff
24530 +
24531 +#define MFL_MAX_LEN 0x0000ffff
24532 +
24533 +#define RXSCA_SC_SEL 0x0000000f
24534 +
24535 +#define TXSCA_SC_SEL 0x0000000f
24536 +
24537 +#define IP_REV_1_IP_ID 0xffff0000
24538 +#define IP_REV_1_IP_MJ 0x0000ff00
24539 +#define IP_REV_1_IP_MM 0x000000ff
24540 +
24541 +#define IP_REV_2_IP_INT 0x00ff0000
24542 +#define IP_REV_2_IP_ERR 0x0000ff00
24543 +#define IP_REV_2_IP_CFG 0x000000ff
24544 +
24545 +#define MECC_CAP 0x80000000
24546 +#define MECC_CET 0x40000000
24547 +#define MECC_SERCNT 0x00ff0000
24548 +#define MECC_MEMADDR 0x000001ff
24549 +
24550 +/* shifts */
24551 +#define CFG_UECT_SHIFT (31-20)
24552 +#define CFG_ESCBT_SHIFT (31-21)
24553 +#define CFG_USFT_SHIFT (31-23)
24554 +#define CFG_ITT_SHIFT (31-24)
24555 +#define CFG_KFT_SHIFT (31-25)
24556 +#define CFG_UFT_SHIFT (31-27)
24557 +#define CFG_KSS_SHIFT (31-29)
24558 +#define CFG_BYPN_SHIFT (31-30)
24559 +#define CFG_S0I_SHIFT (31-31)
24560 +
24561 +#define IP_REV_1_IP_ID_SHIFT (31-15)
24562 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
24563 +#define IP_REV_1_IP_MM_SHIFT (31-31)
24564 +
24565 +#define IP_REV_2_IP_INT_SHIFT (31-15)
24566 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
24567 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
24568 +
24569 +#define MECC_CAP_SHIFT (31-0)
24570 +#define MECC_CET_SHIFT (31-1)
24571 +#define MECC_SERCNT_SHIFT (31-15)
24572 +#define MECC_MEMADDR_SHIFT (31-31)
24573 +
24574 +/**************************************************************************//**
24575 + @Description RX SC defines
24576 +*//***************************************************************************/
24577 +
24578 +/* masks */
24579 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
24580 +#define RX_SCCFG_RP_MASK 0x00000400
24581 +#define RX_SCCFG_VF_MASK 0x00000300
24582 +#define RX_SCCFG_CO_MASK 0x0000003f
24583 +
24584 +/* shifts */
24585 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
24586 +#define RX_SCCFG_RP_SHIFT (31-21)
24587 +#define RX_SCCFG_VF_SHIFT (31-23)
24588 +#define RX_SCCFG_CO_SHIFT (31-31)
24589 +#define RX_SCCFG_CS_SHIFT (31-7)
24590 +
24591 +/**************************************************************************//**
24592 + @Description RX SA defines
24593 +*//***************************************************************************/
24594 +
24595 +/* masks */
24596 +#define RX_SACFG_ACTIVE 0x80000000
24597 +#define RX_SACFG_AN_MASK 0x00000006
24598 +#define RX_SACFG_EN_MASK 0x00000001
24599 +
24600 +/* shifts */
24601 +#define RX_SACFG_AN_SHIFT (31-30)
24602 +#define RX_SACFG_EN_SHIFT (31-31)
24603 +
24604 +/**************************************************************************//**
24605 + @Description TX SC defines
24606 +*//***************************************************************************/
24607 +
24608 +/* masks */
24609 +#define TX_SCCFG_AN_MASK 0x000c0000
24610 +#define TX_SCCFG_ASA_MASK 0x00020000
24611 +#define TX_SCCFG_SCE_MASK 0x00010000
24612 +#define TX_SCCFG_CO_MASK 0x00003f00
24613 +#define TX_SCCFG_CE_MASK 0x00000010
24614 +#define TX_SCCFG_PF_MASK 0x00000008
24615 +#define TX_SCCFG_AIS_MASK 0x00000004
24616 +#define TX_SCCFG_UES_MASK 0x00000002
24617 +#define TX_SCCFG_USCB_MASK 0x00000001
24618 +
24619 +/* shifts */
24620 +#define TX_SCCFG_AN_SHIFT (31-13)
24621 +#define TX_SCCFG_ASA_SHIFT (31-14)
24622 +#define TX_SCCFG_SCE_SHIFT (31-15)
24623 +#define TX_SCCFG_CO_SHIFT (31-23)
24624 +#define TX_SCCFG_CE_SHIFT (31-27)
24625 +#define TX_SCCFG_PF_SHIFT (31-28)
24626 +#define TX_SCCFG_AIS_SHIFT (31-29)
24627 +#define TX_SCCFG_UES_SHIFT (31-30)
24628 +#define TX_SCCFG_USCB_SHIFT (31-31)
24629 +#define TX_SCCFG_CS_SHIFT (31-7)
24630 +
24631 +/**************************************************************************//**
24632 + @Description TX SA defines
24633 +*//***************************************************************************/
24634 +
24635 +/* masks */
24636 +#define TX_SACFG_ACTIVE 0x80000000
24637 +
24638 +
24639 +typedef struct
24640 +{
24641 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
24642 + t_Handle h_SrcHandle;
24643 +} t_FmMacsecIntrSrc;
24644 +
24645 +typedef struct
24646 +{
24647 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
24648 + bool invalidTagsDeliverUncontrolled;
24649 + bool changedTextWithNoEncryptDeliverUncontrolled;
24650 + bool onlyScbIsSetDeliverUncontrolled;
24651 + bool encryptWithNoChangedTextDiscardUncontrolled;
24652 + e_FmMacsecUntagFrameTreatment untagTreatMode;
24653 + uint32_t pnExhThr;
24654 + bool keysUnreadable;
24655 + bool byPassMode;
24656 + bool reservedSc0;
24657 + uint32_t sectagOverhead;
24658 + uint32_t mflSubtract;
24659 +} t_FmMacsecDriverParam;
24660 +
24661 +typedef struct
24662 +{
24663 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
24664 + t_Handle h_Fm;
24665 + t_FmMacsecRegs *p_FmMacsecRegs;
24666 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
24667 + char fmMacsecModuleName[MODULE_NAME_SIZE];
24668 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
24669 + uint32_t events;
24670 + uint32_t exceptions;
24671 + uint32_t userExceptions;
24672 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
24673 + t_Handle h_App; /**< A handle to an application layer object; This handle will
24674 + be passed by the driver upon calling the above callbacks */
24675 + bool rxScTable[NUM_OF_RX_SC];
24676 + uint32_t numRxScAvailable;
24677 + bool txScTable[NUM_OF_TX_SC];
24678 + uint32_t numTxScAvailable;
24679 + t_Handle rxScSpinLock;
24680 + t_Handle txScSpinLock;
24681 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
24682 +} t_FmMacsec;
24683 +
24684 +
24685 +#endif /* __FM_MACSEC_MASTER_H */
24686 --- /dev/null
24687 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
24688 @@ -0,0 +1,883 @@
24689 +/*
24690 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24691 + *
24692 + * Redistribution and use in source and binary forms, with or without
24693 + * modification, are permitted provided that the following conditions are met:
24694 + * * Redistributions of source code must retain the above copyright
24695 + * notice, this list of conditions and the following disclaimer.
24696 + * * Redistributions in binary form must reproduce the above copyright
24697 + * notice, this list of conditions and the following disclaimer in the
24698 + * documentation and/or other materials provided with the distribution.
24699 + * * Neither the name of Freescale Semiconductor nor the
24700 + * names of its contributors may be used to endorse or promote products
24701 + * derived from this software without specific prior written permission.
24702 + *
24703 + *
24704 + * ALTERNATIVELY, this software may be distributed under the terms of the
24705 + * GNU General Public License ("GPL") as published by the Free Software
24706 + * Foundation, either version 2 of that License or (at your option) any
24707 + * later version.
24708 + *
24709 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24710 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24711 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24712 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24713 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24714 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24715 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24716 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24717 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24718 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24719 + */
24720 +
24721 +/******************************************************************************
24722 + @File fm_macsec_secy.c
24723 +
24724 + @Description FM MACSEC SECY driver routines implementation.
24725 +*//***************************************************************************/
24726 +
24727 +#include "std_ext.h"
24728 +#include "error_ext.h"
24729 +#include "xx_ext.h"
24730 +#include "string_ext.h"
24731 +#include "sprint_ext.h"
24732 +
24733 +#include "fm_macsec_secy.h"
24734 +
24735 +
24736 +/****************************************/
24737 +/* static functions */
24738 +/****************************************/
24739 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24740 +{
24741 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24742 +
24743 + UNUSED(id);
24744 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24745 +
24746 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
24747 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
24748 +}
24749 +
24750 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
24751 +{
24752 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24753 +
24754 + UNUSED(id);
24755 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
24756 +
24757 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
24758 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
24759 +}
24760 +
24761 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
24762 +{
24763 + if (!p_FmMacsecSecY->f_Exception)
24764 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
24765 +
24766 + if (!p_FmMacsecSecY->f_Event)
24767 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
24768 +
24769 + if (!p_FmMacsecSecY->numOfRxSc)
24770 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
24771 +
24772 +
24773 + return E_OK;
24774 +}
24775 +
24776 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
24777 + macsecSCI_t sci,
24778 + e_FmMacsecSecYCipherSuite cipherSuite,
24779 + e_ScType type)
24780 +{
24781 + t_SecYSc *p_ScTable;
24782 + void *p_Params;
24783 + uint32_t numOfSc,i;
24784 + t_Error err = E_OK;
24785 + t_RxScParams rxScParams;
24786 + t_TxScParams txScParams;
24787 +
24788 + ASSERT_COND(p_FmMacsecSecY);
24789 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
24790 +
24791 + if (type == e_SC_RX)
24792 + {
24793 + memset(&rxScParams, 0, sizeof(rxScParams));
24794 + i = (NUM_OF_RX_SC - 1);
24795 + p_ScTable = p_FmMacsecSecY->p_RxSc;
24796 + numOfSc = p_FmMacsecSecY->numOfRxSc;
24797 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24798 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
24799 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
24800 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
24801 + rxScParams.cipherSuite = cipherSuite;
24802 + p_Params = &rxScParams;
24803 + }
24804 + else
24805 + {
24806 + memset(&txScParams, 0, sizeof(txScParams));
24807 + i = (NUM_OF_TX_SC - 1);
24808 + p_ScTable = p_FmMacsecSecY->p_TxSc;
24809 + numOfSc = p_FmMacsecSecY->numOfTxSc;
24810 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
24811 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
24812 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
24813 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
24814 + txScParams.cipherSuite = cipherSuite;
24815 + p_Params = &txScParams;
24816 + }
24817 +
24818 + for (i=0;i<numOfSc;i++)
24819 + if (!p_ScTable[i].inUse)
24820 + break;
24821 + if (i == numOfSc)
24822 + {
24823 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
24824 + return NULL;
24825 + }
24826 +
24827 + if (type == e_SC_RX)
24828 + {
24829 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
24830 + ((t_RxScParams *)p_Params)->sci = sci;
24831 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
24832 + {
24833 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
24834 + return NULL;
24835 + }
24836 + }
24837 + else
24838 + {
24839 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
24840 + ((t_TxScParams *)p_Params)->sci = sci;
24841 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
24842 + {
24843 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
24844 + return NULL;
24845 + }
24846 + }
24847 +
24848 + p_ScTable[i].inUse = TRUE;
24849 + return &p_ScTable[i];
24850 +}
24851 +
24852 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
24853 +{
24854 + t_Error err = E_OK;
24855 +
24856 + ASSERT_COND(p_FmMacsecSecY);
24857 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
24858 + ASSERT_COND(p_FmSecYSc);
24859 +
24860 + if (type == e_SC_RX)
24861 + {
24862 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
24863 + RETURN_ERROR(MINOR, err, NO_MSG);
24864 + }
24865 + else
24866 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
24867 + RETURN_ERROR(MINOR, err, NO_MSG);
24868 +
24869 + p_FmSecYSc->inUse = FALSE;
24870 +
24871 + return err;
24872 +}
24873 +
24874 +/****************************************/
24875 +/* API Init unit functions */
24876 +/****************************************/
24877 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
24878 +{
24879 + t_FmMacsecSecY *p_FmMacsecSecY;
24880 +
24881 + /* Allocate FM MACSEC structure */
24882 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
24883 + if (!p_FmMacsecSecY)
24884 + {
24885 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
24886 + return NULL;
24887 + }
24888 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
24889 +
24890 + /* Allocate the FM MACSEC driver's parameters structure */
24891 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
24892 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
24893 + {
24894 + XX_Free(p_FmMacsecSecY);
24895 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
24896 + return NULL;
24897 + }
24898 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
24899 +
24900 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
24901 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
24902 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
24903 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
24904 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
24905 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
24906 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
24907 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
24908 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
24909 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
24910 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
24911 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
24912 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
24913 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
24914 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
24915 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
24916 + p_FmMacsecSecY->events = DEFAULT_events;
24917 +
24918 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
24919 + &p_FmMacsecSecYParam->txScParams,
24920 + sizeof(t_FmMacsecSecYSCParams));
24921 + return p_FmMacsecSecY;
24922 +}
24923 +
24924 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
24925 +{
24926 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
24927 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
24928 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
24929 + t_Error err;
24930 +
24931 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
24932 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
24933 +
24934 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
24935 +
24936 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
24937 +
24938 + if ((p_FmMacsecSecY->isPointToPoint) &&
24939 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
24940 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
24941 +
24942 + /* Rx Sc Allocation */
24943 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
24944 + if (!p_FmMacsecSecY->p_RxSc)
24945 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
24946 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
24947 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
24948 + {
24949 + if (p_FmMacsecSecY->p_TxSc)
24950 + XX_Free(p_FmMacsecSecY->p_TxSc);
24951 + if (p_FmMacsecSecY->p_RxSc)
24952 + XX_Free(p_FmMacsecSecY->p_RxSc);
24953 + return ERROR_CODE(err);
24954 + }
24955 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
24956 + {
24957 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
24958 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
24959 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
24960 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
24961 + }
24962 +
24963 + /* Tx Sc Allocation */
24964 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
24965 + if (!p_FmMacsecSecY->p_TxSc)
24966 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
24967 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
24968 +
24969 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
24970 + {
24971 + if (p_FmMacsecSecY->p_TxSc)
24972 + XX_Free(p_FmMacsecSecY->p_TxSc);
24973 + if (p_FmMacsecSecY->p_RxSc)
24974 + XX_Free(p_FmMacsecSecY->p_RxSc);
24975 + return ERROR_CODE(err);
24976 + }
24977 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
24978 + {
24979 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
24980 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
24981 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
24982 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
24983 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
24984 + e_FM_MACSEC_MOD_SC_TX,
24985 + (uint8_t)txScIds[i],
24986 + e_FM_INTR_TYPE_ERR,
24987 + FmMacsecSecYExceptionsIsr,
24988 + p_FmMacsecSecY);
24989 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
24990 + e_FM_MACSEC_MOD_SC_TX,
24991 + (uint8_t)txScIds[i],
24992 + e_FM_INTR_TYPE_NORMAL,
24993 + FmMacsecSecYEventsIsr,
24994 + p_FmMacsecSecY);
24995 +
24996 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
24997 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
24998 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
24999 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
25000 + }
25001 +
25002 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
25003 + p_FmMacsecSecYDriverParam->txScParams.sci,
25004 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
25005 + e_SC_TX);
25006 + XX_Free(p_FmMacsecSecYDriverParam);
25007 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
25008 +
25009 + return E_OK;
25010 +}
25011 +
25012 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
25013 +{
25014 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25015 + t_Error err = E_OK;
25016 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
25017 +
25018 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25019 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25020 +
25021 + if (p_FmMacsecSecY->isPointToPoint)
25022 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
25023 + if (p_FmMacsecSecY->p_RxSc)
25024 + {
25025 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25026 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
25027 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25028 + return ERROR_CODE(err);
25029 + XX_Free(p_FmMacsecSecY->p_RxSc);
25030 + }
25031 + if (p_FmMacsecSecY->p_TxSc)
25032 + {
25033 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
25034 +
25035 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
25036 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
25037 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25038 + e_FM_MACSEC_MOD_SC_TX,
25039 + (uint8_t)txScIds[i],
25040 + e_FM_INTR_TYPE_ERR);
25041 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25042 + e_FM_MACSEC_MOD_SC_TX,
25043 + (uint8_t)txScIds[i],
25044 + e_FM_INTR_TYPE_NORMAL);
25045 +
25046 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25047 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
25048 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25049 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
25050 + }
25051 +
25052 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25053 + return ERROR_CODE(err);
25054 + XX_Free(p_FmMacsecSecY->p_TxSc);
25055 + }
25056 +
25057 + XX_Free(p_FmMacsecSecY);
25058 +
25059 + return err;
25060 +}
25061 +
25062 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
25063 +{
25064 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25065 +
25066 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25067 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25068 +
25069 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
25070 +
25071 + return E_OK;
25072 +}
25073 +
25074 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
25075 +{
25076 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25077 +
25078 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25079 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25080 +
25081 + p_FmMacsecSecY->protectFrames = protectFrames;
25082 +
25083 + return E_OK;
25084 +}
25085 +
25086 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
25087 +{
25088 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25089 +
25090 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25091 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25092 +
25093 + p_FmMacsecSecY->replayProtect = replayProtect;
25094 + p_FmMacsecSecY->replayWindow = replayWindow;
25095 +
25096 + return E_OK;
25097 +}
25098 +
25099 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
25100 +{
25101 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25102 +
25103 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25104 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25105 +
25106 + p_FmMacsecSecY->validateFrames = validateFrames;
25107 +
25108 + return E_OK;
25109 +}
25110 +
25111 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
25112 +{
25113 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25114 +
25115 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25116 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25117 +
25118 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
25119 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
25120 +
25121 + return E_OK;
25122 +}
25123 +
25124 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
25125 +{
25126 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25127 +
25128 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25129 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25130 +
25131 + p_FmMacsecSecY->numOfRxSc = 1;
25132 + p_FmMacsecSecY->isPointToPoint = TRUE;
25133 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
25134 +
25135 + return E_OK;
25136 +}
25137 +
25138 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
25139 +{
25140 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25141 + uint32_t bitMask = 0;
25142 +
25143 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25144 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25145 +
25146 + GET_EXCEPTION_FLAG(bitMask, exception);
25147 + if (bitMask)
25148 + {
25149 + if (enable)
25150 + p_FmMacsecSecY->exceptions |= bitMask;
25151 + else
25152 + p_FmMacsecSecY->exceptions &= ~bitMask;
25153 + }
25154 + else
25155 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25156 +
25157 + return E_OK;
25158 +}
25159 +
25160 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25161 +{
25162 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25163 + uint32_t bitMask = 0;
25164 +
25165 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25166 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25167 +
25168 + GET_EVENT_FLAG(bitMask, event);
25169 + if (bitMask)
25170 + {
25171 + if (enable)
25172 + p_FmMacsecSecY->events |= bitMask;
25173 + else
25174 + p_FmMacsecSecY->events &= ~bitMask;
25175 + }
25176 + else
25177 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25178 +
25179 + return E_OK;
25180 +}
25181 +
25182 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
25183 +{
25184 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25185 +
25186 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
25187 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
25188 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
25189 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
25190 +
25191 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
25192 +}
25193 +
25194 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
25195 +{
25196 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25197 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25198 +
25199 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25200 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25201 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25202 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25203 +
25204 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
25205 +}
25206 +
25207 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25208 +{
25209 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25210 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25211 + t_Error err = E_OK;
25212 +
25213 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25214 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25215 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25216 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25217 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25218 +
25219 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25220 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
25221 +
25222 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
25223 + RETURN_ERROR(MINOR, err, NO_MSG);
25224 +
25225 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25226 + return err;
25227 +}
25228 +
25229 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25230 +{
25231 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25232 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25233 + t_Error err = E_OK;
25234 +
25235 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25236 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25237 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25238 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25239 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25240 +
25241 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25242 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25243 +
25244 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25245 + RETURN_ERROR(MINOR, err, NO_MSG);
25246 +
25247 + p_FmSecYSc->numOfSa--;
25248 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25249 + /* TODO - check if statistics need to be read*/
25250 + return err;
25251 +}
25252 +
25253 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25254 +{
25255 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25256 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25257 + t_Error err = E_OK;
25258 +
25259 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25260 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25261 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25262 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25263 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25264 +
25265 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25266 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25267 +
25268 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25269 + RETURN_ERROR(MINOR, err, NO_MSG);
25270 +
25271 + p_FmSecYSc->sa[an].active = TRUE;
25272 + return err;
25273 +}
25274 +
25275 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25276 +{
25277 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25278 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25279 + t_Error err = E_OK;
25280 +
25281 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25282 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25283 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25284 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25285 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25286 +
25287 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25288 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25289 +
25290 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25291 + RETURN_ERROR(MINOR, err, NO_MSG);
25292 +
25293 + p_FmSecYSc->sa[an].active = FALSE;
25294 + return err;
25295 +}
25296 +
25297 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
25298 +{
25299 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25300 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25301 + t_Error err = E_OK;
25302 +
25303 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25304 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25305 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25306 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25307 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25308 +
25309 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25310 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25311 +
25312 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
25313 + RETURN_ERROR(MINOR, err, NO_MSG);
25314 +
25315 + return err;
25316 +}
25317 +
25318 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
25319 +{
25320 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25321 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25322 + t_Error err = E_OK;
25323 +
25324 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25325 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25326 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25327 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25328 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25329 +
25330 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25331 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25332 +
25333 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
25334 + RETURN_ERROR(MINOR, err, NO_MSG);
25335 +
25336 + return err;
25337 +}
25338 +
25339 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
25340 +{
25341 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25342 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25343 + t_Error err = E_OK;
25344 +
25345 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25346 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25347 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25348 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25349 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25350 +
25351 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25352 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25353 +
25354 + if (p_FmSecYSc->sa[an].active)
25355 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25356 + RETURN_ERROR(MINOR, err, NO_MSG);
25357 +
25358 + /* TODO - statistics should be read */
25359 +
25360 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
25361 + RETURN_ERROR(MINOR, err, NO_MSG);
25362 +
25363 + if (p_FmSecYSc->sa[an].active)
25364 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25365 + RETURN_ERROR(MINOR, err, NO_MSG);
25366 + return err;
25367 +}
25368 +
25369 +
25370 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
25371 +{
25372 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25373 + t_SecYSc *p_FmSecYSc;
25374 + t_Error err = E_OK;
25375 +
25376 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25377 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25378 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25379 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25380 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25381 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25382 +
25383 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25384 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
25385 +
25386 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
25387 + RETURN_ERROR(MINOR, err, NO_MSG);
25388 +
25389 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25390 + return err;
25391 +}
25392 +
25393 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
25394 +{
25395 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25396 + t_SecYSc *p_FmSecYSc;
25397 + t_Error err = E_OK;
25398 +
25399 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25400 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25401 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25402 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25403 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25404 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25405 +
25406 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25407 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25408 +
25409 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25410 + RETURN_ERROR(MINOR, err, NO_MSG);
25411 +
25412 + p_FmSecYSc->numOfSa--;
25413 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25414 + /* TODO - check if statistics need to be read*/
25415 + return err;
25416 +}
25417 +
25418 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
25419 +{
25420 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25421 + t_SecYSc *p_FmSecYSc;
25422 + macsecAN_t currentAn;
25423 + t_Error err = E_OK;
25424 +
25425 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25426 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25427 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25428 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25429 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25430 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25431 +
25432 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25433 + p_FmSecYSc->scId,
25434 + &currentAn)) != E_OK)
25435 + RETURN_ERROR(MINOR, err, NO_MSG);
25436 +
25437 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25438 + p_FmSecYSc->scId,
25439 + p_FmSecYSc->sa[nextActiveAn].saId,
25440 + nextActiveAn)) != E_OK)
25441 + RETURN_ERROR(MINOR, err, NO_MSG);
25442 +
25443 + /* TODO - statistics should be read */
25444 +
25445 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
25446 + RETURN_ERROR(MINOR, err, NO_MSG);
25447 +
25448 + return err;
25449 +}
25450 +
25451 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
25452 +{
25453 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25454 + t_SecYSc *p_FmSecYSc;
25455 + t_Error err = E_OK;
25456 +
25457 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25458 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25459 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25460 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25461 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25462 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25463 +
25464 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25465 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25466 +
25467 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25468 + p_FmSecYSc->scId,
25469 + p_FmSecYSc->sa[an].saId,
25470 + an)) != E_OK)
25471 + RETURN_ERROR(MINOR, err, NO_MSG);
25472 +
25473 + return err;
25474 +}
25475 +
25476 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
25477 +{
25478 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25479 + t_SecYSc *p_FmSecYSc;
25480 + t_Error err = E_OK;
25481 +
25482 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25483 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25484 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25485 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25486 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25487 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
25488 +
25489 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25490 + p_FmSecYSc->scId,
25491 + p_An)) != E_OK)
25492 + RETURN_ERROR(MINOR, err, NO_MSG);
25493 +
25494 + return err;
25495 +}
25496 +
25497 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
25498 +{
25499 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25500 + t_Error err = E_OK;
25501 +
25502 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
25503 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
25504 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25505 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25506 +#ifdef DISABLE_SANITY_CHECKS
25507 + UNUSED(h_FmMacsecSecY);
25508 +#endif /* DISABLE_SANITY_CHECKS */
25509 +
25510 + *p_ScPhysId = p_FmSecYSc->scId;
25511 + return err;
25512 +}
25513 +
25514 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
25515 +{
25516 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25517 + t_SecYSc *p_FmSecYSc;
25518 + t_Error err = E_OK;
25519 +
25520 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25521 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25522 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25523 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25524 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25525 +
25526 + *p_ScPhysId = p_FmSecYSc->scId;
25527 + return err;
25528 +}
25529 +
25530 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
25531 +{
25532 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
25533 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25534 +}
25535 +
25536 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25537 +{
25538 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
25539 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25540 +}
25541 +
25542 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
25543 +{
25544 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25545 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25546 +}
25547 +
25548 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
25549 +{
25550 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
25551 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25552 +}
25553 +
25554 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
25555 +{
25556 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
25557 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25558 +}
25559 +
25560 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
25561 +{
25562 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25563 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25564 +}
25565 +
25566 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
25567 +{
25568 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
25569 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25570 +}
25571 +
25572 --- /dev/null
25573 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25574 @@ -0,0 +1,144 @@
25575 +/*
25576 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25577 + *
25578 + * Redistribution and use in source and binary forms, with or without
25579 + * modification, are permitted provided that the following conditions are met:
25580 + * * Redistributions of source code must retain the above copyright
25581 + * notice, this list of conditions and the following disclaimer.
25582 + * * Redistributions in binary form must reproduce the above copyright
25583 + * notice, this list of conditions and the following disclaimer in the
25584 + * documentation and/or other materials provided with the distribution.
25585 + * * Neither the name of Freescale Semiconductor nor the
25586 + * names of its contributors may be used to endorse or promote products
25587 + * derived from this software without specific prior written permission.
25588 + *
25589 + *
25590 + * ALTERNATIVELY, this software may be distributed under the terms of the
25591 + * GNU General Public License ("GPL") as published by the Free Software
25592 + * Foundation, either version 2 of that License or (at your option) any
25593 + * later version.
25594 + *
25595 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25596 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25597 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25598 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25599 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25600 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25601 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25602 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25603 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25604 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25605 + */
25606 +
25607 +/******************************************************************************
25608 + @File fm_macsec_secy.h
25609 +
25610 + @Description FM MACSEC SecY internal structures and definitions.
25611 +*//***************************************************************************/
25612 +#ifndef __FM_MACSEC_SECY_H
25613 +#define __FM_MACSEC_SECY_H
25614 +
25615 +#include "error_ext.h"
25616 +#include "std_ext.h"
25617 +
25618 +#include "fm_macsec.h"
25619 +
25620 +
25621 +/**************************************************************************//**
25622 + @Description Exceptions
25623 +*//***************************************************************************/
25624 +
25625 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
25626 +
25627 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25628 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
25629 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
25630 + default: bitMask = 0;break;}
25631 +
25632 +/**************************************************************************//**
25633 + @Description Events
25634 +*//***************************************************************************/
25635 +
25636 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
25637 +
25638 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
25639 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
25640 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
25641 + default: bitMask = 0;break;}
25642 +
25643 +/**************************************************************************//**
25644 + @Description Defaults
25645 +*//***************************************************************************/
25646 +
25647 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25648 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
25649 +#define DEFAULT_numOfTxSc 1
25650 +#define DEFAULT_confidentialityEnable FALSE
25651 +#define DEFAULT_confidentialityOffset 0
25652 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
25653 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
25654 +#define DEFAULT_replayEnable FALSE
25655 +#define DEFAULT_replayWindow 0
25656 +#define DEFAULT_protectFrames TRUE
25657 +#define DEFAULT_ptp FALSE
25658 +
25659 +/**************************************************************************//**
25660 + @Description General defines
25661 +*//***************************************************************************/
25662 +
25663 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
25664 +
25665 +
25666 +typedef struct {
25667 + e_ScSaId saId;
25668 + bool active;
25669 + union {
25670 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
25671 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
25672 + };
25673 +} t_SecYSa;
25674 +
25675 +typedef struct {
25676 + bool inUse;
25677 + uint32_t scId;
25678 + e_ScType type;
25679 + uint8_t numOfSa;
25680 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
25681 + union {
25682 + t_FmMacsecSecYRxScStatistics rxScStatistics;
25683 + t_FmMacsecSecYTxScStatistics txScStatistics;
25684 + };
25685 +} t_SecYSc;
25686 +
25687 +typedef struct {
25688 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
25689 +} t_FmMacsecSecYDriverParam;
25690 +
25691 +typedef struct {
25692 + t_Handle h_FmMacsec;
25693 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
25694 + FALSE - no confidentiality protection, only integrity protection*/
25695 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
25696 + common values are 0, 30, and 50 */
25697 + bool replayProtect; /**< replay protection function mode */
25698 + uint32_t replayWindow; /**< the size of the replay window */
25699 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
25700 + e_FmMacsecSciInsertionMode sciInsertionMode;
25701 + bool protectFrames;
25702 + bool isPointToPoint;
25703 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
25704 + uint32_t numOfRxSc; /**< Number of receive channels */
25705 + uint32_t numOfTxSc; /**< Number of transmit channels */
25706 + t_SecYSc *p_RxSc;
25707 + t_SecYSc *p_TxSc;
25708 + uint32_t events;
25709 + uint32_t exceptions;
25710 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
25711 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
25712 + t_Handle h_App;
25713 + t_FmMacsecSecYStatistics statistics;
25714 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
25715 +} t_FmMacsecSecY;
25716 +
25717 +
25718 +#endif /* __FM_MACSEC_SECY_H */
25719 --- /dev/null
25720 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
25721 @@ -0,0 +1,23 @@
25722 +#
25723 +# Makefile for the Freescale Ethernet controllers
25724 +#
25725 +ccflags-y += -DVERSION=\"\"
25726 +#
25727 +#Include netcomm SW specific definitions
25728 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25729 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25730 +
25731 +ccflags-y += -I$(NCSW_FM_INC)
25732 +
25733 +
25734 +obj-y += fsl-ncsw-PFM1.o
25735 +
25736 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
25737 +
25738 +obj-y += MAC/
25739 +obj-y += Pcd/
25740 +obj-y += SP/
25741 +obj-y += Port/
25742 +obj-y += HC/
25743 +obj-y += Rtc/
25744 +obj-y += MACSEC/
25745 --- /dev/null
25746 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
25747 @@ -0,0 +1,26 @@
25748 +#
25749 +# Makefile for the Freescale Ethernet controllers
25750 +#
25751 +ccflags-y += -DVERSION=\"\"
25752 +#
25753 +#Include netcomm SW specific definitions
25754 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
25755 +
25756 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
25757 +
25758 +ccflags-y += -I$(NCSW_FM_INC)
25759 +
25760 +obj-y += fsl-ncsw-Pcd.o
25761 +
25762 +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
25763 +
25764 +ifeq ($(CONFIG_FMAN_V3H),y)
25765 +fsl-ncsw-Pcd-objs += fm_replic.o
25766 +endif
25767 +ifeq ($(CONFIG_FMAN_V3L),y)
25768 +fsl-ncsw-Pcd-objs += fm_replic.o
25769 +endif
25770 +ifeq ($(CONFIG_FMAN_ARM),y)
25771 +fsl-ncsw-Pcd-objs += fm_replic.o
25772 +endif
25773 +
25774 --- /dev/null
25775 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
25776 @@ -0,0 +1,360 @@
25777 +/*
25778 + * Copyright 2008-2012 Freescale Semiconductor Inc.
25779 + *
25780 + * Redistribution and use in source and binary forms, with or without
25781 + * modification, are permitted provided that the following conditions are met:
25782 + * * Redistributions of source code must retain the above copyright
25783 + * notice, this list of conditions and the following disclaimer.
25784 + * * Redistributions in binary form must reproduce the above copyright
25785 + * notice, this list of conditions and the following disclaimer in the
25786 + * documentation and/or other materials provided with the distribution.
25787 + * * Neither the name of Freescale Semiconductor nor the
25788 + * names of its contributors may be used to endorse or promote products
25789 + * derived from this software without specific prior written permission.
25790 + *
25791 + *
25792 + * ALTERNATIVELY, this software may be distributed under the terms of the
25793 + * GNU General Public License ("GPL") as published by the Free Software
25794 + * Foundation, either version 2 of that License or (at your option) any
25795 + * later version.
25796 + *
25797 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25798 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25799 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25800 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25801 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25802 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25803 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25804 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25805 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25806 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25807 + */
25808 +
25809 +
25810 + /**************************************************************************//**
25811 + @File crc64.h
25812 +
25813 + @Description brief This file contains the CRC64 Table, and __inline__
25814 + functions used for calculating crc.
25815 +*//***************************************************************************/
25816 +#ifndef __CRC64_H
25817 +#define __CRC64_H
25818 +
25819 +#include "std_ext.h"
25820 +
25821 +
25822 +#define BITS_PER_BYTE 8
25823 +
25824 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
25825 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
25826 +
25827 +#define CRC64_BYTE_MASK 0xFF
25828 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
25829 +#define CRC64_ODD_MASK 1
25830 +
25831 +
25832 +/**
25833 + \brief '64 bit crc' Table
25834 + */
25835 +struct crc64_t {
25836 + uint64_t initial; /**< Initial seed */
25837 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
25838 +};
25839 +
25840 +
25841 +static struct crc64_t CRC64_ECMA_182 = {
25842 + CRC64_DEFAULT_INITVAL,
25843 + {
25844 + 0x0000000000000000ULL,
25845 + 0xb32e4cbe03a75f6fULL,
25846 + 0xf4843657a840a05bULL,
25847 + 0x47aa7ae9abe7ff34ULL,
25848 + 0x7bd0c384ff8f5e33ULL,
25849 + 0xc8fe8f3afc28015cULL,
25850 + 0x8f54f5d357cffe68ULL,
25851 + 0x3c7ab96d5468a107ULL,
25852 + 0xf7a18709ff1ebc66ULL,
25853 + 0x448fcbb7fcb9e309ULL,
25854 + 0x0325b15e575e1c3dULL,
25855 + 0xb00bfde054f94352ULL,
25856 + 0x8c71448d0091e255ULL,
25857 + 0x3f5f08330336bd3aULL,
25858 + 0x78f572daa8d1420eULL,
25859 + 0xcbdb3e64ab761d61ULL,
25860 + 0x7d9ba13851336649ULL,
25861 + 0xceb5ed8652943926ULL,
25862 + 0x891f976ff973c612ULL,
25863 + 0x3a31dbd1fad4997dULL,
25864 + 0x064b62bcaebc387aULL,
25865 + 0xb5652e02ad1b6715ULL,
25866 + 0xf2cf54eb06fc9821ULL,
25867 + 0x41e11855055bc74eULL,
25868 + 0x8a3a2631ae2dda2fULL,
25869 + 0x39146a8fad8a8540ULL,
25870 + 0x7ebe1066066d7a74ULL,
25871 + 0xcd905cd805ca251bULL,
25872 + 0xf1eae5b551a2841cULL,
25873 + 0x42c4a90b5205db73ULL,
25874 + 0x056ed3e2f9e22447ULL,
25875 + 0xb6409f5cfa457b28ULL,
25876 + 0xfb374270a266cc92ULL,
25877 + 0x48190ecea1c193fdULL,
25878 + 0x0fb374270a266cc9ULL,
25879 + 0xbc9d3899098133a6ULL,
25880 + 0x80e781f45de992a1ULL,
25881 + 0x33c9cd4a5e4ecdceULL,
25882 + 0x7463b7a3f5a932faULL,
25883 + 0xc74dfb1df60e6d95ULL,
25884 + 0x0c96c5795d7870f4ULL,
25885 + 0xbfb889c75edf2f9bULL,
25886 + 0xf812f32ef538d0afULL,
25887 + 0x4b3cbf90f69f8fc0ULL,
25888 + 0x774606fda2f72ec7ULL,
25889 + 0xc4684a43a15071a8ULL,
25890 + 0x83c230aa0ab78e9cULL,
25891 + 0x30ec7c140910d1f3ULL,
25892 + 0x86ace348f355aadbULL,
25893 + 0x3582aff6f0f2f5b4ULL,
25894 + 0x7228d51f5b150a80ULL,
25895 + 0xc10699a158b255efULL,
25896 + 0xfd7c20cc0cdaf4e8ULL,
25897 + 0x4e526c720f7dab87ULL,
25898 + 0x09f8169ba49a54b3ULL,
25899 + 0xbad65a25a73d0bdcULL,
25900 + 0x710d64410c4b16bdULL,
25901 + 0xc22328ff0fec49d2ULL,
25902 + 0x85895216a40bb6e6ULL,
25903 + 0x36a71ea8a7ace989ULL,
25904 + 0x0adda7c5f3c4488eULL,
25905 + 0xb9f3eb7bf06317e1ULL,
25906 + 0xfe5991925b84e8d5ULL,
25907 + 0x4d77dd2c5823b7baULL,
25908 + 0x64b62bcaebc387a1ULL,
25909 + 0xd7986774e864d8ceULL,
25910 + 0x90321d9d438327faULL,
25911 + 0x231c512340247895ULL,
25912 + 0x1f66e84e144cd992ULL,
25913 + 0xac48a4f017eb86fdULL,
25914 + 0xebe2de19bc0c79c9ULL,
25915 + 0x58cc92a7bfab26a6ULL,
25916 + 0x9317acc314dd3bc7ULL,
25917 + 0x2039e07d177a64a8ULL,
25918 + 0x67939a94bc9d9b9cULL,
25919 + 0xd4bdd62abf3ac4f3ULL,
25920 + 0xe8c76f47eb5265f4ULL,
25921 + 0x5be923f9e8f53a9bULL,
25922 + 0x1c4359104312c5afULL,
25923 + 0xaf6d15ae40b59ac0ULL,
25924 + 0x192d8af2baf0e1e8ULL,
25925 + 0xaa03c64cb957be87ULL,
25926 + 0xeda9bca512b041b3ULL,
25927 + 0x5e87f01b11171edcULL,
25928 + 0x62fd4976457fbfdbULL,
25929 + 0xd1d305c846d8e0b4ULL,
25930 + 0x96797f21ed3f1f80ULL,
25931 + 0x2557339fee9840efULL,
25932 + 0xee8c0dfb45ee5d8eULL,
25933 + 0x5da24145464902e1ULL,
25934 + 0x1a083bacedaefdd5ULL,
25935 + 0xa9267712ee09a2baULL,
25936 + 0x955cce7fba6103bdULL,
25937 + 0x267282c1b9c65cd2ULL,
25938 + 0x61d8f8281221a3e6ULL,
25939 + 0xd2f6b4961186fc89ULL,
25940 + 0x9f8169ba49a54b33ULL,
25941 + 0x2caf25044a02145cULL,
25942 + 0x6b055fede1e5eb68ULL,
25943 + 0xd82b1353e242b407ULL,
25944 + 0xe451aa3eb62a1500ULL,
25945 + 0x577fe680b58d4a6fULL,
25946 + 0x10d59c691e6ab55bULL,
25947 + 0xa3fbd0d71dcdea34ULL,
25948 + 0x6820eeb3b6bbf755ULL,
25949 + 0xdb0ea20db51ca83aULL,
25950 + 0x9ca4d8e41efb570eULL,
25951 + 0x2f8a945a1d5c0861ULL,
25952 + 0x13f02d374934a966ULL,
25953 + 0xa0de61894a93f609ULL,
25954 + 0xe7741b60e174093dULL,
25955 + 0x545a57dee2d35652ULL,
25956 + 0xe21ac88218962d7aULL,
25957 + 0x5134843c1b317215ULL,
25958 + 0x169efed5b0d68d21ULL,
25959 + 0xa5b0b26bb371d24eULL,
25960 + 0x99ca0b06e7197349ULL,
25961 + 0x2ae447b8e4be2c26ULL,
25962 + 0x6d4e3d514f59d312ULL,
25963 + 0xde6071ef4cfe8c7dULL,
25964 + 0x15bb4f8be788911cULL,
25965 + 0xa6950335e42fce73ULL,
25966 + 0xe13f79dc4fc83147ULL,
25967 + 0x521135624c6f6e28ULL,
25968 + 0x6e6b8c0f1807cf2fULL,
25969 + 0xdd45c0b11ba09040ULL,
25970 + 0x9aefba58b0476f74ULL,
25971 + 0x29c1f6e6b3e0301bULL,
25972 + 0xc96c5795d7870f42ULL,
25973 + 0x7a421b2bd420502dULL,
25974 + 0x3de861c27fc7af19ULL,
25975 + 0x8ec62d7c7c60f076ULL,
25976 + 0xb2bc941128085171ULL,
25977 + 0x0192d8af2baf0e1eULL,
25978 + 0x4638a2468048f12aULL,
25979 + 0xf516eef883efae45ULL,
25980 + 0x3ecdd09c2899b324ULL,
25981 + 0x8de39c222b3eec4bULL,
25982 + 0xca49e6cb80d9137fULL,
25983 + 0x7967aa75837e4c10ULL,
25984 + 0x451d1318d716ed17ULL,
25985 + 0xf6335fa6d4b1b278ULL,
25986 + 0xb199254f7f564d4cULL,
25987 + 0x02b769f17cf11223ULL,
25988 + 0xb4f7f6ad86b4690bULL,
25989 + 0x07d9ba1385133664ULL,
25990 + 0x4073c0fa2ef4c950ULL,
25991 + 0xf35d8c442d53963fULL,
25992 + 0xcf273529793b3738ULL,
25993 + 0x7c0979977a9c6857ULL,
25994 + 0x3ba3037ed17b9763ULL,
25995 + 0x888d4fc0d2dcc80cULL,
25996 + 0x435671a479aad56dULL,
25997 + 0xf0783d1a7a0d8a02ULL,
25998 + 0xb7d247f3d1ea7536ULL,
25999 + 0x04fc0b4dd24d2a59ULL,
26000 + 0x3886b22086258b5eULL,
26001 + 0x8ba8fe9e8582d431ULL,
26002 + 0xcc0284772e652b05ULL,
26003 + 0x7f2cc8c92dc2746aULL,
26004 + 0x325b15e575e1c3d0ULL,
26005 + 0x8175595b76469cbfULL,
26006 + 0xc6df23b2dda1638bULL,
26007 + 0x75f16f0cde063ce4ULL,
26008 + 0x498bd6618a6e9de3ULL,
26009 + 0xfaa59adf89c9c28cULL,
26010 + 0xbd0fe036222e3db8ULL,
26011 + 0x0e21ac88218962d7ULL,
26012 + 0xc5fa92ec8aff7fb6ULL,
26013 + 0x76d4de52895820d9ULL,
26014 + 0x317ea4bb22bfdfedULL,
26015 + 0x8250e80521188082ULL,
26016 + 0xbe2a516875702185ULL,
26017 + 0x0d041dd676d77eeaULL,
26018 + 0x4aae673fdd3081deULL,
26019 + 0xf9802b81de97deb1ULL,
26020 + 0x4fc0b4dd24d2a599ULL,
26021 + 0xfceef8632775faf6ULL,
26022 + 0xbb44828a8c9205c2ULL,
26023 + 0x086ace348f355aadULL,
26024 + 0x34107759db5dfbaaULL,
26025 + 0x873e3be7d8faa4c5ULL,
26026 + 0xc094410e731d5bf1ULL,
26027 + 0x73ba0db070ba049eULL,
26028 + 0xb86133d4dbcc19ffULL,
26029 + 0x0b4f7f6ad86b4690ULL,
26030 + 0x4ce50583738cb9a4ULL,
26031 + 0xffcb493d702be6cbULL,
26032 + 0xc3b1f050244347ccULL,
26033 + 0x709fbcee27e418a3ULL,
26034 + 0x3735c6078c03e797ULL,
26035 + 0x841b8ab98fa4b8f8ULL,
26036 + 0xadda7c5f3c4488e3ULL,
26037 + 0x1ef430e13fe3d78cULL,
26038 + 0x595e4a08940428b8ULL,
26039 + 0xea7006b697a377d7ULL,
26040 + 0xd60abfdbc3cbd6d0ULL,
26041 + 0x6524f365c06c89bfULL,
26042 + 0x228e898c6b8b768bULL,
26043 + 0x91a0c532682c29e4ULL,
26044 + 0x5a7bfb56c35a3485ULL,
26045 + 0xe955b7e8c0fd6beaULL,
26046 + 0xaeffcd016b1a94deULL,
26047 + 0x1dd181bf68bdcbb1ULL,
26048 + 0x21ab38d23cd56ab6ULL,
26049 + 0x9285746c3f7235d9ULL,
26050 + 0xd52f0e859495caedULL,
26051 + 0x6601423b97329582ULL,
26052 + 0xd041dd676d77eeaaULL,
26053 + 0x636f91d96ed0b1c5ULL,
26054 + 0x24c5eb30c5374ef1ULL,
26055 + 0x97eba78ec690119eULL,
26056 + 0xab911ee392f8b099ULL,
26057 + 0x18bf525d915feff6ULL,
26058 + 0x5f1528b43ab810c2ULL,
26059 + 0xec3b640a391f4fadULL,
26060 + 0x27e05a6e926952ccULL,
26061 + 0x94ce16d091ce0da3ULL,
26062 + 0xd3646c393a29f297ULL,
26063 + 0x604a2087398eadf8ULL,
26064 + 0x5c3099ea6de60cffULL,
26065 + 0xef1ed5546e415390ULL,
26066 + 0xa8b4afbdc5a6aca4ULL,
26067 + 0x1b9ae303c601f3cbULL,
26068 + 0x56ed3e2f9e224471ULL,
26069 + 0xe5c372919d851b1eULL,
26070 + 0xa26908783662e42aULL,
26071 + 0x114744c635c5bb45ULL,
26072 + 0x2d3dfdab61ad1a42ULL,
26073 + 0x9e13b115620a452dULL,
26074 + 0xd9b9cbfcc9edba19ULL,
26075 + 0x6a978742ca4ae576ULL,
26076 + 0xa14cb926613cf817ULL,
26077 + 0x1262f598629ba778ULL,
26078 + 0x55c88f71c97c584cULL,
26079 + 0xe6e6c3cfcadb0723ULL,
26080 + 0xda9c7aa29eb3a624ULL,
26081 + 0x69b2361c9d14f94bULL,
26082 + 0x2e184cf536f3067fULL,
26083 + 0x9d36004b35545910ULL,
26084 + 0x2b769f17cf112238ULL,
26085 + 0x9858d3a9ccb67d57ULL,
26086 + 0xdff2a94067518263ULL,
26087 + 0x6cdce5fe64f6dd0cULL,
26088 + 0x50a65c93309e7c0bULL,
26089 + 0xe388102d33392364ULL,
26090 + 0xa4226ac498dedc50ULL,
26091 + 0x170c267a9b79833fULL,
26092 + 0xdcd7181e300f9e5eULL,
26093 + 0x6ff954a033a8c131ULL,
26094 + 0x28532e49984f3e05ULL,
26095 + 0x9b7d62f79be8616aULL,
26096 + 0xa707db9acf80c06dULL,
26097 + 0x14299724cc279f02ULL,
26098 + 0x5383edcd67c06036ULL,
26099 + 0xe0ada17364673f59ULL
26100 + }
26101 +};
26102 +
26103 +
26104 +/**
26105 + \brief Initializes the crc seed
26106 + */
26107 +static __inline__ uint64_t crc64_init(void)
26108 +{
26109 + return CRC64_ECMA_182.initial;
26110 +}
26111 +
26112 +/**
26113 + \brief Computes 64 bit the crc
26114 + \param[in] data Pointer to the Data in the frame
26115 + \param[in] len Length of the Data
26116 + \param[in] crc seed
26117 + \return calculated crc
26118 + */
26119 +static __inline__ uint64_t crc64_compute(void const *data,
26120 + uint32_t len,
26121 + uint64_t seed)
26122 +{
26123 + uint32_t i;
26124 + uint64_t crc = seed;
26125 + uint8_t *bdata = (uint8_t *) data;
26126 +
26127 + for (i = 0; i < len; i++)
26128 + crc =
26129 + CRC64_ECMA_182.
26130 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
26131 +
26132 + return crc;
26133 +}
26134 +
26135 +
26136 +#endif /* __CRC64_H */
26137 --- /dev/null
26138 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26139 @@ -0,0 +1,7582 @@
26140 +/*
26141 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26142 + *
26143 + * Redistribution and use in source and binary forms, with or without
26144 + * modification, are permitted provided that the following conditions are met:
26145 + * * Redistributions of source code must retain the above copyright
26146 + * notice, this list of conditions and the following disclaimer.
26147 + * * Redistributions in binary form must reproduce the above copyright
26148 + * notice, this list of conditions and the following disclaimer in the
26149 + * documentation and/or other materials provided with the distribution.
26150 + * * Neither the name of Freescale Semiconductor nor the
26151 + * names of its contributors may be used to endorse or promote products
26152 + * derived from this software without specific prior written permission.
26153 + *
26154 + *
26155 + * ALTERNATIVELY, this software may be distributed under the terms of the
26156 + * GNU General Public License ("GPL") as published by the Free Software
26157 + * Foundation, either version 2 of that License or (at your option) any
26158 + * later version.
26159 + *
26160 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26161 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26162 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26163 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26164 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26165 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26166 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26167 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26168 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26169 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26170 + */
26171 +
26172 +
26173 +/******************************************************************************
26174 + @File fm_cc.c
26175 +
26176 + @Description FM Coarse Classifier implementation
26177 + *//***************************************************************************/
26178 +#include <linux/math64.h>
26179 +#include "std_ext.h"
26180 +#include "error_ext.h"
26181 +#include "string_ext.h"
26182 +#include "debug_ext.h"
26183 +#include "fm_pcd_ext.h"
26184 +#include "fm_muram_ext.h"
26185 +
26186 +#include "fm_common.h"
26187 +#include "fm_pcd.h"
26188 +#include "fm_hc.h"
26189 +#include "fm_cc.h"
26190 +#include "crc64.h"
26191 +
26192 +/****************************************/
26193 +/* static functions */
26194 +/****************************************/
26195 +
26196 +
26197 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
26198 +{
26199 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26200 +
26201 + ASSERT_COND(h_FmPcdCcTree);
26202 +
26203 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
26204 + return E_OK;
26205 +
26206 + return ERROR_CODE(E_BUSY);
26207 +}
26208 +
26209 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
26210 +{
26211 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26212 +
26213 + ASSERT_COND(h_FmPcdCcTree);
26214 +
26215 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
26216 +}
26217 +
26218 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
26219 +{
26220 + uint32_t intFlags;
26221 +
26222 + ASSERT_COND(p_CcNode);
26223 +
26224 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26225 +
26226 + if (add)
26227 + p_CcNode->owners++;
26228 + else
26229 + {
26230 + ASSERT_COND(p_CcNode->owners);
26231 + p_CcNode->owners--;
26232 + }
26233 +
26234 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26235 +}
26236 +
26237 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
26238 +{
26239 + t_FmPcdStatsObj *p_StatsObj = NULL;
26240 + t_List *p_Next;
26241 +
26242 + if (!LIST_IsEmpty(p_List))
26243 + {
26244 + p_Next = LIST_FIRST(p_List);
26245 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
26246 + ASSERT_COND(p_StatsObj);
26247 + LIST_DelAndInit(p_Next);
26248 + }
26249 +
26250 + return p_StatsObj;
26251 +}
26252 +
26253 +static __inline__ void EnqueueStatsObj(t_List *p_List,
26254 + t_FmPcdStatsObj *p_StatsObj)
26255 +{
26256 + LIST_AddToTail(&p_StatsObj->node, p_List);
26257 +}
26258 +
26259 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
26260 +{
26261 + t_FmPcdStatsObj *p_StatsObj;
26262 +
26263 + while (!LIST_IsEmpty(p_List))
26264 + {
26265 + p_StatsObj = DequeueStatsObj(p_List);
26266 + ASSERT_COND(p_StatsObj);
26267 +
26268 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26269 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26270 +
26271 + XX_Free(p_StatsObj);
26272 + }
26273 +}
26274 +
26275 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
26276 +{
26277 + t_FmPcdStatsObj* p_StatsObj;
26278 + t_Handle h_FmMuram;
26279 +
26280 + ASSERT_COND(p_CcNode);
26281 +
26282 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26283 + upon node initialization */
26284 + if (p_CcNode->maxNumOfKeys)
26285 + {
26286 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
26287 +
26288 + /* Clean statistics counters & ADs */
26289 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26290 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26291 + }
26292 + else
26293 + {
26294 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26295 + ASSERT_COND(h_FmMuram);
26296 +
26297 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
26298 + if (!p_StatsObj)
26299 + {
26300 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
26301 + return NULL;
26302 + }
26303 +
26304 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
26305 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26306 + if (!p_StatsObj->h_StatsAd)
26307 + {
26308 + XX_Free(p_StatsObj);
26309 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
26310 + return NULL;
26311 + }
26312 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26313 +
26314 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
26315 + h_FmMuram, p_CcNode->countersArraySize,
26316 + FM_PCD_CC_AD_TABLE_ALIGN);
26317 + if (!p_StatsObj->h_StatsCounters)
26318 + {
26319 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26320 + XX_Free(p_StatsObj);
26321 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
26322 + return NULL;
26323 + }
26324 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26325 + }
26326 +
26327 + return p_StatsObj;
26328 +}
26329 +
26330 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
26331 +{
26332 + t_Handle h_FmMuram;
26333 +
26334 + ASSERT_COND(p_CcNode);
26335 + ASSERT_COND(p_StatsObj);
26336 +
26337 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26338 + upon node initialization and now will be enqueued back to the list */
26339 + if (p_CcNode->maxNumOfKeys)
26340 + {
26341 + /* Clean statistics counters */
26342 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26343 +
26344 + /* Clean statistics ADs */
26345 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26346 +
26347 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
26348 + }
26349 + else
26350 + {
26351 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26352 + ASSERT_COND(h_FmMuram);
26353 +
26354 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26355 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26356 +
26357 + XX_Free(p_StatsObj);
26358 + }
26359 +}
26360 +
26361 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
26362 + uint32_t statsCountersAddr)
26363 +{
26364 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
26365 +
26366 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
26367 +}
26368 +
26369 +
26370 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26371 + t_Handle h_Ad, uint64_t physicalMuramBase)
26372 +{
26373 + t_AdOfTypeStats *p_StatsAd;
26374 + uint32_t statsCountersAddr, nextActionAddr, tmp;
26375 +#if (DPAA_VERSION >= 11)
26376 + uint32_t frameLengthRangesAddr;
26377 +#endif /* (DPAA_VERSION >= 11) */
26378 +
26379 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
26380 +
26381 + tmp = FM_PCD_AD_STATS_TYPE;
26382 +
26383 +#if (DPAA_VERSION >= 11)
26384 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26385 + {
26386 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
26387 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
26388 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
26389 + }
26390 +#endif /* (DPAA_VERSION >= 11) */
26391 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
26392 +
26393 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
26394 + tmp = 0;
26395 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
26396 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
26397 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
26398 +
26399 +#if (DPAA_VERSION >= 11)
26400 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26401 + tmp |= FM_PCD_AD_STATS_FLR_EN;
26402 +#endif /* (DPAA_VERSION >= 11) */
26403 +
26404 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
26405 +
26406 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
26407 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
26408 + SetStatsCounters(p_StatsAd, statsCountersAddr);
26409 +}
26410 +
26411 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
26412 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26413 + t_Handle h_FmPcd, t_Handle p_CcNode,
26414 + t_Handle h_Manip, t_Handle h_FrmReplic)
26415 +{
26416 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
26417 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
26418 + t_Handle h_TmpAd;
26419 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
26420 + uint32_t tmpReg32;
26421 + t_Handle p_AdNewPtr = NULL;
26422 +
26423 + UNUSED(h_Manip);
26424 + UNUSED(h_FrmReplic);
26425 +
26426 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
26427 + * Case 1: No Manip. The action descriptor is built within the match table.
26428 + * p_AdResult = p_AdNewPtr;
26429 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
26430 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
26431 + * initialized and returned here.
26432 + * p_AdResult (within the match table) will be initialized after
26433 + * this routine returns and point to the existing AD.
26434 + * Case 3: Manip exists. The action descriptor is built within the match table.
26435 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
26436 + */
26437 +
26438 + /* As default, the "new" ptr is the current one. i.e. the content of the result
26439 + * AD will be written into the match table itself (case (1))*/
26440 + p_AdNewPtr = p_AdContLookup;
26441 +
26442 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
26443 + if (p_FmPcdCcStatsParams)
26444 + {
26445 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
26446 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
26447 +
26448 + /* Swapping addresses between statistics Ad and the current lookup AD */
26449 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
26450 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
26451 + h_Ad = h_TmpAd;
26452 +
26453 + p_AdNewPtr = h_Ad;
26454 + p_AdContLookup = h_Ad;
26455 +
26456 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
26457 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
26458 + }
26459 +
26460 +#if DPAA_VERSION >= 11
26461 + if (h_Manip && h_FrmReplic)
26462 + FmPcdManipUpdateAdContLookupForCc(
26463 + h_Manip,
26464 + h_Ad,
26465 + &p_AdNewPtr,
26466 + (uint32_t)((XX_VirtToPhys(
26467 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
26468 + - p_FmPcd->physicalMuramBase)));
26469 + else
26470 + if (h_FrmReplic)
26471 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
26472 + else
26473 +#endif /* (DPAA_VERSION >= 11) */
26474 + if (h_Manip)
26475 + FmPcdManipUpdateAdContLookupForCc(
26476 + h_Manip,
26477 + h_Ad,
26478 + &p_AdNewPtr,
26479 +
26480 +#ifdef FM_CAPWAP_SUPPORT
26481 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
26482 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
26483 +#else /* not FM_CAPWAP_SUPPORT */
26484 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
26485 + - p_FmPcd->physicalMuramBase))
26486 +#endif /* not FM_CAPWAP_SUPPORT */
26487 + );
26488 +
26489 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
26490 + if (p_AdNewPtr)
26491 + {
26492 + /* cases (1) & (2) */
26493 + tmpReg32 = 0;
26494 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
26495 + tmpReg32 |=
26496 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
26497 + 0;
26498 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
26499 + - p_FmPcd->physicalMuramBase);
26500 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
26501 +
26502 + tmpReg32 = 0;
26503 + tmpReg32 |= p_Node->numOfKeys << 24;
26504 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
26505 + tmpReg32 |=
26506 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
26507 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
26508 + 0;
26509 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
26510 +
26511 + tmpReg32 = 0;
26512 + tmpReg32 |= p_Node->prsArrayOffset << 24;
26513 + tmpReg32 |= p_Node->offset << 16;
26514 + tmpReg32 |= p_Node->parseCode;
26515 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
26516 +
26517 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
26518 + CC_GLBL_MASK_SIZE);
26519 + }
26520 +}
26521 +
26522 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
26523 +{
26524 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
26525 + uint32_t intFlags;
26526 +
26527 + ASSERT_COND(p_CcNode);
26528 +
26529 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26530 +
26531 + if (!p_CcNode->h_Ad)
26532 + {
26533 + if (p_CcNode->maxNumOfKeys)
26534 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
26535 + else
26536 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
26537 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
26538 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26539 +
26540 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26541 +
26542 + if (!p_CcNode->h_Ad)
26543 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
26544 + ("MURAM allocation for CC action descriptor"));
26545 +
26546 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26547 +
26548 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
26549 + p_CcNode, NULL, NULL);
26550 + }
26551 + else
26552 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26553 +
26554 + return E_OK;
26555 +}
26556 +
26557 +static t_Error SetRequiredAction1(
26558 + t_Handle h_FmPcd, uint32_t requiredAction,
26559 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26560 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26561 +{
26562 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
26563 + uint32_t tmpReg32;
26564 + t_Error err;
26565 + t_FmPcdCcNode *p_CcNode;
26566 + int i = 0;
26567 + uint16_t tmp = 0;
26568 + uint16_t profileId;
26569 + uint8_t relativeSchemeId, physicalSchemeId;
26570 + t_CcNodeInformation ccNodeInfo;
26571 +
26572 + for (i = 0; i < numOfEntries; i++)
26573 + {
26574 + if (i == 0)
26575 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
26576 + else
26577 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
26578 +
26579 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
26580 + {
26581 + case (e_FM_PCD_CC):
26582 + if (requiredAction)
26583 + {
26584 + p_CcNode =
26585 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
26586 + ASSERT_COND(p_CcNode);
26587 + if (p_CcNode->shadowAction == requiredAction)
26588 + break;
26589 + if ((requiredAction & UPDATE_CC_WITH_TREE)
26590 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
26591 + {
26592 +
26593 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26594 + ccNodeInfo.h_CcNode = h_Tree;
26595 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
26596 + &ccNodeInfo, NULL);
26597 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26598 + UPDATE_CC_WITH_TREE;
26599 + }
26600 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
26601 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
26602 + {
26603 +
26604 + p_CcNode->shadowAction = 0;
26605 + }
26606 +
26607 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
26608 + && !(p_CcNode->shadowAction
26609 + & UPDATE_CC_WITH_DELETE_TREE))
26610 + {
26611 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
26612 + h_Tree, NULL);
26613 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26614 + UPDATE_CC_WITH_DELETE_TREE;
26615 + }
26616 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
26617 + != e_FM_PCD_INVALID)
26618 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
26619 + else
26620 + tmp = p_CcNode->numOfKeys;
26621 + err = SetRequiredAction1(h_FmPcd, requiredAction,
26622 + p_CcNode->keyAndNextEngineParams,
26623 + p_CcNode->h_AdTable, tmp, h_Tree);
26624 + if (err != E_OK)
26625 + return err;
26626 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
26627 + p_CcNode->shadowAction |= requiredAction;
26628 + }
26629 + break;
26630 +
26631 + case (e_FM_PCD_KG):
26632 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26633 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26634 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26635 + {
26636 + physicalSchemeId =
26637 + FmPcdKgGetSchemeId(
26638 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
26639 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
26640 + h_FmPcd, physicalSchemeId);
26641 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
26642 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
26643 + if (!FmPcdKgIsSchemeValidSw(
26644 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
26645 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
26646 + ("Invalid direct scheme."));
26647 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
26648 + RETURN_ERROR(
26649 + MAJOR, E_INVALID_STATE,
26650 + ("For this action scheme has to be direct."));
26651 + err =
26652 + FmPcdKgCcGetSetParams(
26653 + h_FmPcd,
26654 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
26655 + requiredAction, 0);
26656 + if (err != E_OK)
26657 + RETURN_ERROR(MAJOR, err, NO_MSG);
26658 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26659 + requiredAction;
26660 + }
26661 + break;
26662 +
26663 + case (e_FM_PCD_PLCR):
26664 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26665 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26666 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26667 + {
26668 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
26669 + RETURN_ERROR(
26670 + MAJOR,
26671 + E_NOT_SUPPORTED,
26672 + ("In this initialization only overrideFqid can be initialized"));
26673 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
26674 + RETURN_ERROR(
26675 + MAJOR,
26676 + E_NOT_SUPPORTED,
26677 + ("In this initialization only overrideFqid can be initialized"));
26678 + err =
26679 + FmPcdPlcrGetAbsoluteIdByProfileParams(
26680 + h_FmPcd,
26681 + e_FM_PCD_PLCR_SHARED,
26682 + NULL,
26683 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
26684 + &profileId);
26685 + if (err != E_OK)
26686 + RETURN_ERROR(MAJOR, err, NO_MSG);
26687 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
26688 + requiredAction);
26689 + if (err != E_OK)
26690 + RETURN_ERROR(MAJOR, err, NO_MSG);
26691 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26692 + requiredAction;
26693 + }
26694 + break;
26695 +
26696 + case (e_FM_PCD_DONE):
26697 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26698 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26699 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26700 + {
26701 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
26702 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26703 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
26704 + RETURN_ERROR(
26705 + MAJOR,
26706 + E_INVALID_STATE,
26707 + ("Next engine was previously assigned not as PCD_DONE"));
26708 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
26709 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
26710 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26711 + requiredAction;
26712 + }
26713 + break;
26714 +
26715 + default:
26716 + break;
26717 + }
26718 + }
26719 +
26720 + return E_OK;
26721 +}
26722 +
26723 +static t_Error SetRequiredAction(
26724 + t_Handle h_FmPcd, uint32_t requiredAction,
26725 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26726 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26727 +{
26728 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
26729 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26730 + numOfEntries, h_Tree);
26731 + if (err != E_OK)
26732 + return err;
26733 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
26734 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
26735 + numOfEntries, h_Tree);
26736 +}
26737 +
26738 +static t_Error ReleaseModifiedDataStructure(
26739 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
26740 + t_List *h_FmPcdNewPointersLst,
26741 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
26742 + bool useShadowStructs)
26743 +{
26744 + t_List *p_Pos;
26745 + t_Error err = E_OK;
26746 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
26747 + t_Handle h_Muram;
26748 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
26749 + t_List *p_UpdateLst;
26750 + uint32_t intFlags;
26751 +
26752 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
26753 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
26754 + E_INVALID_HANDLE);
26755 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
26756 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
26757 +
26758 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
26759 + if (p_AdditionalParams->h_NodeForAdd)
26760 + {
26761 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
26762 +
26763 + if (!p_AdditionalParams->tree)
26764 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26765 + else
26766 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
26767 +
26768 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26769 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
26770 + p_FmPcdCcNextNode->h_Spinlock);
26771 +
26772 + if (p_CcNodeInformation)
26773 + p_CcNodeInformation->index++;
26774 + else
26775 + {
26776 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26777 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
26778 + ccNodeInfo.index = 1;
26779 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
26780 + p_FmPcdCcNextNode->h_Spinlock);
26781 + }
26782 + if (p_AdditionalParams->h_ManipForAdd)
26783 + {
26784 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26785 + FmPcdManipGetNodeLstPointedOnThisManip(
26786 + p_AdditionalParams->h_ManipForAdd),
26787 + p_AdditionalParams->h_CurrentNode,
26788 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
26789 +
26790 + if (p_CcNodeInformation)
26791 + p_CcNodeInformation->index++;
26792 + else
26793 + {
26794 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26795 + ccNodeInfo.h_CcNode =
26796 + (t_Handle)p_AdditionalParams->h_CurrentNode;
26797 + ccNodeInfo.index = 1;
26798 + EnqueueNodeInfoToRelevantLst(
26799 + FmPcdManipGetNodeLstPointedOnThisManip(
26800 + p_AdditionalParams->h_ManipForAdd),
26801 + &ccNodeInfo,
26802 + FmPcdManipGetSpinlock(
26803 + p_AdditionalParams->h_ManipForAdd));
26804 + }
26805 + }
26806 + }
26807 +
26808 + if (p_AdditionalParams->h_NodeForRmv)
26809 + {
26810 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
26811 +
26812 + if (!p_AdditionalParams->tree)
26813 + {
26814 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
26815 + p_FmPcdCcWorkingOnNode =
26816 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
26817 +
26818 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
26819 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
26820 + LIST_NEXT(p_Pos))
26821 + {
26822 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
26823 +
26824 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
26825 +
26826 + err =
26827 + SetRequiredAction(
26828 + h_FmPcd,
26829 + UPDATE_CC_WITH_DELETE_TREE,
26830 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
26831 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
26832 + 1, p_CcNodeInformation->h_CcNode);
26833 + }
26834 + }
26835 + else
26836 + {
26837 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
26838 +
26839 + err =
26840 + SetRequiredAction(
26841 + h_FmPcd,
26842 + UPDATE_CC_WITH_DELETE_TREE,
26843 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
26844 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
26845 + 1, p_AdditionalParams->h_CurrentNode);
26846 + }
26847 + if (err)
26848 + return err;
26849 +
26850 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
26851 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
26852 + Update of the node owner */
26853 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26854 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
26855 + p_FmPcdCcNextNode->h_Spinlock);
26856 +
26857 + ASSERT_COND(p_CcNodeInformation);
26858 + ASSERT_COND(p_CcNodeInformation->index);
26859 +
26860 + p_CcNodeInformation->index--;
26861 +
26862 + if (p_CcNodeInformation->index == 0)
26863 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
26864 + p_AdditionalParams->h_CurrentNode,
26865 + p_FmPcdCcNextNode->h_Spinlock);
26866 +
26867 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
26868 +
26869 + if (p_AdditionalParams->h_ManipForRmv)
26870 + {
26871 + p_CcNodeInformation = FindNodeInfoInReleventLst(
26872 + FmPcdManipGetNodeLstPointedOnThisManip(
26873 + p_AdditionalParams->h_ManipForRmv),
26874 + p_AdditionalParams->h_CurrentNode,
26875 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
26876 +
26877 + ASSERT_COND(p_CcNodeInformation);
26878 + ASSERT_COND(p_CcNodeInformation->index);
26879 +
26880 + p_CcNodeInformation->index--;
26881 +
26882 + if (p_CcNodeInformation->index == 0)
26883 + DequeueNodeInfoFromRelevantLst(
26884 + FmPcdManipGetNodeLstPointedOnThisManip(
26885 + p_AdditionalParams->h_ManipForRmv),
26886 + p_AdditionalParams->h_CurrentNode,
26887 + FmPcdManipGetSpinlock(
26888 + p_AdditionalParams->h_ManipForRmv));
26889 + }
26890 + }
26891 +
26892 + if (p_AdditionalParams->h_ManipForRmv)
26893 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
26894 +
26895 + if (p_AdditionalParams->p_StatsObjForRmv)
26896 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
26897 + p_AdditionalParams->p_StatsObjForRmv);
26898 +
26899 +#if (DPAA_VERSION >= 11)
26900 + if (p_AdditionalParams->h_FrmReplicForRmv)
26901 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
26902 + FALSE/* remove */);
26903 +#endif /* (DPAA_VERSION >= 11) */
26904 +
26905 + if (!useShadowStructs)
26906 + {
26907 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
26908 + ASSERT_COND(h_Muram);
26909 +
26910 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
26911 + || (!p_AdditionalParams->tree
26912 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
26913 + {
26914 + /* We release new AD which was allocated and updated for copy from to actual AD */
26915 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
26916 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
26917 + {
26918 +
26919 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
26920 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
26921 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
26922 + }
26923 + }
26924 +
26925 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
26926 + if (p_AdditionalParams->p_AdTableOld)
26927 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
26928 +
26929 + if (p_AdditionalParams->p_KeysMatchTableOld)
26930 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
26931 + }
26932 +
26933 + /* Update current modified node with changed fields if it's required*/
26934 + if (!p_AdditionalParams->tree)
26935 + {
26936 + if (p_AdditionalParams->p_AdTableNew)
26937 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
26938 + p_AdditionalParams->p_AdTableNew;
26939 +
26940 + if (p_AdditionalParams->p_KeysMatchTableNew)
26941 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
26942 + p_AdditionalParams->p_KeysMatchTableNew;
26943 +
26944 + /* Locking node's spinlock before updating 'keys and next engine' structure,
26945 + as it maybe used to retrieve keys statistics */
26946 + intFlags =
26947 + XX_LockIntrSpinlock(
26948 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
26949 +
26950 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
26951 + p_AdditionalParams->numOfKeys;
26952 +
26953 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
26954 + &p_AdditionalParams->keyAndNextEngineParams,
26955 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
26956 +
26957 + XX_UnlockIntrSpinlock(
26958 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
26959 + intFlags);
26960 + }
26961 + else
26962 + {
26963 + uint8_t numEntries =
26964 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
26965 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
26966 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
26967 + &p_AdditionalParams->keyAndNextEngineParams,
26968 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
26969 + }
26970 +
26971 + ReleaseLst(h_FmPcdOldPointersLst);
26972 + ReleaseLst(h_FmPcdNewPointersLst);
26973 +
26974 + XX_Free(p_AdditionalParams);
26975 +
26976 + return E_OK;
26977 +}
26978 +
26979 +static t_Handle BuildNewAd(
26980 + t_Handle h_Ad,
26981 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
26982 + t_FmPcdCcNode *p_CcNode,
26983 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
26984 +{
26985 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
26986 + t_Handle h_OrigAd = NULL;
26987 +
26988 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
26989 + if (!p_FmPcdCcNodeTmp)
26990 + {
26991 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
26992 + return NULL;
26993 + }
26994 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
26995 +
26996 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
26997 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
26998 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
26999 + p_FmPcdCcNodeTmp->h_AdTable =
27000 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
27001 +
27002 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
27003 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
27004 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
27005 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
27006 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
27007 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
27008 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
27009 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
27010 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
27011 +
27012 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
27013 + {
27014 + if (p_FmPcdCcNextEngineParams->h_Manip)
27015 + {
27016 + h_OrigAd = p_CcNode->h_Ad;
27017 + if (AllocAndFillAdForContLookupManip(
27018 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27019 + != E_OK)
27020 + {
27021 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
27022 + XX_Free(p_FmPcdCcNodeTmp);
27023 + return NULL;
27024 + }
27025 + }
27026 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27027 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
27028 + }
27029 +
27030 +#if (DPAA_VERSION >= 11)
27031 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
27032 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
27033 + {
27034 + FillAdOfTypeContLookup(
27035 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27036 + p_FmPcdCcNextEngineParams->h_Manip,
27037 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
27038 + }
27039 +#endif /* (DPAA_VERSION >= 11) */
27040 +
27041 + XX_Free(p_FmPcdCcNodeTmp);
27042 +
27043 + return E_OK;
27044 +}
27045 +
27046 +static t_Error DynamicChangeHc(
27047 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27048 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27049 + bool useShadowStructs)
27050 +{
27051 + t_List *p_PosOld, *p_PosNew;
27052 + uint32_t oldAdAddrOffset, newAdAddrOffset;
27053 + uint16_t i = 0;
27054 + t_Error err = E_OK;
27055 + uint8_t numOfModifiedPtr;
27056 +
27057 + ASSERT_COND(h_FmPcd);
27058 + ASSERT_COND(h_OldPointersLst);
27059 + ASSERT_COND(h_NewPointersLst);
27060 +
27061 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27062 +
27063 + if (numOfModifiedPtr)
27064 + {
27065 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27066 + p_PosOld = LIST_FIRST(h_OldPointersLst);
27067 +
27068 + /* Retrieve address of new AD */
27069 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27070 + p_PosNew);
27071 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27072 + {
27073 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27074 + h_NewPointersLst,
27075 + p_AdditionalParams, useShadowStructs);
27076 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
27077 + }
27078 +
27079 + for (i = 0; i < numOfModifiedPtr; i++)
27080 + {
27081 + /* Retrieve address of current AD */
27082 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27083 + p_PosOld);
27084 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27085 + {
27086 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27087 + h_NewPointersLst,
27088 + p_AdditionalParams,
27089 + useShadowStructs);
27090 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
27091 + }
27092 +
27093 + /* Invoke host command to copy from new AD to old AD */
27094 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
27095 + oldAdAddrOffset, newAdAddrOffset);
27096 + if (err)
27097 + {
27098 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27099 + h_NewPointersLst,
27100 + p_AdditionalParams,
27101 + useShadowStructs);
27102 + RETURN_ERROR(
27103 + MAJOR,
27104 + err,
27105 + ("For part of nodes changes are done - situation is danger"));
27106 + }
27107 +
27108 + p_PosOld = LIST_NEXT(p_PosOld);
27109 + }
27110 + }
27111 + return E_OK;
27112 +}
27113 +
27114 +static t_Error DoDynamicChange(
27115 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27116 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27117 + bool useShadowStructs)
27118 +{
27119 + t_FmPcdCcNode *p_CcNode =
27120 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27121 + t_List *p_PosNew;
27122 + t_CcNodeInformation *p_CcNodeInfo;
27123 + t_FmPcdCcNextEngineParams nextEngineParams;
27124 + t_Handle h_Ad;
27125 + uint32_t keySize;
27126 + t_Error err = E_OK;
27127 + uint8_t numOfModifiedPtr;
27128 +
27129 + ASSERT_COND(h_FmPcd);
27130 +
27131 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
27132 +
27133 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27134 +
27135 + if (numOfModifiedPtr)
27136 + {
27137 +
27138 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27139 +
27140 + /* Invoke host-command to copy from the new Ad to existing Ads */
27141 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27142 + p_AdditionalParams, useShadowStructs);
27143 + if (err)
27144 + RETURN_ERROR(MAJOR, err, NO_MSG);
27145 +
27146 + if (useShadowStructs)
27147 + {
27148 + /* When the host-command above has ended, the old structures are 'free'and we can update
27149 + them by copying from the new shadow structures. */
27150 + if (p_CcNode->lclMask)
27151 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
27152 + else
27153 + keySize = p_CcNode->ccKeySizeAccExtraction;
27154 +
27155 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
27156 + p_AdditionalParams->p_KeysMatchTableNew,
27157 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
27158 +
27159 + MemCpy8(
27160 + p_AdditionalParams->p_AdTableOld,
27161 + p_AdditionalParams->p_AdTableNew,
27162 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
27163 + * FM_PCD_CC_AD_ENTRY_SIZE));
27164 +
27165 + /* Retrieve the address of the allocated Ad */
27166 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
27167 + h_Ad = p_CcNodeInfo->h_CcNode;
27168 +
27169 + /* Build a new Ad that holds the old (now updated) structures */
27170 + p_AdditionalParams->p_KeysMatchTableNew =
27171 + p_AdditionalParams->p_KeysMatchTableOld;
27172 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
27173 +
27174 + nextEngineParams.nextEngine = e_FM_PCD_CC;
27175 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
27176 +
27177 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
27178 +
27179 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
27180 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27181 + p_AdditionalParams, useShadowStructs);
27182 + if (err)
27183 + RETURN_ERROR(MAJOR, err, NO_MSG);
27184 + }
27185 + }
27186 +
27187 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27188 + h_NewPointersLst,
27189 + p_AdditionalParams, useShadowStructs);
27190 + if (err)
27191 + RETURN_ERROR(MAJOR, err, NO_MSG);
27192 +
27193 + return E_OK;
27194 +}
27195 +
27196 +#ifdef FM_CAPWAP_SUPPORT
27197 +static bool IsCapwapApplSpecific(t_Handle h_Node)
27198 +{
27199 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
27200 + bool isManipForCapwapApplSpecificBuild = FALSE;
27201 + int i = 0;
27202 +
27203 + ASSERT_COND(h_Node);
27204 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
27205 + for (i = 0; i < p_CcNode->numOfKeys; i++)
27206 + {
27207 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
27208 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
27209 + {
27210 + isManipForCapwapApplSpecificBuild = TRUE;
27211 + break;
27212 + }
27213 + }
27214 + return isManipForCapwapApplSpecificBuild;
27215 +
27216 +}
27217 +#endif /* FM_CAPWAP_SUPPORT */
27218 +
27219 +static t_Error CcUpdateParam(
27220 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
27221 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
27222 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
27223 + t_Handle h_FmTree, bool modify)
27224 +{
27225 + t_FmPcdCcNode *p_CcNode;
27226 + t_Error err;
27227 + uint16_t tmp = 0;
27228 + int i = 0;
27229 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
27230 +
27231 + level++;
27232 +
27233 + if (p_CcTree->h_IpReassemblyManip)
27234 + {
27235 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27236 + p_CcTree->h_IpReassemblyManip, NULL, validate,
27237 + level, h_FmTree, modify);
27238 + if (err)
27239 + RETURN_ERROR(MAJOR, err, NO_MSG);
27240 + }
27241 +
27242 + if (p_CcTree->h_CapwapReassemblyManip)
27243 + {
27244 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27245 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
27246 + level, h_FmTree, modify);
27247 + if (err)
27248 + RETURN_ERROR(MAJOR, err, NO_MSG);
27249 + }
27250 +
27251 + if (numOfEntries)
27252 + {
27253 + for (i = 0; i < numOfEntries; i++)
27254 + {
27255 + if (i == 0)
27256 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
27257 + else
27258 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
27259 +
27260 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
27261 + == e_FM_PCD_CC)
27262 + {
27263 + p_CcNode =
27264 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
27265 + ASSERT_COND(p_CcNode);
27266 +
27267 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27268 + {
27269 + err =
27270 + FmPcdManipUpdate(
27271 + h_FmPcd,
27272 + NULL,
27273 + h_FmPort,
27274 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27275 + h_Ad, validate, level, h_FmTree, modify);
27276 + if (err)
27277 + RETURN_ERROR(MAJOR, err, NO_MSG);
27278 + }
27279 +
27280 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
27281 + != e_FM_PCD_INVALID)
27282 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
27283 + else
27284 + tmp = p_CcNode->numOfKeys;
27285 +
27286 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
27287 + p_CcNode->keyAndNextEngineParams, tmp,
27288 + p_CcNode->h_AdTable, validate, level,
27289 + h_FmTree, modify);
27290 + if (err)
27291 + RETURN_ERROR(MAJOR, err, NO_MSG);
27292 + }
27293 + else
27294 + {
27295 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27296 + {
27297 + err =
27298 + FmPcdManipUpdate(
27299 + h_FmPcd,
27300 + NULL,
27301 + h_FmPort,
27302 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27303 + h_Ad, validate, level, h_FmTree, modify);
27304 + if (err)
27305 + RETURN_ERROR(MAJOR, err, NO_MSG);
27306 + }
27307 + }
27308 + }
27309 + }
27310 +
27311 + return E_OK;
27312 +}
27313 +
27314 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
27315 +{
27316 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
27317 + {
27318 + case (e_FM_PCD_ACTION_EXACT_MATCH):
27319 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27320 + {
27321 + case (e_FM_PCD_EXTRACT_FROM_KEY):
27322 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
27323 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27324 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
27325 + default:
27326 + return CC_PRIVATE_INFO_NONE;
27327 + }
27328 +
27329 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
27330 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27331 + {
27332 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27333 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
27334 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
27335 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
27336 + default:
27337 + return CC_PRIVATE_INFO_NONE;
27338 + }
27339 +
27340 + default:
27341 + break;
27342 + }
27343 +
27344 + return CC_PRIVATE_INFO_NONE;
27345 +}
27346 +
27347 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
27348 + t_List *p_List)
27349 +{
27350 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27351 +
27352 + if (!LIST_IsEmpty(p_List))
27353 + {
27354 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
27355 + LIST_DelAndInit(&p_CcNodeInfo->node);
27356 + }
27357 +
27358 + return p_CcNodeInfo;
27359 +}
27360 +
27361 +void ReleaseLst(t_List *p_List)
27362 +{
27363 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27364 +
27365 + if (!LIST_IsEmpty(p_List))
27366 + {
27367 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27368 + while (p_CcNodeInfo)
27369 + {
27370 + XX_Free(p_CcNodeInfo);
27371 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27372 + }
27373 + }
27374 +
27375 + LIST_Del(p_List);
27376 +}
27377 +
27378 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
27379 +{
27380 + uint32_t i;
27381 +
27382 + if (!p_CcNode)
27383 + return;
27384 +
27385 + if (p_CcNode->p_GlblMask)
27386 + {
27387 + XX_Free(p_CcNode->p_GlblMask);
27388 + p_CcNode->p_GlblMask = NULL;
27389 + }
27390 +
27391 + if (p_CcNode->h_KeysMatchTable)
27392 + {
27393 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27394 + p_CcNode->h_KeysMatchTable);
27395 + p_CcNode->h_KeysMatchTable = NULL;
27396 + }
27397 +
27398 + if (p_CcNode->h_AdTable)
27399 + {
27400 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27401 + p_CcNode->h_AdTable);
27402 + p_CcNode->h_AdTable = NULL;
27403 + }
27404 +
27405 + if (p_CcNode->h_Ad)
27406 + {
27407 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27408 + p_CcNode->h_Ad);
27409 + p_CcNode->h_Ad = NULL;
27410 + p_CcNode->h_TmpAd = NULL;
27411 + }
27412 +
27413 + if (p_CcNode->h_StatsFLRs)
27414 + {
27415 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27416 + p_CcNode->h_StatsFLRs);
27417 + p_CcNode->h_StatsFLRs = NULL;
27418 + }
27419 +
27420 + if (p_CcNode->h_Spinlock)
27421 + {
27422 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
27423 + p_CcNode->h_Spinlock = NULL;
27424 + }
27425 +
27426 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
27427 + if (p_CcNode->isHashBucket
27428 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
27429 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
27430 + p_CcNode->h_PrivMissStatsCounters;
27431 +
27432 + /* Releasing all currently used statistics objects, including 'miss' entry */
27433 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
27434 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
27435 + PutStatsObj(p_CcNode,
27436 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
27437 +
27438 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
27439 + {
27440 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
27441 + ASSERT_COND(h_FmMuram);
27442 +
27443 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
27444 + }
27445 +
27446 + LIST_Del(&p_CcNode->availableStatsLst);
27447 +
27448 + ReleaseLst(&p_CcNode->availableStatsLst);
27449 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
27450 + ReleaseLst(&p_CcNode->ccTreeIdLst);
27451 + ReleaseLst(&p_CcNode->ccTreesLst);
27452 +
27453 + XX_Free(p_CcNode);
27454 +}
27455 +
27456 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
27457 +{
27458 + if (p_FmPcdTree)
27459 + {
27460 + if (p_FmPcdTree->ccTreeBaseAddr)
27461 + {
27462 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
27463 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
27464 + p_FmPcdTree->ccTreeBaseAddr = 0;
27465 + }
27466 +
27467 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
27468 +
27469 + XX_Free(p_FmPcdTree);
27470 + }
27471 +}
27472 +
27473 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
27474 + uint8_t *parseCodeCcSize)
27475 +{
27476 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
27477 + *parseCodeCcSize = 1;
27478 + else
27479 + if (parseCodeRealSize == 2)
27480 + *parseCodeCcSize = 2;
27481 + else
27482 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
27483 + *parseCodeCcSize = 4;
27484 + else
27485 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
27486 + *parseCodeCcSize = 8;
27487 + else
27488 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
27489 + *parseCodeCcSize = 16;
27490 + else
27491 + if ((parseCodeRealSize > 16)
27492 + && (parseCodeRealSize <= 24))
27493 + *parseCodeCcSize = 24;
27494 + else
27495 + if ((parseCodeRealSize > 24)
27496 + && (parseCodeRealSize <= 32))
27497 + *parseCodeCcSize = 32;
27498 + else
27499 + if ((parseCodeRealSize > 32)
27500 + && (parseCodeRealSize <= 40))
27501 + *parseCodeCcSize = 40;
27502 + else
27503 + if ((parseCodeRealSize > 40)
27504 + && (parseCodeRealSize <= 48))
27505 + *parseCodeCcSize = 48;
27506 + else
27507 + if ((parseCodeRealSize > 48)
27508 + && (parseCodeRealSize <= 56))
27509 + *parseCodeCcSize = 56;
27510 + else
27511 + *parseCodeCcSize = 0;
27512 +}
27513 +
27514 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
27515 + uint8_t *parseCodeRealSize)
27516 +{
27517 + switch (hdr)
27518 + {
27519 + case (HEADER_TYPE_ETH):
27520 + switch (field.eth)
27521 + {
27522 + case (NET_HEADER_FIELD_ETH_DA):
27523 + *parseCodeRealSize = 6;
27524 + break;
27525 +
27526 + case (NET_HEADER_FIELD_ETH_SA):
27527 + *parseCodeRealSize = 6;
27528 + break;
27529 +
27530 + case (NET_HEADER_FIELD_ETH_TYPE):
27531 + *parseCodeRealSize = 2;
27532 + break;
27533 +
27534 + default:
27535 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27536 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27537 + break;
27538 + }
27539 + break;
27540 +
27541 + case (HEADER_TYPE_PPPoE):
27542 + switch (field.pppoe)
27543 + {
27544 + case (NET_HEADER_FIELD_PPPoE_PID):
27545 + *parseCodeRealSize = 2;
27546 + break;
27547 +
27548 + default:
27549 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27550 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27551 + break;
27552 + }
27553 + break;
27554 +
27555 + case (HEADER_TYPE_VLAN):
27556 + switch (field.vlan)
27557 + {
27558 + case (NET_HEADER_FIELD_VLAN_TCI):
27559 + *parseCodeRealSize = 2;
27560 + break;
27561 +
27562 + default:
27563 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
27564 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27565 + break;
27566 + }
27567 + break;
27568 +
27569 + case (HEADER_TYPE_MPLS):
27570 + switch (field.mpls)
27571 + {
27572 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27573 + *parseCodeRealSize = 4;
27574 + break;
27575 +
27576 + default:
27577 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
27578 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27579 + break;
27580 + }
27581 + break;
27582 +
27583 + case (HEADER_TYPE_IPv4):
27584 + switch (field.ipv4)
27585 + {
27586 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27587 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27588 + *parseCodeRealSize = 4;
27589 + break;
27590 +
27591 + case (NET_HEADER_FIELD_IPv4_TOS):
27592 + case (NET_HEADER_FIELD_IPv4_PROTO):
27593 + *parseCodeRealSize = 1;
27594 + break;
27595 +
27596 + case (NET_HEADER_FIELD_IPv4_DST_IP
27597 + | NET_HEADER_FIELD_IPv4_SRC_IP):
27598 + *parseCodeRealSize = 8;
27599 + break;
27600 +
27601 + case (NET_HEADER_FIELD_IPv4_TTL):
27602 + *parseCodeRealSize = 1;
27603 + break;
27604 +
27605 + default:
27606 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
27607 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27608 + break;
27609 + }
27610 + break;
27611 +
27612 + case (HEADER_TYPE_IPv6):
27613 + switch (field.ipv6)
27614 + {
27615 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
27616 + | NET_HEADER_FIELD_IPv6_TC):
27617 + *parseCodeRealSize = 4;
27618 + break;
27619 +
27620 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
27621 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
27622 + *parseCodeRealSize = 1;
27623 + break;
27624 +
27625 + case (NET_HEADER_FIELD_IPv6_DST_IP):
27626 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
27627 + *parseCodeRealSize = 16;
27628 + break;
27629 +
27630 + default:
27631 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27632 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27633 + break;
27634 + }
27635 + break;
27636 +
27637 + case (HEADER_TYPE_IP):
27638 + switch (field.ip)
27639 + {
27640 + case (NET_HEADER_FIELD_IP_DSCP):
27641 + case (NET_HEADER_FIELD_IP_PROTO):
27642 + *parseCodeRealSize = 1;
27643 + break;
27644 +
27645 + default:
27646 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27647 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27648 + break;
27649 + }
27650 + break;
27651 +
27652 + case (HEADER_TYPE_GRE):
27653 + switch (field.gre)
27654 + {
27655 + case (NET_HEADER_FIELD_GRE_TYPE):
27656 + *parseCodeRealSize = 2;
27657 + break;
27658 +
27659 + default:
27660 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
27661 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27662 + break;
27663 + }
27664 + break;
27665 +
27666 + case (HEADER_TYPE_MINENCAP):
27667 + switch (field.minencap)
27668 + {
27669 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
27670 + *parseCodeRealSize = 1;
27671 + break;
27672 +
27673 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
27674 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
27675 + *parseCodeRealSize = 4;
27676 + break;
27677 +
27678 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
27679 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
27680 + *parseCodeRealSize = 8;
27681 + break;
27682 +
27683 + default:
27684 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
27685 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27686 + break;
27687 + }
27688 + break;
27689 +
27690 + case (HEADER_TYPE_TCP):
27691 + switch (field.tcp)
27692 + {
27693 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
27694 + case (NET_HEADER_FIELD_TCP_PORT_DST):
27695 + *parseCodeRealSize = 2;
27696 + break;
27697 +
27698 + case (NET_HEADER_FIELD_TCP_PORT_SRC
27699 + | NET_HEADER_FIELD_TCP_PORT_DST):
27700 + *parseCodeRealSize = 4;
27701 + break;
27702 +
27703 + default:
27704 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
27705 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27706 + break;
27707 + }
27708 + break;
27709 +
27710 + case (HEADER_TYPE_UDP):
27711 + switch (field.udp)
27712 + {
27713 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
27714 + case (NET_HEADER_FIELD_UDP_PORT_DST):
27715 + *parseCodeRealSize = 2;
27716 + break;
27717 +
27718 + case (NET_HEADER_FIELD_UDP_PORT_SRC
27719 + | NET_HEADER_FIELD_UDP_PORT_DST):
27720 + *parseCodeRealSize = 4;
27721 + break;
27722 +
27723 + default:
27724 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
27725 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27726 + break;
27727 + }
27728 + break;
27729 +
27730 + default:
27731 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
27732 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27733 + break;
27734 + }
27735 +}
27736 +
27737 +t_Error ValidateNextEngineParams(
27738 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
27739 + e_FmPcdCcStatsMode statsMode)
27740 +{
27741 + uint16_t absoluteProfileId;
27742 + t_Error err = E_OK;
27743 + uint8_t relativeSchemeId;
27744 +
27745 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
27746 + && (p_FmPcdCcNextEngineParams->statisticsEn))
27747 + RETURN_ERROR(
27748 + MAJOR,
27749 + E_CONFLICT,
27750 + ("Statistics are requested for a key, but statistics mode was set"
27751 + "to 'NONE' upon initialization"));
27752 +
27753 + switch (p_FmPcdCcNextEngineParams->nextEngine)
27754 + {
27755 + case (e_FM_PCD_INVALID):
27756 + err = E_NOT_SUPPORTED;
27757 + break;
27758 +
27759 + case (e_FM_PCD_DONE):
27760 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
27761 + == e_FM_PCD_ENQ_FRAME)
27762 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
27763 + {
27764 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
27765 + RETURN_ERROR(
27766 + MAJOR,
27767 + E_CONFLICT,
27768 + ("When overrideFqid is set, newFqid must not be zero"));
27769 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
27770 + & ~0x00FFFFFF)
27771 + RETURN_ERROR(
27772 + MAJOR, E_INVALID_VALUE,
27773 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
27774 + }
27775 + break;
27776 +
27777 + case (e_FM_PCD_KG):
27778 + relativeSchemeId =
27779 + FmPcdKgGetRelativeSchemeId(
27780 + h_FmPcd,
27781 + FmPcdKgGetSchemeId(
27782 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
27783 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
27784 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
27785 + if (!FmPcdKgIsSchemeValidSw(
27786 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
27787 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27788 + ("not valid schemeIndex in KG next engine param"));
27789 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
27790 + RETURN_ERROR(
27791 + MAJOR,
27792 + E_INVALID_STATE,
27793 + ("CC Node may point only to a scheme that is always direct."));
27794 + break;
27795 +
27796 + case (e_FM_PCD_PLCR):
27797 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
27798 + {
27799 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
27800 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
27801 + {
27802 + err =
27803 + FmPcdPlcrGetAbsoluteIdByProfileParams(
27804 + h_FmPcd,
27805 + e_FM_PCD_PLCR_SHARED,
27806 + NULL,
27807 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
27808 + &absoluteProfileId);
27809 + if (err)
27810 + RETURN_ERROR(MAJOR, err,
27811 + ("Shared profile offset is out of range"));
27812 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
27813 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27814 + ("Invalid profile"));
27815 + }
27816 + }
27817 + break;
27818 +
27819 + case (e_FM_PCD_HASH):
27820 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
27821 + case (e_FM_PCD_CC):
27822 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27823 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
27824 + ("handler to next Node is NULL"));
27825 + break;
27826 +
27827 +#if (DPAA_VERSION >= 11)
27828 + case (e_FM_PCD_FR):
27829 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
27830 + err = E_NOT_SUPPORTED;
27831 + break;
27832 +#endif /* (DPAA_VERSION >= 11) */
27833 +
27834 + default:
27835 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27836 + ("Next engine is not correct"));
27837 + }
27838 +
27839 +
27840 + return err;
27841 +}
27842 +
27843 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
27844 + uint32_t offset, bool glblMask,
27845 + uint8_t *parseArrayOffset, bool fromIc,
27846 + ccPrivateInfo_t icCode)
27847 +{
27848 + if (!fromIc)
27849 + {
27850 + switch (src)
27851 + {
27852 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
27853 + if (glblMask)
27854 + return CC_PC_GENERIC_WITH_MASK;
27855 + else
27856 + return CC_PC_GENERIC_WITHOUT_MASK;
27857 +
27858 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
27859 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
27860 + if (offset)
27861 + return CC_PR_OFFSET;
27862 + else
27863 + return CC_PR_WITHOUT_OFFSET;
27864 +
27865 + default:
27866 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
27867 + return CC_PC_ILLEGAL;
27868 + }
27869 + }
27870 + else
27871 + {
27872 + switch (icCode)
27873 + {
27874 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
27875 + *parseArrayOffset = 0x50;
27876 + return CC_PC_GENERIC_IC_GMASK;
27877 +
27878 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
27879 + *parseArrayOffset = 0x48;
27880 + return CC_PC_GENERIC_IC_GMASK;
27881 +
27882 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
27883 + *parseArrayOffset = 0x48;
27884 + return CC_PC_GENERIC_IC_HASH_INDEXED;
27885 +
27886 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
27887 + *parseArrayOffset = 0x16;
27888 + return CC_PC_GENERIC_IC_HASH_INDEXED;
27889 +
27890 + default:
27891 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
27892 + break;
27893 + }
27894 + }
27895 +
27896 + return CC_PC_ILLEGAL;
27897 +}
27898 +
27899 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
27900 + t_FmPcdFields field)
27901 +{
27902 + switch (hdr)
27903 + {
27904 + case (HEADER_TYPE_NONE):
27905 + ASSERT_COND(FALSE);
27906 + return CC_PC_ILLEGAL;
27907 +
27908 + case (HEADER_TYPE_ETH):
27909 + switch (field.eth)
27910 + {
27911 + case (NET_HEADER_FIELD_ETH_DA):
27912 + return CC_PC_FF_MACDST;
27913 + case (NET_HEADER_FIELD_ETH_SA):
27914 + return CC_PC_FF_MACSRC;
27915 + case (NET_HEADER_FIELD_ETH_TYPE):
27916 + return CC_PC_FF_ETYPE;
27917 + default:
27918 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
27919 + return CC_PC_ILLEGAL;
27920 + }
27921 +
27922 + case (HEADER_TYPE_VLAN):
27923 + switch (field.vlan)
27924 + {
27925 + case (NET_HEADER_FIELD_VLAN_TCI):
27926 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27927 + || (index == e_FM_PCD_HDR_INDEX_1))
27928 + return CC_PC_FF_TCI1;
27929 + if (index == e_FM_PCD_HDR_INDEX_LAST)
27930 + return CC_PC_FF_TCI2;
27931 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
27932 + return CC_PC_ILLEGAL;
27933 + default:
27934 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
27935 + return CC_PC_ILLEGAL;
27936 + }
27937 +
27938 + case (HEADER_TYPE_MPLS):
27939 + switch (field.mpls)
27940 + {
27941 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27942 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27943 + || (index == e_FM_PCD_HDR_INDEX_1))
27944 + return CC_PC_FF_MPLS1;
27945 + if (index == e_FM_PCD_HDR_INDEX_LAST)
27946 + return CC_PC_FF_MPLS_LAST;
27947 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
27948 + return CC_PC_ILLEGAL;
27949 + default:
27950 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
27951 + return CC_PC_ILLEGAL;
27952 + }
27953 +
27954 + case (HEADER_TYPE_IPv4):
27955 + switch (field.ipv4)
27956 + {
27957 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27958 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27959 + || (index == e_FM_PCD_HDR_INDEX_1))
27960 + return CC_PC_FF_IPV4DST1;
27961 + if (index == e_FM_PCD_HDR_INDEX_2)
27962 + return CC_PC_FF_IPV4DST2;
27963 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
27964 + return CC_PC_ILLEGAL;
27965 + case (NET_HEADER_FIELD_IPv4_TOS):
27966 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27967 + || (index == e_FM_PCD_HDR_INDEX_1))
27968 + return CC_PC_FF_IPV4IPTOS_TC1;
27969 + if (index == e_FM_PCD_HDR_INDEX_2)
27970 + return CC_PC_FF_IPV4IPTOS_TC2;
27971 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
27972 + return CC_PC_ILLEGAL;
27973 + case (NET_HEADER_FIELD_IPv4_PROTO):
27974 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27975 + || (index == e_FM_PCD_HDR_INDEX_1))
27976 + return CC_PC_FF_IPV4PTYPE1;
27977 + if (index == e_FM_PCD_HDR_INDEX_2)
27978 + return CC_PC_FF_IPV4PTYPE2;
27979 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
27980 + return CC_PC_ILLEGAL;
27981 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27982 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27983 + || (index == e_FM_PCD_HDR_INDEX_1))
27984 + return CC_PC_FF_IPV4SRC1;
27985 + if (index == e_FM_PCD_HDR_INDEX_2)
27986 + return CC_PC_FF_IPV4SRC2;
27987 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
27988 + return CC_PC_ILLEGAL;
27989 + case (NET_HEADER_FIELD_IPv4_SRC_IP
27990 + | NET_HEADER_FIELD_IPv4_DST_IP):
27991 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
27992 + || (index == e_FM_PCD_HDR_INDEX_1))
27993 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
27994 + if (index == e_FM_PCD_HDR_INDEX_2)
27995 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
27996 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
27997 + return CC_PC_ILLEGAL;
27998 + case (NET_HEADER_FIELD_IPv4_TTL):
27999 + return CC_PC_FF_IPV4TTL;
28000 + default:
28001 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28002 + return CC_PC_ILLEGAL;
28003 + }
28004 +
28005 + case (HEADER_TYPE_IPv6):
28006 + switch (field.ipv6)
28007 + {
28008 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
28009 + | NET_HEADER_FIELD_IPv6_TC):
28010 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28011 + || (index == e_FM_PCD_HDR_INDEX_1))
28012 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
28013 + if (index == e_FM_PCD_HDR_INDEX_2)
28014 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
28015 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28016 + return CC_PC_ILLEGAL;
28017 +
28018 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
28019 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28020 + || (index == e_FM_PCD_HDR_INDEX_1))
28021 + return CC_PC_FF_IPV6PTYPE1;
28022 + if (index == e_FM_PCD_HDR_INDEX_2)
28023 + return CC_PC_FF_IPV6PTYPE2;
28024 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28025 + return CC_PC_FF_IPPID;
28026 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28027 + return CC_PC_ILLEGAL;
28028 +
28029 + case (NET_HEADER_FIELD_IPv6_DST_IP):
28030 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28031 + || (index == e_FM_PCD_HDR_INDEX_1))
28032 + return CC_PC_FF_IPV6DST1;
28033 + if (index == e_FM_PCD_HDR_INDEX_2)
28034 + return CC_PC_FF_IPV6DST2;
28035 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28036 + return CC_PC_ILLEGAL;
28037 +
28038 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
28039 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28040 + || (index == e_FM_PCD_HDR_INDEX_1))
28041 + return CC_PC_FF_IPV6SRC1;
28042 + if (index == e_FM_PCD_HDR_INDEX_2)
28043 + return CC_PC_FF_IPV6SRC2;
28044 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28045 + return CC_PC_ILLEGAL;
28046 +
28047 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
28048 + return CC_PC_FF_IPV6HOP_LIMIT;
28049 +
28050 + default:
28051 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28052 + return CC_PC_ILLEGAL;
28053 + }
28054 +
28055 + case (HEADER_TYPE_IP):
28056 + switch (field.ip)
28057 + {
28058 + case (NET_HEADER_FIELD_IP_DSCP):
28059 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28060 + || (index == e_FM_PCD_HDR_INDEX_1))
28061 + return CC_PC_FF_IPDSCP;
28062 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28063 + return CC_PC_ILLEGAL;
28064 +
28065 + case (NET_HEADER_FIELD_IP_PROTO):
28066 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28067 + return CC_PC_FF_IPPID;
28068 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28069 + return CC_PC_ILLEGAL;
28070 +
28071 + default:
28072 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28073 + return CC_PC_ILLEGAL;
28074 + }
28075 +
28076 + case (HEADER_TYPE_GRE):
28077 + switch (field.gre)
28078 + {
28079 + case (NET_HEADER_FIELD_GRE_TYPE):
28080 + return CC_PC_FF_GREPTYPE;
28081 +
28082 + default:
28083 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28084 + return CC_PC_ILLEGAL;
28085 + }
28086 +
28087 + case (HEADER_TYPE_MINENCAP):
28088 + switch (field.minencap)
28089 + {
28090 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28091 + return CC_PC_FF_MINENCAP_PTYPE;
28092 +
28093 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28094 + return CC_PC_FF_MINENCAP_IPDST;
28095 +
28096 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28097 + return CC_PC_FF_MINENCAP_IPSRC;
28098 +
28099 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28100 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28101 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
28102 +
28103 + default:
28104 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28105 + return CC_PC_ILLEGAL;
28106 + }
28107 +
28108 + case (HEADER_TYPE_TCP):
28109 + switch (field.tcp)
28110 + {
28111 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28112 + return CC_PC_FF_L4PSRC;
28113 +
28114 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28115 + return CC_PC_FF_L4PDST;
28116 +
28117 + case (NET_HEADER_FIELD_TCP_PORT_DST
28118 + | NET_HEADER_FIELD_TCP_PORT_SRC):
28119 + return CC_PC_FF_L4PSRC_L4PDST;
28120 +
28121 + default:
28122 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28123 + return CC_PC_ILLEGAL;
28124 + }
28125 +
28126 + case (HEADER_TYPE_PPPoE):
28127 + switch (field.pppoe)
28128 + {
28129 + case (NET_HEADER_FIELD_PPPoE_PID):
28130 + return CC_PC_FF_PPPPID;
28131 +
28132 + default:
28133 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28134 + return CC_PC_ILLEGAL;
28135 + }
28136 +
28137 + case (HEADER_TYPE_UDP):
28138 + switch (field.udp)
28139 + {
28140 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28141 + return CC_PC_FF_L4PSRC;
28142 +
28143 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28144 + return CC_PC_FF_L4PDST;
28145 +
28146 + case (NET_HEADER_FIELD_UDP_PORT_DST
28147 + | NET_HEADER_FIELD_UDP_PORT_SRC):
28148 + return CC_PC_FF_L4PSRC_L4PDST;
28149 +
28150 + default:
28151 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28152 + return CC_PC_ILLEGAL;
28153 + }
28154 +
28155 + default:
28156 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28157 + return CC_PC_ILLEGAL;
28158 + }
28159 +}
28160 +
28161 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
28162 + uint32_t offset, bool glblMask,
28163 + uint8_t *parseArrayOffset)
28164 +{
28165 + bool offsetRelevant = FALSE;
28166 +
28167 + if (offset)
28168 + offsetRelevant = TRUE;
28169 +
28170 + switch (hdr)
28171 + {
28172 + case (HEADER_TYPE_NONE):
28173 + ASSERT_COND(FALSE);
28174 + return CC_PC_ILLEGAL;
28175 +
28176 + case (HEADER_TYPE_ETH):
28177 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
28178 + break;
28179 +
28180 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
28181 + if (offset || glblMask)
28182 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
28183 + else
28184 + return CC_PC_PR_SHIM1;
28185 + break;
28186 +
28187 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
28188 + if (offset || glblMask)
28189 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
28190 + else
28191 + return CC_PC_PR_SHIM2;
28192 + break;
28193 +
28194 + case (HEADER_TYPE_LLC_SNAP):
28195 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
28196 + break;
28197 +
28198 + case (HEADER_TYPE_PPPoE):
28199 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
28200 + break;
28201 +
28202 + case (HEADER_TYPE_MPLS):
28203 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28204 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28205 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
28206 + else
28207 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28208 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
28209 + else
28210 + {
28211 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
28212 + return CC_PC_ILLEGAL;
28213 + }
28214 + break;
28215 +
28216 + case (HEADER_TYPE_IPv4):
28217 + case (HEADER_TYPE_IPv6):
28218 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28219 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28220 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
28221 + else
28222 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
28223 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
28224 + else
28225 + {
28226 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
28227 + return CC_PC_ILLEGAL;
28228 + }
28229 + break;
28230 +
28231 + case (HEADER_TYPE_MINENCAP):
28232 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
28233 + break;
28234 +
28235 + case (HEADER_TYPE_GRE):
28236 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
28237 + break;
28238 +
28239 + case (HEADER_TYPE_TCP):
28240 + case (HEADER_TYPE_UDP):
28241 + case (HEADER_TYPE_IPSEC_AH):
28242 + case (HEADER_TYPE_IPSEC_ESP):
28243 + case (HEADER_TYPE_DCCP):
28244 + case (HEADER_TYPE_SCTP):
28245 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
28246 + break;
28247 +
28248 + default:
28249 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
28250 + return CC_PC_ILLEGAL;
28251 + }
28252 +
28253 + if (offsetRelevant)
28254 + return CC_PR_OFFSET;
28255 + else
28256 + return CC_PR_WITHOUT_OFFSET;
28257 +}
28258 +
28259 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
28260 + uint32_t offset, uint8_t *parseArrayOffset,
28261 + e_FmPcdHdrIndex hdrIndex)
28262 +{
28263 + bool offsetRelevant = FALSE;
28264 +
28265 + if (offset)
28266 + offsetRelevant = TRUE;
28267 +
28268 + switch (hdr)
28269 + {
28270 + case (HEADER_TYPE_NONE):
28271 + ASSERT_COND(FALSE);
28272 + break;
28273 + case (HEADER_TYPE_ETH):
28274 + switch (field.eth)
28275 + {
28276 + case (NET_HEADER_FIELD_ETH_TYPE):
28277 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
28278 + break;
28279 +
28280 + default:
28281 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28282 + return CC_PC_ILLEGAL;
28283 + }
28284 + break;
28285 +
28286 + case (HEADER_TYPE_VLAN):
28287 + switch (field.vlan)
28288 + {
28289 + case (NET_HEADER_FIELD_VLAN_TCI):
28290 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28291 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28292 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
28293 + else
28294 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28295 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
28296 + break;
28297 +
28298 + default:
28299 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28300 + return CC_PC_ILLEGAL;
28301 + }
28302 + break;
28303 +
28304 + default:
28305 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
28306 + return CC_PC_ILLEGAL;
28307 + }
28308 +
28309 + if (offsetRelevant)
28310 + return CC_PR_OFFSET;
28311 + else
28312 + return CC_PR_WITHOUT_OFFSET;
28313 +}
28314 +
28315 +static void FillAdOfTypeResult(t_Handle h_Ad,
28316 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28317 + t_FmPcd *p_FmPcd,
28318 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
28319 +{
28320 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
28321 + t_Handle h_TmpAd;
28322 + uint32_t tmp = 0, tmpNia = 0;
28323 + uint16_t profileId;
28324 + t_Handle p_AdNewPtr = NULL;
28325 + t_Error err = E_OK;
28326 +
28327 + /* There are 3 cases handled in this routine of building a "result" type AD.
28328 + * Case 1: No Manip. The action descriptor is built within the match table.
28329 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28330 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28331 + * initialized and returned here.
28332 + * p_AdResult (within the match table) will be initialized after
28333 + * this routine returns and point to the existing AD.
28334 + * Case 3: Manip exists. The action descriptor is built within the match table.
28335 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
28336 + *
28337 + * If statistics were enabled and the statistics mode of this node requires
28338 + * a statistics Ad, it will be placed after the result Ad and before the
28339 + * manip Ad, if manip Ad exists here.
28340 + */
28341 +
28342 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28343 + * AD will be written into the match table itself (case (1))*/
28344 + p_AdNewPtr = p_AdResult;
28345 +
28346 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28347 + if (p_FmPcdCcStatsParams)
28348 + {
28349 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28350 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28351 +
28352 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
28353 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28354 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28355 + h_Ad = h_TmpAd;
28356 +
28357 + p_AdNewPtr = h_Ad;
28358 + p_AdResult = h_Ad;
28359 +
28360 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28361 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28362 + }
28363 +
28364 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
28365 + if (p_CcNextEngineParams->h_Manip)
28366 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
28367 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
28368 +
28369 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28370 + if (p_AdNewPtr)
28371 + {
28372 + /* case (1) and (2) */
28373 + switch (p_CcNextEngineParams->nextEngine)
28374 + {
28375 + case (e_FM_PCD_DONE):
28376 + if (p_CcNextEngineParams->params.enqueueParams.action
28377 + == e_FM_PCD_ENQ_FRAME)
28378 + {
28379 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
28380 + {
28381 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28382 + tmp |=
28383 + p_CcNextEngineParams->params.enqueueParams.newFqid;
28384 +#if (DPAA_VERSION >= 11)
28385 + tmp |=
28386 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
28387 + & FM_PCD_AD_RESULT_VSP_MASK)
28388 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28389 +#endif /* (DPAA_VERSION >= 11) */
28390 + }
28391 + else
28392 + {
28393 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28394 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28395 + }
28396 + }
28397 +
28398 + if (p_CcNextEngineParams->params.enqueueParams.action
28399 + == e_FM_PCD_DROP_FRAME)
28400 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
28401 + else
28402 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
28403 + break;
28404 +
28405 + case (e_FM_PCD_KG):
28406 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
28407 + {
28408 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28409 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
28410 +#if (DPAA_VERSION >= 11)
28411 + tmp |=
28412 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
28413 + & FM_PCD_AD_RESULT_VSP_MASK)
28414 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28415 +#endif /* (DPAA_VERSION >= 11) */
28416 + }
28417 + else
28418 + {
28419 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28420 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28421 + }
28422 + tmpNia = NIA_KG_DIRECT;
28423 + tmpNia |= NIA_ENG_KG;
28424 + tmpNia |= NIA_KG_CC_EN;
28425 + tmpNia |= FmPcdKgGetSchemeId(
28426 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
28427 + break;
28428 +
28429 + case (e_FM_PCD_PLCR):
28430 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
28431 + {
28432 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28433 +
28434 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28435 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
28436 + {
28437 + tmpNia |= NIA_PLCR_ABSOLUTE;
28438 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
28439 + (t_Handle)p_FmPcd,
28440 + e_FM_PCD_PLCR_SHARED,
28441 + NULL,
28442 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
28443 + &profileId);
28444 +
28445 + if (err != E_OK) {
28446 + REPORT_ERROR(MAJOR, err, NO_MSG);
28447 + return;
28448 + }
28449 +
28450 + }
28451 + else
28452 + profileId =
28453 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28454 +
28455 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
28456 +#if (DPAA_VERSION >= 11)
28457 + tmp |=
28458 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
28459 + & FM_PCD_AD_RESULT_VSP_MASK)
28460 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28461 +#endif /* (DPAA_VERSION >= 11) */
28462 + WRITE_UINT32(
28463 + p_AdResult->plcrProfile,
28464 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
28465 + }
28466 + else
28467 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28468 +
28469 + tmpNia |=
28470 + NIA_ENG_PLCR
28471 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28472 + break;
28473 +
28474 + default:
28475 + return;
28476 + }WRITE_UINT32(p_AdResult->fqid, tmp);
28477 +
28478 + if (p_CcNextEngineParams->h_Manip)
28479 + {
28480 + tmp = GET_UINT32(p_AdResult->plcrProfile);
28481 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
28482 + - (p_FmPcd->physicalMuramBase)) >> 4;
28483 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
28484 +
28485 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
28486 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
28487 + }
28488 +
28489 +#if (DPAA_VERSION >= 11)
28490 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
28491 +#endif /* (DPAA_VERSION >= 11) */
28492 + WRITE_UINT32(p_AdResult->nia, tmpNia);
28493 + }
28494 +}
28495 +
28496 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
28497 + t_Handle h_FmPort, t_Handle h_FmTree,
28498 + bool validate)
28499 +{
28500 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28501 +
28502 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28503 + p_CcTree->keyAndNextEngineParams,
28504 + p_CcTree->numOfEntries,
28505 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
28506 + h_FmTree, FALSE);
28507 +}
28508 +
28509 +
28510 +static void ReleaseNewNodeCommonPart(
28511 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28512 +{
28513 + if (p_AdditionalInfo->p_AdTableNew)
28514 + FM_MURAM_FreeMem(
28515 + FmPcdGetMuramHandle(
28516 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28517 + p_AdditionalInfo->p_AdTableNew);
28518 +
28519 + if (p_AdditionalInfo->p_KeysMatchTableNew)
28520 + FM_MURAM_FreeMem(
28521 + FmPcdGetMuramHandle(
28522 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28523 + p_AdditionalInfo->p_KeysMatchTableNew);
28524 +}
28525 +
28526 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
28527 + uint8_t *p_Mask)
28528 +{
28529 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
28530 +
28531 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
28532 + && !p_CcNode->lclMask)
28533 + {
28534 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
28535 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
28536 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
28537 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
28538 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
28539 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
28540 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
28541 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
28542 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
28543 + {
28544 + p_CcNode->glblMaskSize = 0;
28545 + p_CcNode->lclMask = TRUE;
28546 + }
28547 + else
28548 + {
28549 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
28550 + p_CcNode->glblMaskUpdated = TRUE;
28551 + p_CcNode->glblMaskSize = 4;
28552 + }
28553 + }
28554 + else
28555 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
28556 + {
28557 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
28558 + {
28559 + p_CcNode->lclMask = TRUE;
28560 + p_CcNode->glblMaskSize = 0;
28561 + }
28562 + }
28563 + else
28564 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
28565 + {
28566 + uint32_t tmpMask = 0xffffffff;
28567 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
28568 + {
28569 + p_CcNode->lclMask = TRUE;
28570 + p_CcNode->glblMaskSize = 0;
28571 + }
28572 + }
28573 + else
28574 + if (p_Mask)
28575 + {
28576 + p_CcNode->lclMask = TRUE;
28577 + p_CcNode->glblMaskSize = 0;
28578 + }
28579 +
28580 + /* In static mode (maxNumOfKeys > 0), local mask is supported
28581 + only is mask support was enabled at initialization */
28582 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
28583 + {
28584 + p_CcNode->lclMask = FALSE;
28585 + p_CcNode->glblMaskSize = prvGlblMaskSize;
28586 + return ERROR_CODE(E_NOT_SUPPORTED);
28587 + }
28588 +
28589 + return E_OK;
28590 +}
28591 +
28592 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
28593 +{
28594 + t_FmPcd *p_FmPcd;
28595 + t_Handle h_Ad;
28596 +
28597 + if (isTree)
28598 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28599 + else
28600 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28601 +
28602 + if ((isTree && p_FmPcd->p_CcShadow)
28603 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
28604 + {
28605 + /* The allocated shadow is divided as follows:
28606 + 0 . . . 16 . . .
28607 + ---------------------------------------------------
28608 + | Shadow | Shadow Keys | Shadow Next |
28609 + | Ad | Match Table | Engine Table |
28610 + | (16 bytes) | (maximal size) | (maximal size) |
28611 + ---------------------------------------------------
28612 + */
28613 + if (!p_FmPcd->p_CcShadow)
28614 + {
28615 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28616 + return NULL;
28617 + }
28618 +
28619 + h_Ad = p_FmPcd->p_CcShadow;
28620 + }
28621 + else
28622 + {
28623 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
28624 + FM_PCD_CC_AD_ENTRY_SIZE,
28625 + FM_PCD_CC_AD_TABLE_ALIGN);
28626 + if (!h_Ad)
28627 + {
28628 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
28629 + return NULL;
28630 + }
28631 + }
28632 +
28633 + return h_Ad;
28634 +}
28635 +
28636 +static t_Error BuildNewNodeCommonPart(
28637 + t_FmPcdCcNode *p_CcNode, int *size,
28638 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28639 +{
28640 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
28641 +
28642 + if (p_CcNode->lclMask)
28643 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
28644 + else
28645 + *size = p_CcNode->ccKeySizeAccExtraction;
28646 +
28647 + if (p_CcNode->maxNumOfKeys == 0)
28648 + {
28649 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
28650 + FmPcdGetMuramHandle(p_FmPcd),
28651 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28652 + * FM_PCD_CC_AD_ENTRY_SIZE),
28653 + FM_PCD_CC_AD_TABLE_ALIGN);
28654 + if (!p_AdditionalInfo->p_AdTableNew)
28655 + RETURN_ERROR(
28656 + MAJOR, E_NO_MEMORY,
28657 + ("MURAM allocation for CC node action descriptors table"));
28658 +
28659 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
28660 + FmPcdGetMuramHandle(p_FmPcd),
28661 + (uint32_t)(*size * sizeof(uint8_t)
28662 + * (p_AdditionalInfo->numOfKeys + 1)),
28663 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
28664 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
28665 + {
28666 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
28667 + p_AdditionalInfo->p_AdTableNew);
28668 + p_AdditionalInfo->p_AdTableNew = NULL;
28669 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28670 + ("MURAM allocation for CC node key match table"));
28671 + }
28672 +
28673 + MemSet8(
28674 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28675 + 0,
28676 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
28677 + * FM_PCD_CC_AD_ENTRY_SIZE));
28678 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28679 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
28680 + }
28681 + else
28682 + {
28683 + /* The allocated shadow is divided as follows:
28684 + 0 . . . 16 . . .
28685 + ---------------------------------------------------
28686 + | Shadow | Shadow Keys | Shadow Next |
28687 + | Ad | Match Table | Engine Table |
28688 + | (16 bytes) | (maximal size) | (maximal size) |
28689 + ---------------------------------------------------
28690 + */
28691 +
28692 + if (!p_FmPcd->p_CcShadow)
28693 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28694 +
28695 + p_AdditionalInfo->p_KeysMatchTableNew =
28696 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
28697 + p_AdditionalInfo->p_AdTableNew =
28698 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
28699 +
28700 + MemSet8(
28701 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
28702 + 0,
28703 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
28704 + * FM_PCD_CC_AD_ENTRY_SIZE));
28705 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
28706 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
28707 + }
28708 +
28709 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
28710 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
28711 +
28712 + return E_OK;
28713 +}
28714 +
28715 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
28716 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
28717 + t_FmPcdCcKeyParams *p_KeyParams,
28718 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
28719 +{
28720 + t_Error err = E_OK;
28721 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
28722 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
28723 + int size;
28724 + int i = 0, j = 0;
28725 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
28726 + uint32_t requiredAction = 0;
28727 + bool prvLclMask;
28728 + t_CcNodeInformation *p_CcNodeInformation;
28729 + t_FmPcdCcStatsParams statsParams = { 0 };
28730 + t_List *p_Pos;
28731 + t_FmPcdStatsObj *p_StatsObj;
28732 +
28733 + /* Check that new NIA is legal */
28734 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
28735 + p_CcNode->statisticsMode);
28736 + if (err)
28737 + RETURN_ERROR(MAJOR, err, NO_MSG);
28738 +
28739 + prvLclMask = p_CcNode->lclMask;
28740 +
28741 + /* Check that new key is not require update of localMask */
28742 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
28743 + p_KeyParams->p_Mask);
28744 + if (err)
28745 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28746 +
28747 + /* Update internal data structure with new next engine for the given index */
28748 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
28749 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
28750 +
28751 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
28752 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
28753 +
28754 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
28755 + == e_FM_PCD_CC)
28756 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
28757 + {
28758 + err =
28759 + AllocAndFillAdForContLookupManip(
28760 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
28761 + if (err)
28762 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28763 + }
28764 +
28765 + if (p_KeyParams->p_Mask)
28766 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
28767 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
28768 + else
28769 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
28770 + p_CcNode->userSizeOfExtraction);
28771 +
28772 + /* Update numOfKeys */
28773 + if (add)
28774 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
28775 + else
28776 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
28777 +
28778 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
28779 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
28780 + if (err)
28781 + RETURN_ERROR(MAJOR, err, NO_MSG);
28782 +
28783 + /* Check that manip is legal and what requiredAction is necessary for this manip */
28784 + if (p_KeyParams->ccNextEngineParams.h_Manip)
28785 + {
28786 + err = FmPcdManipCheckParamsForCcNextEngine(
28787 + &p_KeyParams->ccNextEngineParams, &requiredAction);
28788 + if (err)
28789 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28790 + }
28791 +
28792 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
28793 + requiredAction;
28794 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
28795 + UPDATE_CC_WITH_TREE;
28796 +
28797 + /* Update new Ad and new Key Table according to new requirement */
28798 + i = 0;
28799 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
28800 + {
28801 + p_AdTableNewTmp =
28802 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
28803 +
28804 + if (j == keyIndex)
28805 + {
28806 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
28807 + {
28808 + /* Allocate a statistics object that holds statistics AD and counters.
28809 + - For added key - New statistics AD and counters pointer need to be allocated
28810 + new statistics object. If statistics were enabled, we need to replace the
28811 + existing descriptor with a new descriptor with nullified counters.
28812 + */
28813 + p_StatsObj = GetStatsObj(p_CcNode);
28814 + ASSERT_COND(p_StatsObj);
28815 +
28816 + /* Store allocated statistics object */
28817 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
28818 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
28819 + p_StatsObj;
28820 +
28821 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
28822 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
28823 +#if (DPAA_VERSION >= 11)
28824 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
28825 +
28826 +#endif /* (DPAA_VERSION >= 11) */
28827 +
28828 + /* Building action descriptor for the received new key */
28829 + NextStepAd(p_AdTableNewTmp, &statsParams,
28830 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
28831 + }
28832 + else
28833 + {
28834 + /* Building action descriptor for the received new key */
28835 + NextStepAd(p_AdTableNewTmp, NULL,
28836 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
28837 + }
28838 +
28839 + /* Copy the received new key into keys match table */
28840 + p_KeysMatchTableNewTmp =
28841 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
28842 +
28843 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
28844 + p_CcNode->userSizeOfExtraction);
28845 +
28846 + /* Update mask for the received new key */
28847 + if (p_CcNode->lclMask)
28848 + {
28849 + if (p_KeyParams->p_Mask)
28850 + {
28851 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
28852 + p_CcNode->ccKeySizeAccExtraction),
28853 + p_KeyParams->p_Mask,
28854 + p_CcNode->userSizeOfExtraction);
28855 + }
28856 + else
28857 + if (p_CcNode->ccKeySizeAccExtraction > 4)
28858 + {
28859 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
28860 + p_CcNode->ccKeySizeAccExtraction),
28861 + 0xff, p_CcNode->userSizeOfExtraction);
28862 + }
28863 + else
28864 + {
28865 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
28866 + p_CcNode->ccKeySizeAccExtraction),
28867 + p_CcNode->p_GlblMask,
28868 + p_CcNode->userSizeOfExtraction);
28869 + }
28870 + }
28871 +
28872 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
28873 + if (!add)
28874 + i++;
28875 + }
28876 + else
28877 + {
28878 + /* Copy existing action descriptors to the newly allocated Ad table */
28879 + p_AdTableOldTmp =
28880 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
28881 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
28882 + FM_PCD_CC_AD_ENTRY_SIZE);
28883 +
28884 + /* Copy existing keys and their masks to the newly allocated keys match table */
28885 + p_KeysMatchTableNewTmp =
28886 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
28887 + p_KeysMatchTableOldTmp =
28888 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
28889 +
28890 + if (p_CcNode->lclMask)
28891 + {
28892 + if (prvLclMask)
28893 + {
28894 + MemCpy8(
28895 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
28896 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
28897 + p_CcNode->ccKeySizeAccExtraction);
28898 + }
28899 + else
28900 + {
28901 + p_KeysMatchTableOldTmp =
28902 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
28903 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
28904 +
28905 + if (p_CcNode->ccKeySizeAccExtraction > 4)
28906 + {
28907 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
28908 + p_CcNode->ccKeySizeAccExtraction),
28909 + 0xff, p_CcNode->userSizeOfExtraction);
28910 + }
28911 + else
28912 + {
28913 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
28914 + p_CcNode->ccKeySizeAccExtraction),
28915 + p_CcNode->p_GlblMask,
28916 + p_CcNode->userSizeOfExtraction);
28917 + }
28918 + }
28919 + }
28920 +
28921 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
28922 + p_CcNode->ccKeySizeAccExtraction);
28923 +
28924 + i++;
28925 + }
28926 + }
28927 +
28928 + /* Miss action descriptor */
28929 + p_AdTableNewTmp =
28930 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
28931 + p_AdTableOldTmp =
28932 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
28933 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
28934 +
28935 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
28936 + {
28937 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
28938 + {
28939 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
28940 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
28941 + /* Update the manipulation which has to be updated from parameters of the port */
28942 + /* It's has to be updated with restrictions defined in the function */
28943 + err =
28944 + SetRequiredAction(
28945 + p_CcNode->h_FmPcd,
28946 + p_CcNode->shadowAction
28947 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
28948 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
28949 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
28950 + 1, p_CcNodeInformation->h_CcNode);
28951 + if (err)
28952 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28953 +
28954 + err =
28955 + CcUpdateParam(
28956 + p_CcNode->h_FmPcd,
28957 + NULL,
28958 + NULL,
28959 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
28960 + 1,
28961 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
28962 + TRUE, p_CcNodeInformation->index,
28963 + p_CcNodeInformation->h_CcNode, TRUE);
28964 + if (err)
28965 + RETURN_ERROR(MAJOR, err, (NO_MSG));
28966 + }
28967 + }
28968 +
28969 + if (p_CcNode->lclMask)
28970 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
28971 +
28972 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
28973 + p_AdditionalInfo->h_NodeForAdd =
28974 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
28975 + if (p_KeyParams->ccNextEngineParams.h_Manip)
28976 + p_AdditionalInfo->h_ManipForAdd =
28977 + p_KeyParams->ccNextEngineParams.h_Manip;
28978 +
28979 +#if (DPAA_VERSION >= 11)
28980 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
28981 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
28982 + p_AdditionalInfo->h_FrmReplicForAdd =
28983 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
28984 +#endif /* (DPAA_VERSION >= 11) */
28985 +
28986 + if (!add)
28987 + {
28988 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
28989 + == e_FM_PCD_CC)
28990 + p_AdditionalInfo->h_NodeForRmv =
28991 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
28992 +
28993 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
28994 + p_AdditionalInfo->h_ManipForRmv =
28995 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
28996 +
28997 + /* If statistics were previously enabled, store the old statistics object to be released */
28998 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
28999 + {
29000 + p_AdditionalInfo->p_StatsObjForRmv =
29001 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29002 + }
29003 +
29004 +#if (DPAA_VERSION >= 11)
29005 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29006 + == e_FM_PCD_FR)
29007 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29008 + p_AdditionalInfo->h_FrmReplicForRmv =
29009 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29010 +#endif /* (DPAA_VERSION >= 11) */
29011 + }
29012 +
29013 + return E_OK;
29014 +}
29015 +
29016 +static t_Error BuildNewNodeRemoveKey(
29017 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29018 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29019 +{
29020 + int i = 0, j = 0;
29021 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29022 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29023 + int size;
29024 + t_Error err = E_OK;
29025 +
29026 + /*save new numOfKeys*/
29027 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
29028 +
29029 + /*function which allocates in the memory new KeyTbl, AdTbl*/
29030 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29031 + if (err)
29032 + RETURN_ERROR(MAJOR, err, NO_MSG);
29033 +
29034 + /*update new Ad and new Key Table according to new requirement*/
29035 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
29036 + {
29037 + if (j == keyIndex)
29038 + j++;
29039 +
29040 + if (j == p_CcNode->numOfKeys)
29041 + break;
29042 + p_AdTableNewTmp =
29043 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29044 + p_AdTableOldTmp =
29045 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29046 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29047 +
29048 + p_KeysMatchTableOldTmp =
29049 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
29050 + p_KeysMatchTableNewTmp =
29051 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
29052 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29053 + size * sizeof(uint8_t));
29054 + }
29055 +
29056 + p_AdTableNewTmp =
29057 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29058 + p_AdTableOldTmp =
29059 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29060 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29061 +
29062 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29063 + == e_FM_PCD_CC)
29064 + p_AdditionalInfo->h_NodeForRmv =
29065 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29066 +
29067 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29068 + p_AdditionalInfo->h_ManipForRmv =
29069 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29070 +
29071 + /* If statistics were previously enabled, store the old statistics object to be released */
29072 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29073 + {
29074 + p_AdditionalInfo->p_StatsObjForRmv =
29075 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29076 + }
29077 +
29078 +#if (DPAA_VERSION >= 11)
29079 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29080 + == e_FM_PCD_FR)
29081 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29082 + p_AdditionalInfo->h_FrmReplicForRmv =
29083 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29084 +#endif /* (DPAA_VERSION >= 11) */
29085 +
29086 + return E_OK;
29087 +}
29088 +
29089 +static t_Error BuildNewNodeModifyKey(
29090 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
29091 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29092 +{
29093 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
29094 + t_Error err = E_OK;
29095 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29096 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29097 + int size;
29098 + int i = 0, j = 0;
29099 + bool prvLclMask;
29100 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
29101 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
29102 +
29103 + prvLclMask = p_CcNode->lclMask;
29104 +
29105 + /* Check that new key is not require update of localMask */
29106 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
29107 + if (err)
29108 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29109 +
29110 + /* Update internal data structure with new next engine for the given index */
29111 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
29112 + p_CcNode->userSizeOfExtraction);
29113 +
29114 + if (p_Mask)
29115 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
29116 + p_CcNode->userSizeOfExtraction);
29117 + else
29118 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29119 + p_CcNode->userSizeOfExtraction);
29120 +
29121 + /*function which build in the memory new KeyTbl, AdTbl*/
29122 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29123 + if (err)
29124 + RETURN_ERROR(MAJOR, err, NO_MSG);
29125 +
29126 + /*fill the New AdTable and New KeyTable*/
29127 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
29128 + {
29129 + p_AdTableNewTmp =
29130 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29131 + p_AdTableOldTmp =
29132 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29133 +
29134 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29135 +
29136 + if (j == keyIndex)
29137 + {
29138 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29139 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29140 + {
29141 + /* As statistics were enabled, we need to update the existing
29142 + statistics descriptor with a new nullified counters. */
29143 + p_StatsObj = GetStatsObj(p_CcNode);
29144 + ASSERT_COND(p_StatsObj);
29145 +
29146 + SetStatsCounters(
29147 + p_AdTableNewTmp,
29148 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
29149 + - p_FmPcd->physicalMuramBase)));
29150 +
29151 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
29152 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
29153 +
29154 + /* As we need to replace only the counters, we build a new statistics
29155 + object that holds the old AD and the new counters - this will be the
29156 + currently used statistics object.
29157 + The newly allocated AD is not required and may be released back to
29158 + the available objects with the previous counters pointer. */
29159 + p_StatsObj->h_StatsAd =
29160 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29161 +
29162 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
29163 + tmpStatsObj.h_StatsAd;
29164 +
29165 + /* Store allocated statistics object */
29166 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29167 + p_StatsObj;
29168 +
29169 + /* As statistics were previously enabled, store the old statistics object to be released */
29170 + p_AdditionalInfo->p_StatsObjForRmv =
29171 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29172 + }
29173 +
29174 + p_KeysMatchTableNewTmp =
29175 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29176 +
29177 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
29178 + p_CcNode->userSizeOfExtraction);
29179 +
29180 + if (p_CcNode->lclMask)
29181 + {
29182 + if (p_Mask)
29183 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29184 + p_CcNode->ccKeySizeAccExtraction),
29185 + p_Mask, p_CcNode->userSizeOfExtraction);
29186 + else
29187 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29188 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29189 + p_CcNode->ccKeySizeAccExtraction),
29190 + 0xff, p_CcNode->userSizeOfExtraction);
29191 + else
29192 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29193 + p_CcNode->ccKeySizeAccExtraction),
29194 + p_CcNode->p_GlblMask,
29195 + p_CcNode->userSizeOfExtraction);
29196 + }
29197 + }
29198 + else
29199 + {
29200 + p_KeysMatchTableNewTmp =
29201 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29202 + p_KeysMatchTableOldTmp =
29203 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
29204 +
29205 + if (p_CcNode->lclMask)
29206 + {
29207 + if (prvLclMask)
29208 + MemCpy8(
29209 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29210 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29211 + p_CcNode->userSizeOfExtraction);
29212 + else
29213 + {
29214 + p_KeysMatchTableOldTmp =
29215 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29216 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29217 +
29218 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29219 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29220 + p_CcNode->ccKeySizeAccExtraction),
29221 + 0xff, p_CcNode->userSizeOfExtraction);
29222 + else
29223 + MemCpy8(
29224 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29225 + p_CcNode->p_GlblMask,
29226 + p_CcNode->userSizeOfExtraction);
29227 + }
29228 + }
29229 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29230 + p_CcNode->ccKeySizeAccExtraction);
29231 + }
29232 + }
29233 +
29234 + p_AdTableNewTmp =
29235 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29236 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
29237 +
29238 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29239 +
29240 + return E_OK;
29241 +}
29242 +
29243 +static t_Error BuildNewNodeModifyNextEngine(
29244 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29245 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
29246 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29247 +{
29248 + t_Error err = E_OK;
29249 + uint32_t requiredAction = 0;
29250 + t_List *p_Pos;
29251 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
29252 + t_Handle p_Ad;
29253 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
29254 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
29255 + t_FmPcdStatsObj *p_StatsObj;
29256 + t_FmPcdCcStatsParams statsParams = { 0 };
29257 +
29258 + ASSERT_COND(p_CcNextEngineParams);
29259 +
29260 + /* check that new NIA is legal */
29261 + if (!p_AdditionalInfo->tree)
29262 + err = ValidateNextEngineParams(
29263 + h_FmPcd, p_CcNextEngineParams,
29264 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
29265 + else
29266 + /* Statistics are not supported for CC root */
29267 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
29268 + e_FM_PCD_CC_STATS_MODE_NONE);
29269 + if (err)
29270 + RETURN_ERROR(MAJOR, err, NO_MSG);
29271 +
29272 + /* Update internal data structure for next engine per index (index - key) */
29273 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29274 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29275 +
29276 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29277 + if (p_CcNextEngineParams->h_Manip)
29278 + {
29279 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
29280 + &requiredAction);
29281 + if (err)
29282 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29283 + }
29284 +
29285 + if (!p_AdditionalInfo->tree)
29286 + {
29287 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29288 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
29289 + p_Ad = p_FmPcdCcNode1->h_AdTable;
29290 +
29291 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29292 + == e_FM_PCD_CC)
29293 + p_AdditionalInfo->h_NodeForRmv =
29294 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29295 +
29296 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29297 + p_AdditionalInfo->h_ManipForRmv =
29298 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29299 +
29300 +#if (DPAA_VERSION >= 11)
29301 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29302 + == e_FM_PCD_FR)
29303 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29304 + p_AdditionalInfo->h_FrmReplicForRmv =
29305 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29306 +#endif /* (DPAA_VERSION >= 11) */
29307 + }
29308 + else
29309 + {
29310 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29311 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
29312 +
29313 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29314 + == e_FM_PCD_CC)
29315 + p_AdditionalInfo->h_NodeForRmv =
29316 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29317 +
29318 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29319 + p_AdditionalInfo->h_ManipForRmv =
29320 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29321 +
29322 +#if (DPAA_VERSION >= 11)
29323 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29324 + == e_FM_PCD_FR)
29325 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29326 + p_AdditionalInfo->h_FrmReplicForRmv =
29327 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29328 +#endif /* (DPAA_VERSION >= 11) */
29329 + }
29330 +
29331 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29332 + && p_CcNextEngineParams->h_Manip)
29333 + {
29334 + err = AllocAndFillAdForContLookupManip(
29335 + p_CcNextEngineParams->params.ccParams.h_CcNode);
29336 + if (err)
29337 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29338 + }
29339 +
29340 + ASSERT_COND(p_Ad);
29341 +
29342 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29343 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
29344 +
29345 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
29346 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
29347 + only the actual Nia-Ad should be modified. */
29348 + if ((!p_AdditionalInfo->tree)
29349 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29350 + && (p_CcNextEngineParams->statisticsEn))
29351 + ccNodeInfo.h_CcNode =
29352 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29353 +
29354 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29355 +
29356 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29357 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
29358 + if (!p_Ad)
29359 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29360 + ("MURAM allocation for CC node action descriptor"));
29361 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29362 +
29363 + /* If statistics were not enabled before, but requested now - Allocate a statistics
29364 + object that holds statistics AD and counters. */
29365 + if ((!p_AdditionalInfo->tree)
29366 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29367 + && (p_CcNextEngineParams->statisticsEn))
29368 + {
29369 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
29370 + ASSERT_COND(p_StatsObj);
29371 +
29372 + /* Store allocated statistics object */
29373 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29374 + p_StatsObj;
29375 +
29376 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29377 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29378 +
29379 +#if (DPAA_VERSION >= 11)
29380 + statsParams.h_StatsFLRs =
29381 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
29382 +
29383 +#endif /* (DPAA_VERSION >= 11) */
29384 +
29385 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
29386 + }
29387 + else
29388 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
29389 +
29390 + ccNodeInfo.h_CcNode = p_Ad;
29391 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29392 +
29393 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29394 + requiredAction;
29395 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29396 + UPDATE_CC_WITH_TREE;
29397 +
29398 + if (!p_AdditionalInfo->tree)
29399 + {
29400 + ASSERT_COND(p_FmPcdCcNode1);
29401 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
29402 + {
29403 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
29404 + {
29405 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29406 +
29407 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29408 + /* Update the manipulation which has to be updated from parameters of the port
29409 + it's has to be updated with restrictions defined in the function */
29410 +
29411 + err =
29412 + SetRequiredAction(
29413 + p_FmPcdCcNode1->h_FmPcd,
29414 + p_FmPcdCcNode1->shadowAction
29415 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29416 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29417 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
29418 + if (err)
29419 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29420 +
29421 + err = CcUpdateParam(
29422 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
29423 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
29424 + p_Ad, TRUE, p_CcNodeInformation->index,
29425 + p_CcNodeInformation->h_CcNode, TRUE);
29426 + if (err)
29427 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29428 + }
29429 + }
29430 + }
29431 + else
29432 + {
29433 + ASSERT_COND(p_FmPcdCcTree);
29434 +
29435 + err =
29436 + SetRequiredAction(
29437 + h_FmPcd,
29438 + p_FmPcdCcTree->requiredAction
29439 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29440 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29441 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
29442 + if (err)
29443 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29444 +
29445 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
29446 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29447 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
29448 + if (err)
29449 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29450 + }
29451 +
29452 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29453 + p_AdditionalInfo->h_NodeForAdd =
29454 + p_CcNextEngineParams->params.ccParams.h_CcNode;
29455 + if (p_CcNextEngineParams->h_Manip)
29456 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
29457 +
29458 + /* If statistics were previously enabled, but now are disabled,
29459 + store the old statistics object to be released */
29460 + if ((!p_AdditionalInfo->tree)
29461 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29462 + && (!p_CcNextEngineParams->statisticsEn))
29463 + {
29464 + p_AdditionalInfo->p_StatsObjForRmv =
29465 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
29466 +
29467 +
29468 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
29469 + }
29470 +#if (DPAA_VERSION >= 11)
29471 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
29472 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
29473 + p_AdditionalInfo->h_FrmReplicForAdd =
29474 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
29475 +#endif /* (DPAA_VERSION >= 11) */
29476 +
29477 + return E_OK;
29478 +}
29479 +
29480 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
29481 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29482 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29483 +{
29484 + t_CcNodeInformation *p_CcNodeInformation;
29485 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
29486 + t_List *p_Pos;
29487 + int i = 0;
29488 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
29489 + t_CcNodeInformation ccNodeInfo;
29490 +
29491 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
29492 + {
29493 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29494 + p_NodePtrOnCurrentMdfNode =
29495 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
29496 +
29497 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
29498 +
29499 + /* Search in the previous node which exact index points on this current modified node for getting AD */
29500 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
29501 + {
29502 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29503 + == e_FM_PCD_CC)
29504 + {
29505 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29506 + == (t_Handle)p_CrntMdfNode)
29507 + {
29508 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29509 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
29510 + else
29511 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
29512 + p_AdTablePtOnCrntCurrentMdfNode =
29513 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
29514 + else
29515 + p_AdTablePtOnCrntCurrentMdfNode =
29516 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
29517 +
29518 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29519 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
29520 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29521 +
29522 + if (!(*p_NextEngineParams))
29523 + *p_NextEngineParams =
29524 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29525 + }
29526 + }
29527 + }
29528 +
29529 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
29530 + }
29531 +}
29532 +
29533 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
29534 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29535 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29536 +{
29537 + t_CcNodeInformation *p_CcNodeInformation;
29538 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
29539 + t_List *p_Pos;
29540 + int i = 0;
29541 + t_Handle p_AdTableTmp;
29542 + t_CcNodeInformation ccNodeInfo;
29543 +
29544 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
29545 + {
29546 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29547 + p_TreePtrOnCurrentMdfNode =
29548 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
29549 +
29550 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
29551 +
29552 + /*search in the trees which exact index points on this current modified node for getting AD */
29553 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
29554 + {
29555 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29556 + == e_FM_PCD_CC)
29557 + {
29558 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29559 + == (t_Handle)p_CrntMdfNode)
29560 + {
29561 + p_AdTableTmp =
29562 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
29563 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29564 + ccNodeInfo.h_CcNode = p_AdTableTmp;
29565 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29566 +
29567 + if (!(*p_NextEngineParams))
29568 + *p_NextEngineParams =
29569 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29570 + }
29571 + }
29572 + }
29573 +
29574 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
29575 + }
29576 +}
29577 +
29578 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
29579 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29580 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
29581 +{
29582 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
29583 + int i = 0, j = 0;
29584 + bool wasUpdate = FALSE;
29585 + t_FmPcdCcNode *p_CcNode = NULL;
29586 + t_FmPcdCcTree *p_FmPcdCcTree;
29587 + uint16_t numOfKeys;
29588 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
29589 +
29590 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
29591 +
29592 + if (!tree)
29593 + {
29594 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29595 + numOfKeys = p_CcNode->numOfKeys;
29596 +
29597 + /* node has to be pointed by another node or tree */
29598 +
29599 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29600 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
29601 + if (!p_KeyAndNextEngineParams)
29602 + {
29603 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29604 + return NULL;
29605 + }
29606 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
29607 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29608 +
29609 + if (ttlCheck)
29610 + {
29611 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
29612 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
29613 + {
29614 + XX_Free(p_KeyAndNextEngineParams);
29615 + 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"));
29616 + return NULL;
29617 + }
29618 + }
29619 +
29620 + if (hashCheck)
29621 + {
29622 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
29623 + {
29624 + XX_Free(p_KeyAndNextEngineParams);
29625 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
29626 + return NULL;
29627 + }
29628 + }
29629 + }
29630 + else
29631 + {
29632 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29633 + numOfKeys = p_FmPcdCcTree->numOfEntries;
29634 +
29635 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29636 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
29637 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
29638 + if (!p_KeyAndNextEngineParams)
29639 + {
29640 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29641 + return NULL;
29642 + }
29643 + memcpy(p_KeyAndNextEngineParams,
29644 + p_FmPcdCcTree->keyAndNextEngineParams,
29645 + FM_PCD_MAX_NUM_OF_CC_GROUPS
29646 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29647 + }
29648 +
29649 + p_FmPcdModifyCcKeyAdditionalParams =
29650 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
29651 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29652 + if (!p_FmPcdModifyCcKeyAdditionalParams)
29653 + {
29654 + XX_Free(p_KeyAndNextEngineParams);
29655 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
29656 + return NULL;
29657 + }
29658 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
29659 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
29660 +
29661 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
29662 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
29663 +
29664 + while (i < numOfKeys)
29665 + {
29666 + if ((j == keyIndex) && !wasUpdate)
29667 + {
29668 + if (modifyState == e_MODIFY_STATE_ADD)
29669 + j++;
29670 + else
29671 + if (modifyState == e_MODIFY_STATE_REMOVE)
29672 + i++;
29673 + wasUpdate = TRUE;
29674 + }
29675 + else
29676 + {
29677 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29678 + p_KeyAndNextEngineParams + i,
29679 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29680 + i++;
29681 + j++;
29682 + }
29683 + }
29684 +
29685 + if (keyIndex == numOfKeys)
29686 + {
29687 + if (modifyState == e_MODIFY_STATE_ADD)
29688 + j++;
29689 + }
29690 +
29691 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
29692 + p_KeyAndNextEngineParams + numOfKeys,
29693 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
29694 +
29695 + XX_Free(p_KeyAndNextEngineParams);
29696 +
29697 + return p_FmPcdModifyCcKeyAdditionalParams;
29698 +}
29699 +
29700 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
29701 + t_FmPcdCcNode *p_CcNode,
29702 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
29703 + t_List *h_OldLst, t_List *h_NewLst)
29704 +{
29705 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
29706 + t_CcNodeInformation ccNodeInfo = { 0 };
29707 + t_Handle h_NewAd;
29708 + t_Handle h_OrigAd = NULL;
29709 +
29710 + /* Building a list of all action descriptors that point to the previous node */
29711 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
29712 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29713 + &p_NextEngineParams);
29714 +
29715 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
29716 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
29717 + &p_NextEngineParams);
29718 +
29719 + /* This node must be found as next engine of one of its previous nodes or trees*/
29720 + if (p_NextEngineParams)
29721 + {
29722 + /* Building a new action descriptor that points to the modified node */
29723 + h_NewAd = GetNewAd(p_CcNode, FALSE);
29724 + if (!h_NewAd)
29725 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
29726 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29727 +
29728 + h_OrigAd = p_CcNode->h_Ad;
29729 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
29730 + p_NextEngineParams);
29731 +
29732 + ccNodeInfo.h_CcNode = h_NewAd;
29733 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29734 +
29735 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
29736 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
29737 + }
29738 + return E_OK;
29739 +}
29740 +
29741 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
29742 +{
29743 + ASSERT_COND(p_FmPcdCcTree);
29744 +
29745 + /* this routine must be protected by the calling routine! */
29746 +
29747 + if (add)
29748 + p_FmPcdCcTree->owners++;
29749 + else
29750 + {
29751 + ASSERT_COND(p_FmPcdCcTree->owners);
29752 + p_FmPcdCcTree->owners--;
29753 + }
29754 +}
29755 +
29756 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
29757 +{
29758 + t_Error err = E_OK;
29759 + int i = 0;
29760 +
29761 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29762 + {
29763 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29764 + {
29765 + err =
29766 + FmPcdManipCheckParamsWithCcNodeParams(
29767 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
29768 + (t_Handle)p_CcNode);
29769 + if (err)
29770 + return err;
29771 + }
29772 + }
29773 +
29774 + return err;
29775 +}
29776 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
29777 + t_FmPcdCcNodeParams *p_CcNodeParam,
29778 + uint32_t *p_NumOfRanges,
29779 + uint32_t *p_CountersArraySize)
29780 +{
29781 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
29782 + uint32_t i;
29783 +
29784 + UNUSED(p_CcNodeParam);
29785 +
29786 + switch (statisticsMode)
29787 + {
29788 + case e_FM_PCD_CC_STATS_MODE_NONE:
29789 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29790 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
29791 + RETURN_ERROR(
29792 + MAJOR,
29793 + E_INVALID_VALUE,
29794 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
29795 + return E_OK;
29796 +
29797 + case e_FM_PCD_CC_STATS_MODE_FRAME:
29798 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
29799 + *p_NumOfRanges = 1;
29800 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29801 + return E_OK;
29802 +
29803 +#if (DPAA_VERSION >= 11)
29804 + case e_FM_PCD_CC_STATS_MODE_RMON:
29805 + {
29806 + uint16_t *p_FrameLengthRanges =
29807 + p_CcNodeParam->keysParams.frameLengthRanges;
29808 + uint32_t i;
29809 +
29810 + if (p_FrameLengthRanges[0] <= 0)
29811 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
29812 +
29813 + if (p_FrameLengthRanges[0] == 0xFFFF)
29814 + {
29815 + *p_NumOfRanges = 1;
29816 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
29817 + return E_OK;
29818 + }
29819 +
29820 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
29821 + {
29822 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
29823 + RETURN_ERROR(
29824 + MAJOR,
29825 + E_INVALID_VALUE,
29826 + ("Frame length range must be larger at least by 1 from preceding range"));
29827 +
29828 + /* Stop when last range is reached */
29829 + if (p_FrameLengthRanges[i] == 0xFFFF)
29830 + break;
29831 + }
29832 +
29833 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
29834 + || (p_FrameLengthRanges[i] != 0xFFFF))
29835 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
29836 + ("Last Frame length range must be 0xFFFF"));
29837 +
29838 + *p_NumOfRanges = i + 1;
29839 +
29840 + /* Allocate an extra counter for byte count, as counters
29841 + array always begins with byte count */
29842 + *p_CountersArraySize = (*p_NumOfRanges + 1)
29843 + * FM_PCD_CC_STATS_COUNTER_SIZE;
29844 +
29845 + }
29846 + return E_OK;
29847 +#endif /* (DPAA_VERSION >= 11) */
29848 +
29849 + default:
29850 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
29851 + }
29852 +}
29853 +
29854 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
29855 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
29856 +{
29857 + int tmp = 0;
29858 + t_FmPcdCcKeyParams *p_KeyParams;
29859 + t_Error err;
29860 + uint32_t requiredAction = 0;
29861 +
29862 + /* Validate statistics parameters */
29863 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
29864 + &(p_CcNode->numOfStatsFLRs),
29865 + &(p_CcNode->countersArraySize));
29866 + if (err)
29867 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
29868 +
29869 + /* Validate next engine parameters on Miss */
29870 + err = ValidateNextEngineParams(
29871 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
29872 + p_CcNode->statisticsMode);
29873 + if (err)
29874 + RETURN_ERROR(MAJOR, err,
29875 + ("For this node MissNextEngineParams are not valid"));
29876 +
29877 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
29878 + {
29879 + err = FmPcdManipCheckParamsForCcNextEngine(
29880 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
29881 + &requiredAction);
29882 + if (err)
29883 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29884 + }
29885 +
29886 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
29887 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
29888 + sizeof(t_FmPcdCcNextEngineParams));
29889 +
29890 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
29891 + requiredAction;
29892 +
29893 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
29894 + == e_FM_PCD_CC)
29895 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
29896 + {
29897 + err =
29898 + AllocAndFillAdForContLookupManip(
29899 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
29900 + if (err)
29901 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29902 + }
29903 +
29904 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
29905 + {
29906 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
29907 +
29908 + if (!p_KeyParams->p_Key)
29909 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
29910 +
29911 + err = ValidateNextEngineParams(h_FmPcd,
29912 + &p_KeyParams->ccNextEngineParams,
29913 + p_CcNode->statisticsMode);
29914 + if (err)
29915 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29916 +
29917 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
29918 + p_KeyParams->p_Mask);
29919 + if (err)
29920 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29921 +
29922 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29923 + {
29924 + err = FmPcdManipCheckParamsForCcNextEngine(
29925 + &p_KeyParams->ccNextEngineParams, &requiredAction);
29926 + if (err)
29927 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29928 + }
29929 +
29930 + /* Store 'key' parameters - key, mask (if passed by the user) */
29931 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
29932 + p_CcNodeParam->keysParams.keySize);
29933 +
29934 + if (p_KeyParams->p_Mask)
29935 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
29936 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
29937 + else
29938 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
29939 + p_CcNodeParam->keysParams.keySize);
29940 +
29941 + /* Store next engine parameters */
29942 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
29943 + &p_KeyParams->ccNextEngineParams,
29944 + sizeof(t_FmPcdCcNextEngineParams));
29945 +
29946 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
29947 +
29948 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
29949 + == e_FM_PCD_CC)
29950 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
29951 + {
29952 + err =
29953 + AllocAndFillAdForContLookupManip(
29954 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
29955 + if (err)
29956 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29957 + }
29958 + }
29959 +
29960 + if (p_CcNode->maxNumOfKeys)
29961 + {
29962 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
29963 + RETURN_ERROR(
29964 + MAJOR,
29965 + E_INVALID_VALUE,
29966 + ("Number of keys exceed the provided maximal number of keys"));
29967 + }
29968 +
29969 + *isKeyTblAlloc = TRUE;
29970 +
29971 + return E_OK;
29972 +}
29973 +
29974 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
29975 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
29976 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
29977 +{
29978 + int tmp = 0;
29979 + t_FmPcdCcKeyParams *p_KeyParams;
29980 + t_Error err;
29981 + uint8_t key = 0x01;
29982 + uint32_t requiredAction = 0;
29983 +
29984 + if (p_CcNode->numOfKeys != 1)
29985 + RETURN_ERROR(
29986 + MAJOR,
29987 + E_INVALID_VALUE,
29988 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
29989 +
29990 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
29991 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
29992 + RETURN_ERROR(
29993 + MAJOR,
29994 + E_INVALID_VALUE,
29995 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
29996 +
29997 + /* Validate statistics parameters */
29998 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
29999 + &(p_CcNode->numOfStatsFLRs),
30000 + &(p_CcNode->countersArraySize));
30001 + if (err)
30002 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30003 +
30004 + err = ValidateNextEngineParams(
30005 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30006 + p_CcNodeParam->keysParams.statisticsMode);
30007 + if (err)
30008 + RETURN_ERROR(MAJOR, err,
30009 + ("For this node MissNextEngineParams are not valid"));
30010 +
30011 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30012 + {
30013 + err = FmPcdManipCheckParamsForCcNextEngine(
30014 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30015 + &requiredAction);
30016 + if (err)
30017 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30018 + }
30019 +
30020 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30021 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30022 + sizeof(t_FmPcdCcNextEngineParams));
30023 +
30024 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30025 + requiredAction;
30026 +
30027 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30028 + == e_FM_PCD_CC)
30029 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30030 + {
30031 + err =
30032 + AllocAndFillAdForContLookupManip(
30033 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30034 + if (err)
30035 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30036 + }
30037 +
30038 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30039 + {
30040 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30041 +
30042 + if (p_KeyParams->p_Mask)
30043 + RETURN_ERROR(
30044 + MAJOR,
30045 + E_INVALID_VALUE,
30046 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
30047 +
30048 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
30049 + RETURN_ERROR(
30050 + MAJOR,
30051 + E_INVALID_VALUE,
30052 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
30053 +
30054 + err = ValidateNextEngineParams(h_FmPcd,
30055 + &p_KeyParams->ccNextEngineParams,
30056 + p_CcNode->statisticsMode);
30057 + if (err)
30058 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30059 +
30060 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30061 + {
30062 + err = FmPcdManipCheckParamsForCcNextEngine(
30063 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30064 + if (err)
30065 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30066 + }
30067 +
30068 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
30069 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
30070 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
30071 +
30072 + /* Store NextEngine parameters */
30073 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30074 + &p_KeyParams->ccNextEngineParams,
30075 + sizeof(t_FmPcdCcNextEngineParams));
30076 +
30077 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30078 + == e_FM_PCD_CC)
30079 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30080 + {
30081 + err =
30082 + AllocAndFillAdForContLookupManip(
30083 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30084 + if (err)
30085 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30086 + }
30087 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30088 + }
30089 +
30090 + *isKeyTblAlloc = FALSE;
30091 +
30092 + return E_OK;
30093 +}
30094 +
30095 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
30096 + t_FmPcdCcNodeParams *p_CcNodeParam,
30097 + t_FmPcdCcNode *p_CcNode,
30098 + bool *isKeyTblAlloc)
30099 +{
30100 + int tmp = 0, countOnes = 0;
30101 + t_FmPcdCcKeyParams *p_KeyParams;
30102 + t_Error err;
30103 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
30104 + uint16_t countMask = (uint16_t)(glblMask >> 4);
30105 + uint32_t requiredAction = 0;
30106 +
30107 + if (glblMask & 0x000f)
30108 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30109 + ("icIndxMask has to be with last nibble 0"));
30110 +
30111 + while (countMask)
30112 + {
30113 + countOnes++;
30114 + countMask = (uint16_t)(countMask >> 1);
30115 + }
30116 +
30117 + if (!POWER_OF_2(p_CcNode->numOfKeys))
30118 + RETURN_ERROR(
30119 + MAJOR,
30120 + E_INVALID_VALUE,
30121 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
30122 +
30123 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
30124 + RETURN_ERROR(
30125 + MAJOR,
30126 + E_INVALID_VALUE,
30127 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
30128 +
30129 + if (p_CcNodeParam->keysParams.maxNumOfKeys
30130 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
30131 + RETURN_ERROR(
30132 + MAJOR,
30133 + E_INVALID_VALUE,
30134 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
30135 +
30136 + /* Validate statistics parameters */
30137 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30138 + &(p_CcNode->numOfStatsFLRs),
30139 + &(p_CcNode->countersArraySize));
30140 + if (err)
30141 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30142 +
30143 + err = ValidateNextEngineParams(
30144 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30145 + p_CcNode->statisticsMode);
30146 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30147 + RETURN_ERROR(
30148 + MAJOR,
30149 + err,
30150 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
30151 +
30152 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30153 + {
30154 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30155 +
30156 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
30157 + RETURN_ERROR(
30158 + MAJOR,
30159 + E_INVALID_VALUE,
30160 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
30161 +
30162 + if ((glblMask & (tmp * 16)) == (tmp * 16))
30163 + {
30164 + err = ValidateNextEngineParams(h_FmPcd,
30165 + &p_KeyParams->ccNextEngineParams,
30166 + p_CcNode->statisticsMode);
30167 + if (err)
30168 + RETURN_ERROR(
30169 + MAJOR,
30170 + err,
30171 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
30172 +
30173 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30174 + {
30175 + err = FmPcdManipCheckParamsForCcNextEngine(
30176 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30177 + if (err)
30178 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30179 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
30180 + requiredAction;
30181 + }
30182 +
30183 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30184 + &p_KeyParams->ccNextEngineParams,
30185 + sizeof(t_FmPcdCcNextEngineParams));
30186 +
30187 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30188 + == e_FM_PCD_CC)
30189 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30190 + {
30191 + err =
30192 + AllocAndFillAdForContLookupManip(
30193 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30194 + if (err)
30195 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30196 + }
30197 + }
30198 + else
30199 + {
30200 + err = ValidateNextEngineParams(h_FmPcd,
30201 + &p_KeyParams->ccNextEngineParams,
30202 + p_CcNode->statisticsMode);
30203 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30204 + RETURN_ERROR(
30205 + MAJOR,
30206 + err,
30207 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
30208 + }
30209 + }
30210 +
30211 + *isKeyTblAlloc = FALSE;
30212 + cpu_to_be16s(&glblMask);
30213 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
30214 +
30215 + return E_OK;
30216 +}
30217 +
30218 +static t_Error ModifyNextEngineParamNode(
30219 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
30220 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
30221 +{
30222 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
30223 + t_FmPcd *p_FmPcd;
30224 + t_List h_OldPointersLst, h_NewPointersLst;
30225 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
30226 + t_Error err = E_OK;
30227 +
30228 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
30229 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
30230 +
30231 + if (keyIndex >= p_CcNode->numOfKeys)
30232 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30233 + ("keyIndex > previously cleared last index + 1"));
30234 +
30235 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30236 +
30237 + INIT_LIST(&h_OldPointersLst);
30238 + INIT_LIST(&h_NewPointersLst);
30239 +
30240 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
30241 + e_MODIFY_STATE_CHANGE, FALSE,
30242 + FALSE, FALSE);
30243 + if (!p_ModifyKeyParams)
30244 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
30245 +
30246 + if (p_CcNode->maxNumOfKeys
30247 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
30248 + {
30249 + XX_Free(p_ModifyKeyParams);
30250 + return ERROR_CODE(E_BUSY);
30251 + }
30252 +
30253 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
30254 + p_FmPcdCcNextEngineParams,
30255 + &h_OldPointersLst, &h_NewPointersLst,
30256 + p_ModifyKeyParams);
30257 + if (err)
30258 + {
30259 + XX_Free(p_ModifyKeyParams);
30260 + if (p_CcNode->maxNumOfKeys)
30261 + RELEASE_LOCK(p_FmPcd->shadowLock);
30262 + RETURN_ERROR(MAJOR, err, NO_MSG);
30263 + }
30264 +
30265 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
30266 + p_ModifyKeyParams, FALSE);
30267 +
30268 + if (p_CcNode->maxNumOfKeys)
30269 + RELEASE_LOCK(p_FmPcd->shadowLock);
30270 +
30271 + ReleaseLst(&h_OldPointersLst);
30272 + ReleaseLst(&h_NewPointersLst);
30273 +
30274 + return err;
30275 +}
30276 +
30277 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
30278 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
30279 +{
30280 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
30281 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
30282 + uint16_t i;
30283 +
30284 + ASSERT_COND(p_Key);
30285 + ASSERT_COND(p_KeyIndex);
30286 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
30287 +
30288 + if (keySize != p_CcNode->userSizeOfExtraction)
30289 + RETURN_ERROR(
30290 + MINOR, E_INVALID_VALUE,
30291 + ("Key size doesn't match the extraction size of the node"));
30292 +
30293 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
30294 + if (!p_Mask)
30295 + memset(tmpMask, 0xFF, keySize);
30296 +
30297 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30298 + {
30299 + /* Comparing received key */
30300 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
30301 + == 0)
30302 + {
30303 + if (p_Mask)
30304 + {
30305 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
30306 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
30307 + keySize) == 0)
30308 + {
30309 + *p_KeyIndex = i;
30310 + return E_OK;
30311 + }
30312 + }
30313 + else
30314 + {
30315 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
30316 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
30317 + keySize) == 0)
30318 + {
30319 + *p_KeyIndex = i;
30320 + return E_OK;
30321 + }
30322 + }
30323 + }
30324 + }
30325 +
30326 + return ERROR_CODE(E_NOT_FOUND);
30327 +}
30328 +
30329 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
30330 + bool isKeyTblAlloc,
30331 + uint32_t *p_MatchTableSize,
30332 + uint32_t *p_AdTableSize)
30333 +{
30334 + uint32_t shadowSize;
30335 + t_Error err;
30336 +
30337 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
30338 + (if local mask support is requested) */
30339 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
30340 + * p_CcNode->maxNumOfKeys;
30341 +
30342 + if (p_CcNode->maskSupport)
30343 + *p_MatchTableSize *= 2;
30344 +
30345 + /* Calculate next action descriptors table, including one more entry for miss */
30346 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30347 + * FM_PCD_CC_AD_ENTRY_SIZE);
30348 +
30349 + /* Calculate maximal shadow size of this node.
30350 + All shadow structures will be used for runtime modifications host command. If
30351 + keys table was allocated for this node, the keys table and next engines table may
30352 + be modified in run time (entries added or removed), so shadow tables are requires.
30353 + Otherwise, the only supported runtime modification is a specific next engine update
30354 + and this requires shadow memory of a single AD */
30355 +
30356 + /* Shadow size should be enough to hold the following 3 structures:
30357 + * 1 - an action descriptor */
30358 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
30359 +
30360 + /* 2 - keys match table, if was allocated for the current node */
30361 + if (isKeyTblAlloc)
30362 + shadowSize += *p_MatchTableSize;
30363 +
30364 + /* 3 - next action descriptors table */
30365 + shadowSize += *p_AdTableSize;
30366 +
30367 + /* Update shadow to the calculated size */
30368 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
30369 + FM_PCD_CC_AD_TABLE_ALIGN);
30370 + if (err != E_OK)
30371 + {
30372 + DeleteNode(p_CcNode);
30373 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
30374 + }
30375 +
30376 + return E_OK;
30377 +}
30378 +
30379 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
30380 +{
30381 + t_FmPcdStatsObj *p_StatsObj;
30382 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
30383 + uint32_t i;
30384 +
30385 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
30386 + if (!h_FmMuram)
30387 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30388 +
30389 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
30390 + will be allocated to support runtime modifications */
30391 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
30392 + {
30393 + /* Allocate list object structure */
30394 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
30395 + if (!p_StatsObj)
30396 + {
30397 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30398 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
30399 + }
30400 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
30401 +
30402 + /* Allocate statistics AD from MURAM */
30403 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
30404 + FM_PCD_CC_AD_ENTRY_SIZE,
30405 + FM_PCD_CC_AD_TABLE_ALIGN);
30406 + if (!h_StatsAd)
30407 + {
30408 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30409 + XX_Free(p_StatsObj);
30410 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30411 + ("MURAM allocation for statistics ADs"));
30412 + }
30413 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30414 +
30415 + /* Allocate statistics counters from MURAM */
30416 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
30417 + h_FmMuram, p_CcNode->countersArraySize,
30418 + FM_PCD_CC_AD_TABLE_ALIGN);
30419 + if (!h_StatsCounters)
30420 + {
30421 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30422 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
30423 + XX_Free(p_StatsObj);
30424 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30425 + ("MURAM allocation for statistics counters"));
30426 + }
30427 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
30428 +
30429 + p_StatsObj->h_StatsAd = h_StatsAd;
30430 + p_StatsObj->h_StatsCounters = h_StatsCounters;
30431 +
30432 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
30433 + }
30434 +
30435 + return E_OK;
30436 +}
30437 +
30438 +static t_Error MatchTableGetKeyStatistics(
30439 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30440 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
30441 +{
30442 + uint32_t *p_StatsCounters, i;
30443 +
30444 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
30445 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30446 + ("Statistics were not enabled for this match table"));
30447 +
30448 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30449 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30450 + ("Statistics were not enabled for this key"));
30451 +
30452 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
30453 +
30454 + p_StatsCounters =
30455 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
30456 + ASSERT_COND(p_StatsCounters);
30457 +
30458 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
30459 +
30460 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
30461 + {
30462 + p_StatsCounters =
30463 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
30464 +
30465 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
30466 +
30467 +#if (DPAA_VERSION >= 11)
30468 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
30469 + GET_UINT32(*p_StatsCounters);
30470 +#endif /* (DPAA_VERSION >= 11) */
30471 + }
30472 +
30473 + return E_OK;
30474 +}
30475 +
30476 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
30477 + t_FmPcdCcNodeParams *p_CcNodeParam)
30478 +{
30479 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
30480 + t_FmPcdCcNode *p_FmPcdCcNextNode;
30481 + t_Error err = E_OK;
30482 + uint32_t tmp, keySize;
30483 + bool glblMask = FALSE;
30484 + t_FmPcdCcKeyParams *p_KeyParams;
30485 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
30486 +#if (DPAA_VERSION >= 11)
30487 + t_Handle h_StatsFLRs;
30488 +#endif /* (DPAA_VERSION >= 11) */
30489 + bool fullField = FALSE;
30490 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
30491 + bool isKeyTblAlloc, fromIc = FALSE;
30492 + uint32_t matchTableSize, adTableSize;
30493 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
30494 + t_FmPcdStatsObj *p_StatsObj;
30495 + t_FmPcdCcStatsParams statsParams = { 0 };
30496 + t_Handle h_Manip;
30497 +
30498 + ASSERT_COND(h_FmPcd);
30499 + ASSERT_COND(p_CcNode);
30500 + ASSERT_COND(p_CcNodeParam);
30501 +
30502 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
30503 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30504 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30505 +
30506 + p_CcNode->h_FmPcd = h_FmPcd;
30507 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
30508 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
30509 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
30510 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
30511 +
30512 + /* For backward compatibility - even if statistics mode is nullified,
30513 + we'll fix it to frame mode so we can support per-key request for
30514 + statistics using 'statisticsEn' in next engine parameters */
30515 + if (!p_CcNode->maxNumOfKeys
30516 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
30517 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
30518 +
30519 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
30520 + if (!h_FmMuram)
30521 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30522 +
30523 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
30524 + INIT_LIST(&p_CcNode->ccTreeIdLst);
30525 + INIT_LIST(&p_CcNode->ccTreesLst);
30526 + INIT_LIST(&p_CcNode->availableStatsLst);
30527 +
30528 + p_CcNode->h_Spinlock = XX_InitSpinlock();
30529 + if (!p_CcNode->h_Spinlock)
30530 + {
30531 + DeleteNode(p_CcNode);
30532 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
30533 + }
30534 +
30535 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
30536 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
30537 + == HEADER_TYPE_IPv4)
30538 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
30539 + == HEADER_TYPE_IPv6))
30540 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
30541 + == e_FM_PCD_EXTRACT_FULL_FIELD)
30542 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
30543 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
30544 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
30545 + == NET_HEADER_FIELD_IPv4_TTL)))
30546 + {
30547 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30548 + &isKeyTblAlloc);
30549 + glblMask = FALSE;
30550 + }
30551 + else
30552 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
30553 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30554 + == e_FM_PCD_EXTRACT_FROM_KEY)
30555 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30556 + == e_FM_PCD_EXTRACT_FROM_HASH)
30557 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30558 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
30559 + {
30560 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30561 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
30562 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
30563 + {
30564 + DeleteNode(p_CcNode);
30565 + RETURN_ERROR(
30566 + MAJOR,
30567 + E_INVALID_VALUE,
30568 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
30569 + }
30570 +
30571 + icCode = IcDefineCode(p_CcNodeParam);
30572 + fromIc = TRUE;
30573 + if (icCode == CC_PRIVATE_INFO_NONE)
30574 + {
30575 + DeleteNode(p_CcNode);
30576 + RETURN_ERROR(
30577 + MAJOR,
30578 + E_INVALID_STATE,
30579 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
30580 + }
30581 +
30582 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
30583 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
30584 + {
30585 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30586 + &isKeyTblAlloc);
30587 + glblMask = TRUE;
30588 + }
30589 + else
30590 + {
30591 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30592 + &isKeyTblAlloc);
30593 + if (p_CcNode->glblMaskSize)
30594 + glblMask = TRUE;
30595 + }
30596 + }
30597 + else
30598 + {
30599 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
30600 + if (p_CcNode->glblMaskSize)
30601 + glblMask = TRUE;
30602 + }
30603 +
30604 + if (err)
30605 + {
30606 + DeleteNode(p_CcNode);
30607 + RETURN_ERROR(MAJOR, err, NO_MSG);
30608 + }
30609 +
30610 + switch (p_CcNodeParam->extractCcParams.type)
30611 + {
30612 + case (e_FM_PCD_EXTRACT_BY_HDR):
30613 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
30614 + {
30615 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
30616 + p_CcNode->parseCode =
30617 + GetFullFieldParseCode(
30618 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30619 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30620 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
30621 + GetSizeHeaderField(
30622 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30623 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
30624 + &p_CcNode->sizeOfExtraction);
30625 + fullField = TRUE;
30626 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
30627 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30628 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30629 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30630 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30631 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30632 + && (p_CcNode->parseCode
30633 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30634 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30635 + && (p_CcNode->parseCode
30636 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
30637 + && glblMask)
30638 + {
30639 + glblMask = FALSE;
30640 + p_CcNode->glblMaskSize = 4;
30641 + p_CcNode->lclMask = TRUE;
30642 + }
30643 + break;
30644 +
30645 + case (e_FM_PCD_EXTRACT_FROM_HDR):
30646 + p_CcNode->sizeOfExtraction =
30647 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
30648 + p_CcNode->offset =
30649 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30650 + p_CcNode->userOffset =
30651 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
30652 + p_CcNode->parseCode =
30653 + GetPrParseCode(
30654 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30655 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30656 + p_CcNode->offset, glblMask,
30657 + &p_CcNode->prsArrayOffset);
30658 + break;
30659 +
30660 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
30661 + p_CcNode->offset =
30662 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30663 + p_CcNode->userOffset =
30664 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
30665 + p_CcNode->sizeOfExtraction =
30666 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
30667 + p_CcNode->parseCode =
30668 + GetFieldParseCode(
30669 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30670 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
30671 + p_CcNode->offset,
30672 + &p_CcNode->prsArrayOffset,
30673 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
30674 + break;
30675 +
30676 + default:
30677 + DeleteNode(p_CcNode);
30678 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30679 + }
30680 + break;
30681 +
30682 + case (e_FM_PCD_EXTRACT_NON_HDR):
30683 + /* get the field code for the generic extract */
30684 + p_CcNode->sizeOfExtraction =
30685 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
30686 + p_CcNode->offset =
30687 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30688 + p_CcNode->userOffset =
30689 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
30690 + p_CcNode->parseCode = GetGenParseCode(
30691 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
30692 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
30693 + fromIc, icCode);
30694 +
30695 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
30696 + {
30697 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
30698 + {
30699 + DeleteNode(p_CcNode);
30700 + RETURN_ERROR(
30701 + MAJOR,
30702 + E_INVALID_SELECTION,
30703 + ("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)"));
30704 + }
30705 + }
30706 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
30707 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
30708 + {
30709 + p_CcNode->offset += p_CcNode->prsArrayOffset;
30710 + p_CcNode->prsArrayOffset = 0;
30711 + }
30712 + break;
30713 +
30714 + default:
30715 + DeleteNode(p_CcNode);
30716 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
30717 + }
30718 +
30719 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
30720 + {
30721 + DeleteNode(p_CcNode);
30722 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
30723 + }
30724 +
30725 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
30726 + || !p_CcNode->sizeOfExtraction)
30727 + {
30728 + DeleteNode(p_CcNode);
30729 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30730 + ("sizeOfExatrction can not be greater than 56 and not 0"));
30731 + }
30732 +
30733 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
30734 + {
30735 + DeleteNode(p_CcNode);
30736 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30737 + ("keySize has to be equal to sizeOfExtraction"));
30738 + }
30739 +
30740 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
30741 +
30742 + if (!glblMask)
30743 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30744 +
30745 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
30746 + if (err != E_OK)
30747 + {
30748 + DeleteNode(p_CcNode);
30749 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30750 + ("keySize has to be equal to sizeOfExtraction"));
30751 + }
30752 +
30753 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
30754 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
30755 + &p_CcNode->ccKeySizeAccExtraction);
30756 +
30757 + /* If local mask is used, it is stored next to each key in the keys match table */
30758 + if (p_CcNode->lclMask)
30759 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
30760 + else
30761 + keySize = p_CcNode->ccKeySizeAccExtraction;
30762 +
30763 + /* Update CC shadow with maximal size required by this node */
30764 + if (p_CcNode->maxNumOfKeys)
30765 + {
30766 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
30767 + &adTableSize);
30768 + if (err != E_OK)
30769 + {
30770 + DeleteNode(p_CcNode);
30771 + RETURN_ERROR(MAJOR, err, NO_MSG);
30772 + }
30773 +
30774 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
30775 +
30776 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
30777 + {
30778 + err = AllocStatsObjs(p_CcNode);
30779 + if (err != E_OK)
30780 + {
30781 + DeleteNode(p_CcNode);
30782 + RETURN_ERROR(MAJOR, err, NO_MSG);
30783 + }
30784 + }
30785 +
30786 + /* If manipulation will be initialized before this node, it will use the table
30787 + descriptor in the AD table of previous node and this node will need an extra
30788 + AD as his table descriptor. */
30789 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
30790 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
30791 + if (!p_CcNode->h_TmpAd)
30792 + {
30793 + DeleteNode(p_CcNode);
30794 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30795 + ("MURAM allocation for CC action descriptor"));
30796 + }
30797 + }
30798 + else
30799 + {
30800 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
30801 + * (p_CcNode->numOfKeys + 1));
30802 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
30803 + * (p_CcNode->numOfKeys + 1));
30804 + }
30805 +
30806 +#if (DPAA_VERSION >= 11)
30807 + switch (p_CcNode->statisticsMode)
30808 + {
30809 +
30810 + case e_FM_PCD_CC_STATS_MODE_RMON:
30811 + /* If RMON statistics or RMON conditional statistics modes are requested,
30812 + allocate frame length ranges array */
30813 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
30814 + h_FmMuram,
30815 + (uint32_t)(p_CcNode->numOfStatsFLRs)
30816 + * FM_PCD_CC_STATS_FLR_SIZE,
30817 + FM_PCD_CC_AD_TABLE_ALIGN);
30818 +
30819 + if (!p_CcNode->h_StatsFLRs)
30820 + {
30821 + DeleteNode(p_CcNode);
30822 + RETURN_ERROR(
30823 + MAJOR, E_NO_MEMORY,
30824 + ("MURAM allocation for CC frame length ranges array"));
30825 + }
30826 +
30827 + /* Initialize using value received from the user */
30828 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
30829 + {
30830 + uint16_t flr =
30831 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
30832 +
30833 + h_StatsFLRs =
30834 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
30835 +
30836 + MemCpy8(h_StatsFLRs,
30837 + &flr,
30838 + FM_PCD_CC_STATS_FLR_SIZE);
30839 + }
30840 + break;
30841 +
30842 + default:
30843 + break;
30844 + }
30845 +#endif /* (DPAA_VERSION >= 11) */
30846 +
30847 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
30848 + identification, IPv6 hop count identification, etc. */
30849 + if (isKeyTblAlloc)
30850 + {
30851 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
30852 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
30853 + if (!p_CcNode->h_KeysMatchTable)
30854 + {
30855 + DeleteNode(p_CcNode);
30856 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30857 + ("MURAM allocation for CC node key match table"));
30858 + }
30859 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
30860 + }
30861 +
30862 + /* Allocate action descriptors table */
30863 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
30864 + FM_PCD_CC_AD_TABLE_ALIGN);
30865 + if (!p_CcNode->h_AdTable)
30866 + {
30867 + DeleteNode(p_CcNode);
30868 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30869 + ("MURAM allocation for CC node action descriptors table"));
30870 + }
30871 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
30872 +
30873 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
30874 + p_AdTableTmp = p_CcNode->h_AdTable;
30875 +
30876 + /* For each key, create the key and the next step AD */
30877 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30878 + {
30879 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30880 +
30881 + if (p_KeysMatchTblTmp)
30882 + {
30883 + /* Copy the key */
30884 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
30885 + p_CcNode->sizeOfExtraction);
30886 +
30887 + /* Copy the key mask or initialize it to 0xFF..F */
30888 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
30889 + {
30890 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
30891 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
30892 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
30893 + }
30894 + else
30895 + if (p_CcNode->lclMask)
30896 + {
30897 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
30898 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
30899 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
30900 + }
30901 +
30902 + p_KeysMatchTblTmp =
30903 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
30904 + }
30905 +
30906 + /* Create the next action descriptor in the match table */
30907 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
30908 + {
30909 + p_StatsObj = GetStatsObj(p_CcNode);
30910 + ASSERT_COND(p_StatsObj);
30911 +
30912 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
30913 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
30914 +#if (DPAA_VERSION >= 11)
30915 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
30916 +
30917 +#endif /* (DPAA_VERSION >= 11) */
30918 + NextStepAd(p_AdTableTmp, &statsParams,
30919 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
30920 +
30921 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
30922 + }
30923 + else
30924 + {
30925 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
30926 + p_FmPcd);
30927 +
30928 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
30929 + }
30930 +
30931 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30932 + }
30933 +
30934 + /* Update next engine for the 'miss' entry */
30935 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
30936 + {
30937 + p_StatsObj = GetStatsObj(p_CcNode);
30938 + ASSERT_COND(p_StatsObj);
30939 +
30940 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
30941 + allocated by the hash table. So, if this node is a bucket of a hash table,
30942 + we'll replace the locally allocated counters with the shared counters. */
30943 + if (p_CcNode->isHashBucket)
30944 + {
30945 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
30946 +
30947 + /* Store original counters pointer and replace it with mutual preallocated pointer */
30948 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
30949 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
30950 + }
30951 +
30952 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
30953 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
30954 +#if (DPAA_VERSION >= 11)
30955 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
30956 +
30957 +#endif /* (DPAA_VERSION >= 11) */
30958 +
30959 + NextStepAd(p_AdTableTmp, &statsParams,
30960 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30961 + p_FmPcd);
30962 +
30963 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
30964 + }
30965 + else
30966 + {
30967 + NextStepAd(p_AdTableTmp, NULL,
30968 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30969 + p_FmPcd);
30970 +
30971 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
30972 + }
30973 +
30974 + /* This parameter will be used to initialize the "key length" field in the action descriptor
30975 + that points to this node and it should be 0 for full field extraction */
30976 + if (fullField == TRUE)
30977 + p_CcNode->sizeOfExtraction = 0;
30978 +
30979 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
30980 + {
30981 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30982 + == e_FM_PCD_CC)
30983 + {
30984 + p_FmPcdCcNextNode =
30985 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
30986 + p_CcInformation = FindNodeInfoInReleventLst(
30987 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
30988 + p_FmPcdCcNextNode->h_Spinlock);
30989 + if (!p_CcInformation)
30990 + {
30991 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
30992 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
30993 + ccNodeInfo.index = 1;
30994 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
30995 + &ccNodeInfo,
30996 + p_FmPcdCcNextNode->h_Spinlock);
30997 + }
30998 + else
30999 + p_CcInformation->index++;
31000 +
31001 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31002 + {
31003 + h_Manip =
31004 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
31005 + p_CcInformation = FindNodeInfoInReleventLst(
31006 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31007 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
31008 + if (!p_CcInformation)
31009 + {
31010 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31011 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31012 + ccNodeInfo.index = 1;
31013 + EnqueueNodeInfoToRelevantLst(
31014 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31015 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
31016 + }
31017 + else
31018 + p_CcInformation->index++;
31019 + }
31020 + }
31021 + }
31022 +
31023 + p_AdTableTmp = p_CcNode->h_AdTable;
31024 +
31025 + if (!FmPcdLockTryLockAll(h_FmPcd))
31026 + {
31027 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31028 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
31029 + return ERROR_CODE(E_BUSY);
31030 + }
31031 +
31032 + /* Required action for each next engine */
31033 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31034 + {
31035 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
31036 + {
31037 + err = SetRequiredAction(
31038 + h_FmPcd,
31039 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
31040 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
31041 + NULL);
31042 + if (err)
31043 + {
31044 + FmPcdLockUnlockAll(h_FmPcd);
31045 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31046 + RETURN_ERROR(MAJOR, err, NO_MSG);
31047 + }
31048 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31049 + }
31050 + }
31051 +
31052 + FmPcdLockUnlockAll(h_FmPcd);
31053 +
31054 + return E_OK;
31055 +}
31056 +/************************** End of static functions **************************/
31057 +
31058 +/*****************************************************************************/
31059 +/* Inter-module API routines */
31060 +/*****************************************************************************/
31061 +
31062 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
31063 + t_Handle h_Spinlock)
31064 +{
31065 + t_CcNodeInformation *p_CcInformation;
31066 + t_List *p_Pos;
31067 + uint32_t intFlags;
31068 +
31069 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31070 +
31071 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31072 + p_Pos = LIST_NEXT(p_Pos))
31073 + {
31074 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31075 +
31076 + ASSERT_COND(p_CcInformation->h_CcNode);
31077 +
31078 + if (p_CcInformation->h_CcNode == h_Info)
31079 + {
31080 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31081 + return p_CcInformation;
31082 + }
31083 + }
31084 +
31085 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31086 +
31087 + return NULL;
31088 +}
31089 +
31090 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
31091 + t_Handle h_Spinlock)
31092 +{
31093 + t_CcNodeInformation *p_CcInformation;
31094 + uint32_t intFlags = 0;
31095 +
31096 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
31097 + sizeof(t_CcNodeInformation));
31098 +
31099 + if (p_CcInformation)
31100 + {
31101 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
31102 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
31103 + INIT_LIST(&p_CcInformation->node);
31104 +
31105 + if (h_Spinlock)
31106 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31107 +
31108 + LIST_AddToTail(&p_CcInformation->node, p_List);
31109 +
31110 + if (h_Spinlock)
31111 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31112 + }
31113 + else
31114 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
31115 +}
31116 +
31117 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
31118 + t_Handle h_Spinlock)
31119 +{
31120 + t_CcNodeInformation *p_CcInformation = NULL;
31121 + uint32_t intFlags = 0;
31122 + t_List *p_Pos;
31123 +
31124 + if (h_Spinlock)
31125 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31126 +
31127 + if (LIST_IsEmpty(p_List))
31128 + {
31129 + XX_RestoreAllIntr(intFlags);
31130 + return;
31131 + }
31132 +
31133 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31134 + p_Pos = LIST_NEXT(p_Pos))
31135 + {
31136 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31137 + ASSERT_COND(p_CcInformation);
31138 + ASSERT_COND(p_CcInformation->h_CcNode);
31139 + if (p_CcInformation->h_CcNode == h_Info)
31140 + break;
31141 + }
31142 +
31143 + if (p_CcInformation)
31144 + {
31145 + LIST_DelAndInit(&p_CcInformation->node);
31146 + XX_Free(p_CcInformation);
31147 + }
31148 +
31149 + if (h_Spinlock)
31150 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31151 +}
31152 +
31153 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
31154 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
31155 + t_FmPcd *p_FmPcd)
31156 +{
31157 + switch (p_FmPcdCcNextEngineParams->nextEngine)
31158 + {
31159 + case (e_FM_PCD_KG):
31160 + case (e_FM_PCD_PLCR):
31161 + case (e_FM_PCD_DONE):
31162 + /* if NIA is not CC, create a "result" type AD */
31163 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31164 + p_FmPcdCcNextEngineParams);
31165 + break;
31166 +#if (DPAA_VERSION >= 11)
31167 + case (e_FM_PCD_FR):
31168 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
31169 + {
31170 + FillAdOfTypeContLookup(
31171 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31172 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31173 + p_FmPcdCcNextEngineParams->h_Manip,
31174 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
31175 + FrmReplicGroupUpdateOwner(
31176 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
31177 + TRUE/* add */);
31178 + }
31179 + break;
31180 +#endif /* (DPAA_VERSION >= 11) */
31181 +
31182 + case (e_FM_PCD_CC):
31183 + /* if NIA is not CC, create a TD to continue the CC lookup */
31184 + FillAdOfTypeContLookup(
31185 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31186 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31187 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
31188 +
31189 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31190 + TRUE);
31191 + break;
31192 +
31193 + default:
31194 + return;
31195 + }
31196 +}
31197 +
31198 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31199 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
31200 + bool createSchemes)
31201 +{
31202 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31203 + t_FmPcdCcNextEngineParams nextEngineParams;
31204 + t_NetEnvParams netEnvParams;
31205 + t_Handle h_Ad;
31206 + bool isIpv6Present;
31207 + uint8_t ipv4GroupId, ipv6GroupId;
31208 + t_Error err;
31209 +
31210 + ASSERT_COND(p_FmPcdCcTree);
31211 +
31212 + /* this routine must be protected by the calling routine! */
31213 +
31214 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31215 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31216 +
31217 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31218 +
31219 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
31220 +
31221 + if (isIpv6Present
31222 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
31223 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31224 +
31225 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31226 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31227 +
31228 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31229 + nextEngineParams.h_Manip = h_IpReassemblyManip;
31230 +
31231 + /* Lock tree */
31232 + err = CcRootTryLock(p_FmPcdCcTree);
31233 + if (err)
31234 + return ERROR_CODE(E_BUSY);
31235 +
31236 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
31237 + {
31238 + CcRootReleaseLock(p_FmPcdCcTree);
31239 + return E_OK;
31240 + }
31241 +
31242 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
31243 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
31244 + {
31245 + CcRootReleaseLock(p_FmPcdCcTree);
31246 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31247 + ("This tree was previously updated with different IPR"));
31248 + }
31249 +
31250 + /* Initialize IPR for the first time for this tree */
31251 + if (isIpv6Present)
31252 + {
31253 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
31254 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
31255 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
31256 +
31257 + if (createSchemes)
31258 + {
31259 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
31260 + p_FmPcdCcTree,
31261 + h_IpReassemblyManip, FALSE,
31262 + ipv6GroupId);
31263 + if (err)
31264 + {
31265 + p_FmPcdCcTree->numOfGrps--;
31266 + CcRootReleaseLock(p_FmPcdCcTree);
31267 + RETURN_ERROR(MAJOR, err, NO_MSG);
31268 + }
31269 + }
31270 +
31271 + NextStepAd(
31272 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
31273 + NULL, &nextEngineParams, h_FmPcd);
31274 + }
31275 +
31276 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
31277 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
31278 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
31279 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31280 +
31281 + if (createSchemes)
31282 + {
31283 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
31284 + h_IpReassemblyManip, TRUE,
31285 + ipv4GroupId);
31286 + if (err)
31287 + {
31288 + p_FmPcdCcTree->numOfGrps--;
31289 + if (isIpv6Present)
31290 + {
31291 + p_FmPcdCcTree->numOfGrps--;
31292 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
31293 + }
31294 + CcRootReleaseLock(p_FmPcdCcTree);
31295 + RETURN_ERROR(MAJOR, err, NO_MSG);
31296 + }
31297 + }
31298 +
31299 + NextStepAd(
31300 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31301 + NULL, &nextEngineParams, h_FmPcd);
31302 +
31303 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
31304 +
31305 + CcRootReleaseLock(p_FmPcdCcTree);
31306 +
31307 + return E_OK;
31308 +}
31309 +
31310 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31311 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
31312 + bool createSchemes)
31313 +{
31314 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31315 + t_FmPcdCcNextEngineParams nextEngineParams;
31316 + t_NetEnvParams netEnvParams;
31317 + t_Handle h_Ad;
31318 + uint8_t groupId;
31319 + t_Error err;
31320 +
31321 + ASSERT_COND(p_FmPcdCcTree);
31322 +
31323 + /* this routine must be protected by the calling routine! */
31324 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31325 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31326 +
31327 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31328 +
31329 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31330 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
31331 +
31332 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31333 + nextEngineParams.h_Manip = h_ReassemblyManip;
31334 +
31335 + /* Lock tree */
31336 + err = CcRootTryLock(p_FmPcdCcTree);
31337 + if (err)
31338 + return ERROR_CODE(E_BUSY);
31339 +
31340 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
31341 + {
31342 + CcRootReleaseLock(p_FmPcdCcTree);
31343 + return E_OK;
31344 + }
31345 +
31346 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
31347 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
31348 + {
31349 + CcRootReleaseLock(p_FmPcdCcTree);
31350 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31351 + ("This tree was previously updated with different CPR"));
31352 + }
31353 +
31354 + groupId = p_FmPcdCcTree->numOfGrps++;
31355 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
31356 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31357 +
31358 + if (createSchemes)
31359 + {
31360 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
31361 + p_FmPcdCcTree,
31362 + h_ReassemblyManip, groupId);
31363 + if (err)
31364 + {
31365 + p_FmPcdCcTree->numOfGrps--;
31366 + CcRootReleaseLock(p_FmPcdCcTree);
31367 + RETURN_ERROR(MAJOR, err, NO_MSG);
31368 + }
31369 + }
31370 +
31371 + NextStepAd(
31372 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31373 + NULL, &nextEngineParams, h_FmPcd);
31374 +
31375 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
31376 +
31377 + CcRootReleaseLock(p_FmPcdCcTree);
31378 +
31379 + return E_OK;
31380 +}
31381 +
31382 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
31383 +{
31384 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31385 +
31386 + ASSERT_COND(p_FmPcdCcTree);
31387 +
31388 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
31389 +}
31390 +
31391 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
31392 + t_Handle h_SavedManipParams)
31393 +{
31394 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31395 +
31396 + ASSERT_COND(p_FmPcdCcTree);
31397 +
31398 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
31399 +}
31400 +
31401 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
31402 +{
31403 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31404 +
31405 + ASSERT_COND(p_CcNode);
31406 +
31407 + return p_CcNode->parseCode;
31408 +}
31409 +
31410 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
31411 +{
31412 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31413 +
31414 + ASSERT_COND(p_CcNode);
31415 +
31416 + return p_CcNode->offset;
31417 +}
31418 +
31419 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
31420 +{
31421 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31422 +
31423 + ASSERT_COND(p_CcNode);
31424 +
31425 + return p_CcNode->numOfKeys;
31426 +}
31427 +
31428 +t_Error FmPcdCcModifyNextEngineParamTree(
31429 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
31430 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31431 +{
31432 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31433 + t_FmPcd *p_FmPcd;
31434 + t_List h_OldPointersLst, h_NewPointersLst;
31435 + uint16_t keyIndex;
31436 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31437 + t_Error err = E_OK;
31438 +
31439 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31440 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31441 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
31442 +
31443 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31444 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31445 + ("grpId you asked > numOfGroup of relevant tree"));
31446 +
31447 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
31448 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
31449 +
31450 + p_FmPcd = (t_FmPcd *)h_FmPcd;
31451 +
31452 + INIT_LIST(&h_OldPointersLst);
31453 + INIT_LIST(&h_NewPointersLst);
31454 +
31455 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
31456 + + index);
31457 +
31458 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
31459 + e_MODIFY_STATE_CHANGE, FALSE,
31460 + FALSE, TRUE);
31461 + if (!p_ModifyKeyParams)
31462 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31463 +
31464 + p_ModifyKeyParams->tree = TRUE;
31465 +
31466 + if (p_FmPcd->p_CcShadow
31467 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31468 + {
31469 + XX_Free(p_ModifyKeyParams);
31470 + return ERROR_CODE(E_BUSY);
31471 + }
31472 +
31473 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
31474 + p_FmPcdCcNextEngineParams,
31475 + &h_OldPointersLst, &h_NewPointersLst,
31476 + p_ModifyKeyParams);
31477 + if (err)
31478 + {
31479 + XX_Free(p_ModifyKeyParams);
31480 + RETURN_ERROR(MAJOR, err, NO_MSG);
31481 + }
31482 +
31483 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31484 + p_ModifyKeyParams, FALSE);
31485 +
31486 + if (p_FmPcd->p_CcShadow)
31487 + RELEASE_LOCK(p_FmPcd->shadowLock);
31488 +
31489 + ReleaseLst(&h_OldPointersLst);
31490 + ReleaseLst(&h_NewPointersLst);
31491 +
31492 + return err;
31493 +
31494 +}
31495 +
31496 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31497 + uint16_t keyIndex)
31498 +{
31499 +
31500 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31501 + t_FmPcd *p_FmPcd;
31502 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31503 + t_List h_OldPointersLst, h_NewPointersLst;
31504 + bool useShadowStructs = FALSE;
31505 + t_Error err = E_OK;
31506 +
31507 + if (keyIndex >= p_CcNode->numOfKeys)
31508 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31509 + ("impossible to remove key when numOfKeys <= keyIndex"));
31510 +
31511 + if (p_CcNode->h_FmPcd != h_FmPcd)
31512 + RETURN_ERROR(
31513 + MAJOR,
31514 + E_INVALID_VALUE,
31515 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31516 +
31517 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31518 +
31519 + INIT_LIST(&h_OldPointersLst);
31520 + INIT_LIST(&h_NewPointersLst);
31521 +
31522 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31523 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
31524 + FALSE);
31525 + if (!p_ModifyKeyParams)
31526 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31527 +
31528 + if (p_CcNode->maxNumOfKeys)
31529 + {
31530 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31531 + {
31532 + XX_Free(p_ModifyKeyParams);
31533 + return ERROR_CODE(E_BUSY);
31534 + }
31535 +
31536 + useShadowStructs = TRUE;
31537 + }
31538 +
31539 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
31540 + if (err)
31541 + {
31542 + XX_Free(p_ModifyKeyParams);
31543 + if (p_CcNode->maxNumOfKeys)
31544 + RELEASE_LOCK(p_FmPcd->shadowLock);
31545 + RETURN_ERROR(MAJOR, err, NO_MSG);
31546 + }
31547 +
31548 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31549 + &h_OldPointersLst,
31550 + &h_NewPointersLst);
31551 + if (err)
31552 + {
31553 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31554 + XX_Free(p_ModifyKeyParams);
31555 + if (p_CcNode->maxNumOfKeys)
31556 + RELEASE_LOCK(p_FmPcd->shadowLock);
31557 + RETURN_ERROR(MAJOR, err, NO_MSG);
31558 + }
31559 +
31560 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31561 + p_ModifyKeyParams, useShadowStructs);
31562 +
31563 + if (p_CcNode->maxNumOfKeys)
31564 + RELEASE_LOCK(p_FmPcd->shadowLock);
31565 +
31566 + ReleaseLst(&h_OldPointersLst);
31567 + ReleaseLst(&h_NewPointersLst);
31568 +
31569 + return err;
31570 +}
31571 +
31572 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31573 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
31574 + uint8_t *p_Mask)
31575 +{
31576 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31577 + t_FmPcd *p_FmPcd;
31578 + t_List h_OldPointersLst, h_NewPointersLst;
31579 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31580 + uint16_t tmpKeyIndex;
31581 + bool useShadowStructs = FALSE;
31582 + t_Error err = E_OK;
31583 +
31584 + if (keyIndex >= p_CcNode->numOfKeys)
31585 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31586 + ("keyIndex > previously cleared last index + 1"));
31587 +
31588 + if (keySize != p_CcNode->userSizeOfExtraction)
31589 + RETURN_ERROR(
31590 + MAJOR,
31591 + E_INVALID_VALUE,
31592 + ("size for ModifyKey has to be the same as defined in SetNode"));
31593 +
31594 + if (p_CcNode->h_FmPcd != h_FmPcd)
31595 + RETURN_ERROR(
31596 + MAJOR,
31597 + E_INVALID_VALUE,
31598 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31599 +
31600 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
31601 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31602 + RETURN_ERROR(
31603 + MINOR,
31604 + E_ALREADY_EXISTS,
31605 + ("The received key and mask pair was already found in the match table of the provided node"));
31606 +
31607 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31608 +
31609 + INIT_LIST(&h_OldPointersLst);
31610 + INIT_LIST(&h_NewPointersLst);
31611 +
31612 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31613 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31614 + FALSE);
31615 + if (!p_ModifyKeyParams)
31616 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31617 +
31618 + if (p_CcNode->maxNumOfKeys)
31619 + {
31620 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31621 + {
31622 + XX_Free(p_ModifyKeyParams);
31623 + return ERROR_CODE(E_BUSY);
31624 + }
31625 +
31626 + useShadowStructs = TRUE;
31627 + }
31628 +
31629 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
31630 + p_ModifyKeyParams);
31631 + if (err)
31632 + {
31633 + XX_Free(p_ModifyKeyParams);
31634 + if (p_CcNode->maxNumOfKeys)
31635 + RELEASE_LOCK(p_FmPcd->shadowLock);
31636 + RETURN_ERROR(MAJOR, err, NO_MSG);
31637 + }
31638 +
31639 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31640 + &h_OldPointersLst,
31641 + &h_NewPointersLst);
31642 + if (err)
31643 + {
31644 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31645 + XX_Free(p_ModifyKeyParams);
31646 + if (p_CcNode->maxNumOfKeys)
31647 + RELEASE_LOCK(p_FmPcd->shadowLock);
31648 + RETURN_ERROR(MAJOR, err, NO_MSG);
31649 + }
31650 +
31651 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31652 + p_ModifyKeyParams, useShadowStructs);
31653 +
31654 + if (p_CcNode->maxNumOfKeys)
31655 + RELEASE_LOCK(p_FmPcd->shadowLock);
31656 +
31657 + ReleaseLst(&h_OldPointersLst);
31658 + ReleaseLst(&h_NewPointersLst);
31659 +
31660 + return err;
31661 +}
31662 +
31663 +t_Error FmPcdCcModifyMissNextEngineParamNode(
31664 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31665 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31666 +{
31667 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31668 + t_FmPcd *p_FmPcd;
31669 + t_List h_OldPointersLst, h_NewPointersLst;
31670 + uint16_t keyIndex;
31671 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31672 + t_Error err = E_OK;
31673 +
31674 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
31675 +
31676 + keyIndex = p_CcNode->numOfKeys;
31677 +
31678 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31679 +
31680 + INIT_LIST(&h_OldPointersLst);
31681 + INIT_LIST(&h_NewPointersLst);
31682 +
31683 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31684 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
31685 + FALSE);
31686 + if (!p_ModifyKeyParams)
31687 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31688 +
31689 + if (p_CcNode->maxNumOfKeys
31690 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31691 + {
31692 + XX_Free(p_ModifyKeyParams);
31693 + return ERROR_CODE(E_BUSY);
31694 + }
31695 +
31696 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
31697 + p_FmPcdCcNextEngineParams,
31698 + &h_OldPointersLst, &h_NewPointersLst,
31699 + p_ModifyKeyParams);
31700 + if (err)
31701 + {
31702 + XX_Free(p_ModifyKeyParams);
31703 + if (p_CcNode->maxNumOfKeys)
31704 + RELEASE_LOCK(p_FmPcd->shadowLock);
31705 + RETURN_ERROR(MAJOR, err, NO_MSG);
31706 + }
31707 +
31708 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31709 + p_ModifyKeyParams, FALSE);
31710 +
31711 + if (p_CcNode->maxNumOfKeys)
31712 + RELEASE_LOCK(p_FmPcd->shadowLock);
31713 +
31714 + ReleaseLst(&h_OldPointersLst);
31715 + ReleaseLst(&h_NewPointersLst);
31716 +
31717 + return err;
31718 +}
31719 +
31720 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31721 + uint16_t keyIndex, uint8_t keySize,
31722 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31723 +{
31724 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31725 + t_FmPcd *p_FmPcd;
31726 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31727 + t_List h_OldPointersLst, h_NewPointersLst;
31728 + bool useShadowStructs = FALSE;
31729 + uint16_t tmpKeyIndex;
31730 + t_Error err = E_OK;
31731 +
31732 + if (keyIndex > p_CcNode->numOfKeys)
31733 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
31734 + ("keyIndex > previously cleared last index + 1"));
31735 +
31736 + if (keySize != p_CcNode->userSizeOfExtraction)
31737 + RETURN_ERROR(
31738 + MAJOR,
31739 + E_INVALID_VALUE,
31740 + ("keySize has to be defined as it was defined in initialization step"));
31741 +
31742 + if (p_CcNode->h_FmPcd != h_FmPcd)
31743 + RETURN_ERROR(
31744 + MAJOR,
31745 + E_INVALID_VALUE,
31746 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31747 +
31748 + if (p_CcNode->maxNumOfKeys)
31749 + {
31750 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
31751 + RETURN_ERROR(
31752 + MAJOR,
31753 + E_FULL,
31754 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
31755 + }
31756 + else
31757 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
31758 + RETURN_ERROR(
31759 + MAJOR,
31760 + E_INVALID_VALUE,
31761 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
31762 +
31763 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
31764 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
31765 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31766 + RETURN_ERROR(
31767 + MAJOR,
31768 + E_ALREADY_EXISTS,
31769 + ("The received key and mask pair was already found in the match table of the provided node"));
31770 +
31771 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31772 +
31773 + INIT_LIST(&h_OldPointersLst);
31774 + INIT_LIST(&h_NewPointersLst);
31775 +
31776 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31777 + e_MODIFY_STATE_ADD, TRUE, TRUE,
31778 + FALSE);
31779 + if (!p_ModifyKeyParams)
31780 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31781 +
31782 + if (p_CcNode->maxNumOfKeys)
31783 + {
31784 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31785 + {
31786 + XX_Free(p_ModifyKeyParams);
31787 + return ERROR_CODE(E_BUSY);
31788 + }
31789 +
31790 + useShadowStructs = TRUE;
31791 + }
31792 +
31793 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
31794 + p_FmPcdCcKeyParams,
31795 + p_ModifyKeyParams, TRUE);
31796 + if (err)
31797 + {
31798 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31799 + XX_Free(p_ModifyKeyParams);
31800 + if (p_CcNode->maxNumOfKeys)
31801 + RELEASE_LOCK(p_FmPcd->shadowLock);
31802 + RETURN_ERROR(MAJOR, err, NO_MSG);
31803 + }
31804 +
31805 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31806 + &h_OldPointersLst,
31807 + &h_NewPointersLst);
31808 + if (err)
31809 + {
31810 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31811 + XX_Free(p_ModifyKeyParams);
31812 + if (p_CcNode->maxNumOfKeys)
31813 + RELEASE_LOCK(p_FmPcd->shadowLock);
31814 + RETURN_ERROR(MAJOR, err, NO_MSG);
31815 + }
31816 +
31817 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31818 + p_ModifyKeyParams, useShadowStructs);
31819 + if (p_CcNode->maxNumOfKeys)
31820 + RELEASE_LOCK(p_FmPcd->shadowLock);
31821 +
31822 + ReleaseLst(&h_OldPointersLst);
31823 + ReleaseLst(&h_NewPointersLst);
31824 +
31825 + return err;
31826 +}
31827 +
31828 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31829 + uint16_t keyIndex, uint8_t keySize,
31830 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
31831 +{
31832 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31833 + t_FmPcd *p_FmPcd;
31834 + t_List h_OldPointersLst, h_NewPointersLst;
31835 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31836 + uint16_t tmpKeyIndex;
31837 + bool useShadowStructs = FALSE;
31838 + t_Error err = E_OK;
31839 +
31840 + if (keyIndex > p_CcNode->numOfKeys)
31841 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31842 + ("keyIndex > previously cleared last index + 1"));
31843 +
31844 + if (keySize != p_CcNode->userSizeOfExtraction)
31845 + RETURN_ERROR(
31846 + MAJOR,
31847 + E_INVALID_VALUE,
31848 + ("keySize has to be defined as it was defined in initialization step"));
31849 +
31850 + if (p_CcNode->h_FmPcd != h_FmPcd)
31851 + RETURN_ERROR(
31852 + MAJOR,
31853 + E_INVALID_VALUE,
31854 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31855 +
31856 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
31857 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
31858 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31859 + RETURN_ERROR(
31860 + MINOR,
31861 + E_ALREADY_EXISTS,
31862 + ("The received key and mask pair was already found in the match table of the provided node"));
31863 +
31864 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31865 +
31866 + INIT_LIST(&h_OldPointersLst);
31867 + INIT_LIST(&h_NewPointersLst);
31868 +
31869 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31870 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31871 + FALSE);
31872 + if (!p_ModifyKeyParams)
31873 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31874 +
31875 + if (p_CcNode->maxNumOfKeys)
31876 + {
31877 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31878 + {
31879 + XX_Free(p_ModifyKeyParams);
31880 + return ERROR_CODE(E_BUSY);
31881 + }
31882 +
31883 + useShadowStructs = TRUE;
31884 + }
31885 +
31886 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
31887 + p_FmPcdCcKeyParams,
31888 + p_ModifyKeyParams, FALSE);
31889 + if (err)
31890 + {
31891 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31892 + XX_Free(p_ModifyKeyParams);
31893 + if (p_CcNode->maxNumOfKeys)
31894 + RELEASE_LOCK(p_FmPcd->shadowLock);
31895 + RETURN_ERROR(MAJOR, err, NO_MSG);
31896 + }
31897 +
31898 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31899 + &h_OldPointersLst,
31900 + &h_NewPointersLst);
31901 + if (err)
31902 + {
31903 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31904 + XX_Free(p_ModifyKeyParams);
31905 + if (p_CcNode->maxNumOfKeys)
31906 + RELEASE_LOCK(p_FmPcd->shadowLock);
31907 + RETURN_ERROR(MAJOR, err, NO_MSG);
31908 + }
31909 +
31910 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31911 + p_ModifyKeyParams, useShadowStructs);
31912 +
31913 + if (p_CcNode->maxNumOfKeys)
31914 + RELEASE_LOCK(p_FmPcd->shadowLock);
31915 +
31916 + ReleaseLst(&h_OldPointersLst);
31917 + ReleaseLst(&h_NewPointersLst);
31918 +
31919 + return err;
31920 +}
31921 +
31922 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
31923 + t_Handle h_Pointer)
31924 +{
31925 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
31926 + t_CcNodeInformation *p_CcNodeInfo;
31927 +
31928 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
31929 + (uint32_t)ILLEGAL_BASE);
31930 +
31931 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
31932 +
31933 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
31934 + - p_FmPcd->physicalMuramBase);
31935 +}
31936 +
31937 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
31938 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
31939 +{
31940 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31941 +
31942 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31943 +
31944 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31945 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31946 + ("grpId you asked > numOfGroup of relevant tree"));
31947 +
31948 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
31949 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
31950 +
31951 + return E_OK;
31952 +}
31953 +
31954 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
31955 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
31956 + t_Handle h_FmPort)
31957 +{
31958 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
31959 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31960 + t_Error err = E_OK;
31961 +
31962 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31963 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31964 +
31965 + /* this routine must be protected by the calling routine by locking all PCD modules! */
31966 +
31967 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
31968 +
31969 + if (err == E_OK)
31970 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
31971 +
31972 + *p_Offset = (uint32_t)(XX_VirtToPhys(
31973 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
31974 + - p_FmPcd->physicalMuramBase);
31975 +
31976 + return err;
31977 +}
31978 +
31979 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
31980 +{
31981 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31982 +
31983 + /* this routine must be protected by the calling routine by locking all PCD modules! */
31984 +
31985 + UNUSED(h_FmPcd);
31986 +
31987 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31988 +
31989 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
31990 +
31991 + return E_OK;
31992 +}
31993 +
31994 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31995 + t_List *p_List)
31996 +{
31997 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31998 + t_List *p_Pos, *p_Tmp;
31999 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
32000 + uint32_t intFlags;
32001 + t_Error err = E_OK;
32002 +
32003 + intFlags = FmPcdLock(h_FmPcd);
32004 +
32005 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
32006 + {
32007 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32008 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
32009 +
32010 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
32011 +
32012 + if (err)
32013 + {
32014 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
32015 + {
32016 + if (p_Tmp == p_Pos)
32017 + break;
32018 +
32019 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
32020 + }
32021 + break;
32022 + }
32023 +
32024 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
32025 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
32026 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
32027 + }
32028 +
32029 + FmPcdUnlock(h_FmPcd, intFlags);
32030 + CORE_MemoryBarrier();
32031 +
32032 + return err;
32033 +}
32034 +
32035 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
32036 +{
32037 + t_List *p_Pos;
32038 + t_CcNodeInformation *p_CcNodeInfo;
32039 + t_Handle h_FmPcdCcTree;
32040 + uint32_t intFlags;
32041 +
32042 + intFlags = FmPcdLock(h_FmPcd);
32043 +
32044 + LIST_FOR_EACH(p_Pos, p_List)
32045 + {
32046 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32047 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
32048 + CcRootReleaseLock(h_FmPcdCcTree);
32049 + }
32050 +
32051 + ReleaseLst(p_List);
32052 +
32053 + FmPcdUnlock(h_FmPcd, intFlags);
32054 + CORE_MemoryBarrier();
32055 +}
32056 +
32057 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
32058 +{
32059 + uint32_t intFlags;
32060 + uint32_t newSize = 0, newAlign = 0;
32061 + bool allocFail = FALSE;
32062 +
32063 + ASSERT_COND(p_FmPcd);
32064 +
32065 + if (!size)
32066 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
32067 +
32068 + if (!POWER_OF_2(align))
32069 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
32070 +
32071 + newSize = p_FmPcd->ccShadowSize;
32072 + newAlign = p_FmPcd->ccShadowAlign;
32073 +
32074 + /* Check if current shadow is large enough to hold the requested size */
32075 + if (size > p_FmPcd->ccShadowSize)
32076 + newSize = size;
32077 +
32078 + /* Check if current shadow matches the requested alignment */
32079 + if (align > p_FmPcd->ccShadowAlign)
32080 + newAlign = align;
32081 +
32082 + /* If a bigger shadow size or bigger shadow alignment are required,
32083 + a new shadow will be allocated */
32084 + if ((newSize != p_FmPcd->ccShadowSize)
32085 + || (newAlign != p_FmPcd->ccShadowAlign))
32086 + {
32087 + intFlags = FmPcdLock(p_FmPcd);
32088 +
32089 + if (p_FmPcd->p_CcShadow)
32090 + {
32091 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
32092 + p_FmPcd->ccShadowSize = 0;
32093 + p_FmPcd->ccShadowAlign = 0;
32094 + }
32095 +
32096 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
32097 + newSize, newAlign);
32098 + if (!p_FmPcd->p_CcShadow)
32099 + {
32100 + allocFail = TRUE;
32101 +
32102 + /* If new shadow size allocation failed,
32103 + re-allocate with previous parameters */
32104 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
32105 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
32106 + p_FmPcd->ccShadowAlign);
32107 + }
32108 +
32109 + FmPcdUnlock(p_FmPcd, intFlags);
32110 +
32111 + if (allocFail)
32112 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32113 + ("MURAM allocation for CC Shadow memory"));
32114 +
32115 + p_FmPcd->ccShadowSize = newSize;
32116 + p_FmPcd->ccShadowAlign = newAlign;
32117 + }
32118 +
32119 + return E_OK;
32120 +}
32121 +
32122 +#if (DPAA_VERSION >= 11)
32123 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
32124 + t_Handle h_ReplicGroup,
32125 + t_List *p_AdTables,
32126 + uint32_t *p_NumOfAdTables)
32127 +{
32128 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
32129 + int i = 0;
32130 + void * p_AdTable;
32131 + t_CcNodeInformation ccNodeInfo;
32132 +
32133 + ASSERT_COND(h_Node);
32134 + *p_NumOfAdTables = 0;
32135 +
32136 + /* search in the current node which exact index points on this current replicator group for getting AD */
32137 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
32138 + {
32139 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32140 + == e_FM_PCD_FR)
32141 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
32142 + == (t_Handle)h_ReplicGroup)))
32143 + {
32144 + /* save the current ad table in the list */
32145 + /* this entry uses the input replicator group */
32146 + p_AdTable =
32147 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
32148 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32149 + ccNodeInfo.h_CcNode = p_AdTable;
32150 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
32151 + (*p_NumOfAdTables)++;
32152 + }
32153 + }
32154 +
32155 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
32156 +}
32157 +#endif /* (DPAA_VERSION >= 11) */
32158 +/*********************** End of inter-module routines ************************/
32159 +
32160 +/****************************************/
32161 +/* API Init unit functions */
32162 +/****************************************/
32163 +
32164 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
32165 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
32166 +{
32167 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32168 + t_Error err = E_OK;
32169 + int i = 0, j = 0, k = 0;
32170 + t_FmPcdCcTree *p_FmPcdCcTree;
32171 + uint8_t numOfEntries;
32172 + t_Handle p_CcTreeTmp;
32173 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
32174 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
32175 + t_NetEnvParams netEnvParams;
32176 + uint8_t lastOne = 0;
32177 + uint32_t requiredAction = 0;
32178 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32179 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32180 +
32181 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32182 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
32183 +
32184 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32185 + {
32186 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32187 + return NULL;
32188 + }
32189 +
32190 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
32191 + if (!p_FmPcdCcTree)
32192 + {
32193 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
32194 + return NULL;
32195 + }
32196 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
32197 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
32198 +
32199 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
32200 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32201 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32202 + memset(p_Params,
32203 + 0,
32204 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32205 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32206 +
32207 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
32208 +
32209 +#ifdef FM_CAPWAP_SUPPORT
32210 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
32211 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
32212 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
32213 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
32214 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
32215 + {
32216 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
32217 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
32218 + {
32219 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
32220 + XX_Free(p_Params);
32221 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32222 + return NULL;
32223 + }
32224 + }
32225 +#endif /* FM_CAPWAP_SUPPORT */
32226 +
32227 + numOfEntries = 0;
32228 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
32229 +
32230 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
32231 + {
32232 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
32233 +
32234 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
32235 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
32236 + {
32237 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32238 + XX_Free(p_Params);
32239 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
32240 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
32241 + return NULL;
32242 + }
32243 +
32244 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
32245 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
32246 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
32247 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32248 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32249 + {
32250 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32251 + XX_Free(p_Params);
32252 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32253 + return NULL;
32254 + }
32255 +
32256 + if (lastOne)
32257 + {
32258 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
32259 + {
32260 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32261 + XX_Free(p_Params);
32262 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
32263 + return NULL;
32264 + }
32265 + }
32266 +
32267 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32268 +
32269 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
32270 + netEnvParams.numOfDistinctionUnits =
32271 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
32272 +
32273 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
32274 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
32275 +
32276 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
32277 + if (err)
32278 + {
32279 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32280 + XX_Free(p_Params);
32281 + REPORT_ERROR(MAJOR, err, NO_MSG);
32282 + return NULL;
32283 + }
32284 +
32285 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
32286 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32287 + j++)
32288 + {
32289 + err = ValidateNextEngineParams(
32290 + h_FmPcd,
32291 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32292 + e_FM_PCD_CC_STATS_MODE_NONE);
32293 + if (err)
32294 + {
32295 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32296 + XX_Free(p_Params);
32297 + REPORT_ERROR(MAJOR, err, (NO_MSG));
32298 + return NULL;
32299 + }
32300 +
32301 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
32302 + {
32303 + err = FmPcdManipCheckParamsForCcNextEngine(
32304 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32305 + &requiredAction);
32306 + if (err)
32307 + {
32308 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32309 + XX_Free(p_Params);
32310 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32311 + return NULL;
32312 + }
32313 + }
32314 + p_KeyAndNextEngineParams = p_Params + k;
32315 +
32316 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
32317 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32318 + sizeof(t_FmPcdCcNextEngineParams));
32319 +
32320 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
32321 + == e_FM_PCD_CC)
32322 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
32323 + {
32324 + err =
32325 + AllocAndFillAdForContLookupManip(
32326 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
32327 + if (err)
32328 + {
32329 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32330 + XX_Free(p_Params);
32331 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32332 + return NULL;
32333 + }
32334 + }
32335 +
32336 + requiredAction |= UPDATE_CC_WITH_TREE;
32337 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
32338 +
32339 + k++;
32340 + }
32341 + }
32342 +
32343 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
32344 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
32345 +
32346 + p_FmPcdCcTree->ccTreeBaseAddr =
32347 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
32348 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
32349 + FM_PCD_CC_TREE_ADDR_ALIGN));
32350 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
32351 + {
32352 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32353 + XX_Free(p_Params);
32354 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32355 + return NULL;
32356 + }
32357 + MemSet8(
32358 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
32359 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
32360 +
32361 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32362 +
32363 + for (i = 0; i < numOfEntries; i++)
32364 + {
32365 + p_KeyAndNextEngineParams = p_Params + i;
32366 +
32367 + NextStepAd(p_CcTreeTmp, NULL,
32368 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
32369 +
32370 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32371 +
32372 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
32373 + p_KeyAndNextEngineParams,
32374 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
32375 +
32376 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32377 + == e_FM_PCD_CC)
32378 + {
32379 + p_FmPcdCcNextNode =
32380 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
32381 + p_CcInformation = FindNodeInfoInReleventLst(
32382 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
32383 + p_FmPcdCcNextNode->h_Spinlock);
32384 +
32385 + if (!p_CcInformation)
32386 + {
32387 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32388 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
32389 + ccNodeInfo.index = 1;
32390 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
32391 + &ccNodeInfo,
32392 + p_FmPcdCcNextNode->h_Spinlock);
32393 + }
32394 + else
32395 + p_CcInformation->index++;
32396 + }
32397 + }
32398 +
32399 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
32400 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32401 +
32402 + if (!FmPcdLockTryLockAll(p_FmPcd))
32403 + {
32404 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32405 + XX_Free(p_Params);
32406 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32407 + return NULL;
32408 + }
32409 +
32410 + for (i = 0; i < numOfEntries; i++)
32411 + {
32412 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
32413 + {
32414 + err = SetRequiredAction(
32415 + h_FmPcd,
32416 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
32417 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
32418 + p_FmPcdCcTree);
32419 + if (err)
32420 + {
32421 + FmPcdLockUnlockAll(p_FmPcd);
32422 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32423 + XX_Free(p_Params);
32424 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32425 + return NULL;
32426 + }
32427 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32428 + }
32429 + }
32430 +
32431 + FmPcdLockUnlockAll(p_FmPcd);
32432 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
32433 + if (!p_FmPcdCcTree->p_Lock)
32434 + {
32435 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32436 + XX_Free(p_Params);
32437 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
32438 + return NULL;
32439 + }
32440 +
32441 + XX_Free(p_Params);
32442 +
32443 + return p_FmPcdCcTree;
32444 +}
32445 +
32446 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
32447 +{
32448 + t_FmPcd *p_FmPcd;
32449 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32450 + int i = 0;
32451 +
32452 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32453 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32454 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32455 +
32456 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
32457 +
32458 + if (p_CcTree->owners)
32459 + RETURN_ERROR(
32460 + MAJOR,
32461 + E_INVALID_SELECTION,
32462 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
32463 +
32464 + /* Delete ip-reassembly schemes if exist */
32465 + if (p_CcTree->h_IpReassemblyManip)
32466 + {
32467 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
32468 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
32469 + }
32470 +
32471 + /* Delete capwap-reassembly schemes if exist */
32472 + if (p_CcTree->h_CapwapReassemblyManip)
32473 + {
32474 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
32475 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
32476 + }
32477 +
32478 + for (i = 0; i < p_CcTree->numOfEntries; i++)
32479 + {
32480 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32481 + == e_FM_PCD_CC)
32482 + UpdateNodeOwner(
32483 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32484 + FALSE);
32485 +
32486 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32487 + FmPcdManipUpdateOwner(
32488 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32489 + FALSE);
32490 +
32491 +#ifdef FM_CAPWAP_SUPPORT
32492 + if ((p_CcTree->numOfGrps == 1) &&
32493 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
32494 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
32495 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
32496 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
32497 + {
32498 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
32499 + return E_INVALID_STATE;
32500 + }
32501 +#endif /* FM_CAPWAP_SUPPORT */
32502 +
32503 +#if (DPAA_VERSION >= 11)
32504 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32505 + == e_FM_PCD_FR)
32506 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32507 + FrmReplicGroupUpdateOwner(
32508 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32509 + FALSE);
32510 +#endif /* (DPAA_VERSION >= 11) */
32511 + }
32512 +
32513 + if (p_CcTree->p_Lock)
32514 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
32515 +
32516 + DeleteTree(p_CcTree, p_FmPcd);
32517 +
32518 + return E_OK;
32519 +}
32520 +
32521 +t_Error FM_PCD_CcRootModifyNextEngine(
32522 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
32523 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32524 +{
32525 + t_FmPcd *p_FmPcd;
32526 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32527 + t_Error err = E_OK;
32528 +
32529 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32530 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32531 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32532 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32533 +
32534 + if (!FmPcdLockTryLockAll(p_FmPcd))
32535 + {
32536 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32537 + return ERROR_CODE(E_BUSY);
32538 + }
32539 +
32540 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
32541 + p_FmPcdCcNextEngineParams);
32542 + FmPcdLockUnlockAll(p_FmPcd);
32543 +
32544 + if (err)
32545 + {
32546 + RETURN_ERROR(MAJOR, err, NO_MSG);
32547 + }
32548 +
32549 + return E_OK;
32550 +}
32551 +
32552 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
32553 + t_FmPcdCcNodeParams *p_CcNodeParam)
32554 +{
32555 + t_FmPcdCcNode *p_CcNode;
32556 + t_Error err;
32557 +
32558 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32559 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
32560 +
32561 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
32562 + if (!p_CcNode)
32563 + {
32564 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32565 + return NULL;
32566 + }
32567 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
32568 +
32569 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
32570 +
32571 + switch(GET_ERROR_TYPE(err)
32572 +) {
32573 + case E_OK:
32574 + break;
32575 +
32576 + case E_BUSY:
32577 + DBG(TRACE, ("E_BUSY error"));
32578 + return NULL;
32579 +
32580 + default:
32581 + REPORT_ERROR(MAJOR, err, NO_MSG);
32582 + return NULL;
32583 + }
32584 +
32585 + return p_CcNode;
32586 +}
32587 +
32588 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
32589 +{
32590 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32591 + int i = 0;
32592 +
32593 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32594 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
32595 +
32596 + if (p_CcNode->owners)
32597 + RETURN_ERROR(
32598 + MAJOR,
32599 + E_INVALID_STATE,
32600 + ("This node cannot be removed because it is occupied; first unbind this node"));
32601 +
32602 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32603 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32604 + == e_FM_PCD_CC)
32605 + UpdateNodeOwner(
32606 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32607 + FALSE);
32608 +
32609 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32610 + == e_FM_PCD_CC)
32611 + UpdateNodeOwner(
32612 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32613 + FALSE);
32614 +
32615 + /* Handle also Miss entry */
32616 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
32617 + {
32618 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32619 + FmPcdManipUpdateOwner(
32620 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32621 + FALSE);
32622 +
32623 +#if (DPAA_VERSION >= 11)
32624 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32625 + == e_FM_PCD_FR)
32626 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32627 + {
32628 + FrmReplicGroupUpdateOwner(
32629 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32630 + FALSE);
32631 + }
32632 +#endif /* (DPAA_VERSION >= 11) */
32633 + }
32634 +
32635 + DeleteNode(p_CcNode);
32636 +
32637 + return E_OK;
32638 +}
32639 +
32640 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
32641 + uint8_t keySize,
32642 + t_FmPcdCcKeyParams *p_KeyParams)
32643 +{
32644 + t_FmPcd *p_FmPcd;
32645 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32646 + t_Error err = E_OK;
32647 +
32648 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32649 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32650 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32651 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32652 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32653 +
32654 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
32655 + keyIndex = p_CcNode->numOfKeys;
32656 +
32657 + if (!FmPcdLockTryLockAll(p_FmPcd))
32658 + {
32659 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32660 + return ERROR_CODE(E_BUSY);
32661 + }
32662 +
32663 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
32664 +
32665 + FmPcdLockUnlockAll(p_FmPcd);
32666 +
32667 + switch(GET_ERROR_TYPE(err)
32668 +) {
32669 + case E_OK:
32670 + return E_OK;
32671 +
32672 + case E_BUSY:
32673 + DBG(TRACE, ("E_BUSY error"));
32674 + return ERROR_CODE(E_BUSY);
32675 +
32676 + default:
32677 + RETURN_ERROR(MAJOR, err, NO_MSG);
32678 + }
32679 +}
32680 +
32681 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
32682 +{
32683 + t_FmPcd *p_FmPcd;
32684 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32685 + t_Error err = E_OK;
32686 +
32687 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32688 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32689 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32690 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32691 +
32692 + if (!FmPcdLockTryLockAll(p_FmPcd))
32693 + {
32694 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32695 + return ERROR_CODE(E_BUSY);
32696 + }
32697 +
32698 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
32699 +
32700 + FmPcdLockUnlockAll(p_FmPcd);
32701 +
32702 + switch(GET_ERROR_TYPE(err)
32703 +) {
32704 + case E_OK:
32705 + return E_OK;
32706 +
32707 + case E_BUSY:
32708 + DBG(TRACE, ("E_BUSY error"));
32709 + return ERROR_CODE(E_BUSY);
32710 +
32711 + default:
32712 + RETURN_ERROR(MAJOR, err, NO_MSG);
32713 + }
32714 +
32715 + return E_OK;
32716 +}
32717 +
32718 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
32719 + uint8_t keySize, uint8_t *p_Key,
32720 + uint8_t *p_Mask)
32721 +{
32722 + t_FmPcd *p_FmPcd;
32723 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32724 + t_Error err = E_OK;
32725 +
32726 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32727 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
32728 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32729 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32730 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32731 +
32732 +
32733 + if (!FmPcdLockTryLockAll(p_FmPcd))
32734 + {
32735 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32736 + return ERROR_CODE(E_BUSY);
32737 + }
32738 +
32739 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
32740 +
32741 + FmPcdLockUnlockAll(p_FmPcd);
32742 +
32743 + switch(GET_ERROR_TYPE(err)
32744 +) {
32745 + case E_OK:
32746 + return E_OK;
32747 +
32748 + case E_BUSY:
32749 + DBG(TRACE, ("E_BUSY error"));
32750 + return ERROR_CODE(E_BUSY);
32751 +
32752 + default:
32753 + RETURN_ERROR(MAJOR, err, NO_MSG);
32754 + }
32755 +}
32756 +
32757 +t_Error FM_PCD_MatchTableModifyNextEngine(
32758 + t_Handle h_CcNode, uint16_t keyIndex,
32759 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32760 +{
32761 + t_FmPcd *p_FmPcd;
32762 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32763 + t_Error err = E_OK;
32764 +
32765 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32766 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32767 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32768 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32769 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32770 +
32771 + if (!FmPcdLockTryLockAll(p_FmPcd))
32772 + {
32773 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32774 + return ERROR_CODE(E_BUSY);
32775 + }
32776 +
32777 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
32778 + p_FmPcdCcNextEngineParams);
32779 +
32780 + FmPcdLockUnlockAll(p_FmPcd);
32781 +
32782 + switch(GET_ERROR_TYPE(err)
32783 +) {
32784 + case E_OK:
32785 + return E_OK;
32786 +
32787 + case E_BUSY:
32788 + DBG(TRACE, ("E_BUSY error"));
32789 + return ERROR_CODE(E_BUSY);
32790 +
32791 + default:
32792 + RETURN_ERROR(MAJOR, err, NO_MSG);
32793 + }
32794 +}
32795 +
32796 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
32797 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32798 +{
32799 + t_FmPcd *p_FmPcd;
32800 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32801 + t_Error err = E_OK;
32802 +
32803 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32804 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32805 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32806 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32807 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32808 +
32809 + if (!FmPcdLockTryLockAll(p_FmPcd))
32810 + {
32811 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32812 + return ERROR_CODE(E_BUSY);
32813 + }
32814 +
32815 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
32816 + p_FmPcdCcNextEngineParams);
32817 +
32818 + FmPcdLockUnlockAll(p_FmPcd);
32819 +
32820 + switch(GET_ERROR_TYPE(err)
32821 +) {
32822 + case E_OK:
32823 + return E_OK;
32824 +
32825 + case E_BUSY:
32826 + DBG(TRACE, ("E_BUSY error"));
32827 + return ERROR_CODE(E_BUSY);
32828 +
32829 + default:
32830 + RETURN_ERROR(MAJOR, err, NO_MSG);
32831 + }
32832 +}
32833 +
32834 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
32835 + uint16_t keyIndex,
32836 + uint8_t keySize,
32837 + t_FmPcdCcKeyParams *p_KeyParams)
32838 +{
32839 + t_FmPcd *p_FmPcd;
32840 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32841 + t_Error err = E_OK;
32842 +
32843 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32844 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32845 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32846 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32847 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32848 +
32849 + if (!FmPcdLockTryLockAll(p_FmPcd))
32850 + {
32851 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32852 + return ERROR_CODE(E_BUSY);
32853 + }
32854 +
32855 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
32856 + p_KeyParams);
32857 +
32858 + FmPcdLockUnlockAll(p_FmPcd);
32859 +
32860 + switch(GET_ERROR_TYPE(err)
32861 +) {
32862 + case E_OK:
32863 + return E_OK;
32864 +
32865 + case E_BUSY:
32866 + DBG(TRACE, ("E_BUSY error"));
32867 + return ERROR_CODE(E_BUSY);
32868 +
32869 + default:
32870 + RETURN_ERROR(MAJOR, err, NO_MSG);
32871 + }
32872 +}
32873 +
32874 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
32875 + uint8_t *p_Key, uint8_t *p_Mask)
32876 +{
32877 + t_FmPcd *p_FmPcd;
32878 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32879 + uint16_t keyIndex;
32880 + t_Error err;
32881 +
32882 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
32883 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32884 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32885 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32886 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32887 +
32888 + if (!FmPcdLockTryLockAll(p_FmPcd))
32889 + {
32890 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32891 + return ERROR_CODE(E_BUSY);
32892 + }
32893 +
32894 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
32895 + if (GET_ERROR_TYPE(err) != E_OK)
32896 + {
32897 + FmPcdLockUnlockAll(p_FmPcd);
32898 + RETURN_ERROR(
32899 + MAJOR,
32900 + err,
32901 + ("The received key and mask pair was not found in the match table of the provided node"));
32902 + }
32903 +
32904 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
32905 +
32906 + FmPcdLockUnlockAll(p_FmPcd);
32907 +
32908 + switch(GET_ERROR_TYPE(err)
32909 +) {
32910 + case E_OK:
32911 + return E_OK;
32912 +
32913 + case E_BUSY:
32914 + DBG(TRACE, ("E_BUSY error"));
32915 + return ERROR_CODE(E_BUSY);
32916 +
32917 + default:
32918 + RETURN_ERROR(MAJOR, err, NO_MSG);
32919 + }
32920 +}
32921 +
32922 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
32923 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
32924 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32925 +{
32926 + t_FmPcd *p_FmPcd;
32927 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32928 + uint16_t keyIndex;
32929 + t_Error err;
32930 +
32931 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
32932 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32933 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32934 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32935 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32936 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32937 +
32938 + if (!FmPcdLockTryLockAll(p_FmPcd))
32939 + {
32940 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32941 + return ERROR_CODE(E_BUSY);
32942 + }
32943 +
32944 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
32945 + if (GET_ERROR_TYPE(err) != E_OK)
32946 + {
32947 + FmPcdLockUnlockAll(p_FmPcd);
32948 + RETURN_ERROR(
32949 + MAJOR,
32950 + err,
32951 + ("The received key and mask pair was not found in the match table of the provided node"));
32952 + }
32953 +
32954 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
32955 + p_FmPcdCcNextEngineParams);
32956 +
32957 + FmPcdLockUnlockAll(p_FmPcd);
32958 +
32959 + switch(GET_ERROR_TYPE(err)
32960 +) {
32961 + case E_OK:
32962 + return E_OK;
32963 +
32964 + case E_BUSY:
32965 + DBG(TRACE, ("E_BUSY error"));
32966 + return ERROR_CODE(E_BUSY);
32967 +
32968 + default:
32969 + RETURN_ERROR(MAJOR, err, NO_MSG);
32970 + }
32971 +}
32972 +
32973 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
32974 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
32975 + t_FmPcdCcKeyParams *p_KeyParams)
32976 +{
32977 + t_FmPcd *p_FmPcd;
32978 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32979 + uint16_t keyIndex;
32980 + t_Error err;
32981 +
32982 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
32983 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
32984 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32985 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32986 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32987 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
32988 +
32989 + if (!FmPcdLockTryLockAll(p_FmPcd))
32990 + {
32991 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32992 + return ERROR_CODE(E_BUSY);
32993 + }
32994 +
32995 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
32996 + if (GET_ERROR_TYPE(err) != E_OK)
32997 + {
32998 + FmPcdLockUnlockAll(p_FmPcd);
32999 + RETURN_ERROR(
33000 + MAJOR,
33001 + err,
33002 + ("The received key and mask pair was not found in the match table of the provided node"));
33003 + }
33004 +
33005 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
33006 + p_KeyParams);
33007 +
33008 + FmPcdLockUnlockAll(p_FmPcd);
33009 +
33010 + switch(GET_ERROR_TYPE(err)
33011 +) {
33012 + case E_OK:
33013 + return E_OK;
33014 +
33015 + case E_BUSY:
33016 + DBG(TRACE, ("E_BUSY error"));
33017 + return ERROR_CODE(E_BUSY);
33018 +
33019 + default:
33020 + RETURN_ERROR(MAJOR, err, NO_MSG);
33021 + }
33022 +}
33023 +
33024 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
33025 + uint8_t *p_Key, uint8_t *p_Mask,
33026 + uint8_t *p_NewKey, uint8_t *p_NewMask)
33027 +{
33028 + t_FmPcd *p_FmPcd;
33029 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33030 + t_List h_List;
33031 + uint16_t keyIndex;
33032 + t_Error err;
33033 +
33034 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33035 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
33036 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33037 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33038 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33039 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33040 +
33041 + INIT_LIST(&h_List);
33042 +
33043 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
33044 + if (err)
33045 + {
33046 + DBG(TRACE, ("Node's trees lock failed"));
33047 + return ERROR_CODE(E_BUSY);
33048 + }
33049 +
33050 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33051 + if (GET_ERROR_TYPE(err) != E_OK)
33052 + {
33053 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33054 + RETURN_ERROR(MAJOR, err,
33055 + ("The received key and mask pair was not found in the "
33056 + "match table of the provided node"));
33057 + }
33058 +
33059 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
33060 + p_NewMask);
33061 +
33062 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33063 +
33064 + switch(GET_ERROR_TYPE(err)
33065 +) {
33066 + case E_OK:
33067 + return E_OK;
33068 +
33069 + case E_BUSY:
33070 + DBG(TRACE, ("E_BUSY error"));
33071 + return ERROR_CODE(E_BUSY);
33072 +
33073 + default:
33074 + RETURN_ERROR(MAJOR, err, NO_MSG);
33075 + }
33076 +}
33077 +
33078 +t_Error FM_PCD_MatchTableGetNextEngine(
33079 + t_Handle h_CcNode, uint16_t keyIndex,
33080 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33081 +{
33082 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33083 +
33084 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33085 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33086 +
33087 + if (keyIndex >= p_CcNode->numOfKeys)
33088 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33089 + ("keyIndex exceeds current number of keys"));
33090 +
33091 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
33092 + RETURN_ERROR(
33093 + MAJOR,
33094 + E_INVALID_VALUE,
33095 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
33096 +
33097 + memcpy(p_FmPcdCcNextEngineParams,
33098 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
33099 + sizeof(t_FmPcdCcNextEngineParams));
33100 +
33101 + return E_OK;
33102 +}
33103 +
33104 +
33105 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
33106 +{
33107 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33108 + uint32_t *p_StatsCounters, frameCount;
33109 + uint32_t intFlags;
33110 +
33111 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
33112 +
33113 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
33114 + {
33115 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
33116 + return 0;
33117 + }
33118 +
33119 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
33120 + && (p_CcNode->statisticsMode
33121 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33122 + {
33123 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
33124 + return 0;
33125 + }
33126 +
33127 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33128 +
33129 + if (keyIndex >= p_CcNode->numOfKeys)
33130 + {
33131 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33132 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
33133 + return 0;
33134 + }
33135 +
33136 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
33137 + {
33138 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33139 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
33140 + return 0;
33141 + }
33142 +
33143 + p_StatsCounters =
33144 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
33145 + ASSERT_COND(p_StatsCounters);
33146 +
33147 + /* The first counter is byte counter, so we need to advance to the next counter */
33148 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
33149 + FM_PCD_CC_STATS_COUNTER_SIZE)));
33150 +
33151 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33152 +
33153 + return frameCount;
33154 +}
33155 +
33156 +t_Error FM_PCD_MatchTableGetKeyStatistics(
33157 + t_Handle h_CcNode, uint16_t keyIndex,
33158 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33159 +{
33160 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33161 + uint32_t intFlags;
33162 + t_Error err;
33163 +
33164 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33165 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33166 +
33167 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33168 +
33169 + if (keyIndex >= p_CcNode->numOfKeys)
33170 + RETURN_ERROR(
33171 + MAJOR,
33172 + E_INVALID_STATE,
33173 + ("The provided keyIndex exceeds the number of keys in this match table"));
33174 +
33175 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33176 +
33177 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33178 +
33179 + if (err != E_OK)
33180 + RETURN_ERROR(MAJOR, err, NO_MSG);
33181 +
33182 + return E_OK;
33183 +}
33184 +
33185 +t_Error FM_PCD_MatchTableGetMissStatistics(
33186 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
33187 +{
33188 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33189 + uint32_t intFlags;
33190 + t_Error err;
33191 +
33192 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33193 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33194 +
33195 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33196 +
33197 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
33198 + p_MissStatistics);
33199 +
33200 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33201 +
33202 + if (err != E_OK)
33203 + RETURN_ERROR(MAJOR, err, NO_MSG);
33204 +
33205 + return E_OK;
33206 +}
33207 +
33208 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
33209 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33210 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33211 +{
33212 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33213 + uint16_t keyIndex;
33214 + uint32_t intFlags;
33215 + t_Error err;
33216 +
33217 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33218 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33219 +
33220 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33221 +
33222 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33223 + if (GET_ERROR_TYPE(err) != E_OK)
33224 + {
33225 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33226 + RETURN_ERROR(MAJOR, err,
33227 + ("The received key and mask pair was not found in the "
33228 + "match table of the provided node"));
33229 + }
33230 +
33231 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
33232 +
33233 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33234 +
33235 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33236 +
33237 + if (err != E_OK)
33238 + RETURN_ERROR(MAJOR, err, NO_MSG);
33239 +
33240 + return E_OK;
33241 +}
33242 +
33243 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
33244 + uint8_t keySize, uint8_t *p_Key,
33245 + uint8_t hashShift,
33246 + t_Handle *p_CcNodeBucketHandle,
33247 + uint8_t *p_BucketIndex,
33248 + uint16_t *p_LastIndex)
33249 +{
33250 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33251 + uint16_t glblMask;
33252 + uint64_t crc64 = 0;
33253 +
33254 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33255 + SANITY_CHECK_RETURN_ERROR(
33256 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
33257 + E_INVALID_STATE);
33258 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33259 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
33260 +
33261 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
33262 + be16_to_cpus(&glblMask);
33263 +
33264 + crc64 = crc64_init();
33265 + crc64 = crc64_compute(p_Key, keySize, crc64);
33266 + crc64 >>= hashShift;
33267 +
33268 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
33269 + & glblMask) >> 4);
33270 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
33271 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
33272 +
33273 + *p_CcNodeBucketHandle =
33274 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
33275 + if (!*p_CcNodeBucketHandle)
33276 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
33277 +
33278 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
33279 +
33280 + return E_OK;
33281 +}
33282 +
33283 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
33284 +{
33285 + t_FmPcdCcNode *p_CcNodeHashTbl;
33286 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
33287 + t_FmPcdCcNode *p_CcNode;
33288 + t_Handle h_MissStatsCounters = NULL;
33289 + t_FmPcdCcKeyParams *p_HashKeyParams;
33290 + int i;
33291 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
33292 + bool statsEnForMiss = FALSE;
33293 + t_Error err;
33294 +
33295 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33296 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
33297 +
33298 + if (p_Param->maxNumOfKeys == 0)
33299 + {
33300 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
33301 + return NULL;
33302 + }
33303 +
33304 + if (p_Param->hashResMask == 0)
33305 + {
33306 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
33307 + return NULL;
33308 + }
33309 +
33310 + /*Fix: QorIQ SDK / QSDK-2131*/
33311 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
33312 + {
33313 + 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."));
33314 + return NULL;
33315 + }
33316 +
33317 +#if (DPAA_VERSION >= 11)
33318 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
33319 + {
33320 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33321 + ("RMON statistics mode is not supported for hash table"));
33322 + return NULL;
33323 + }
33324 +#endif /* (DPAA_VERSION >= 11) */
33325 +
33326 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33327 + sizeof(t_FmPcdCcNodeParams));
33328 + if (!p_ExactMatchCcNodeParam)
33329 + {
33330 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
33331 + return NULL;
33332 + }
33333 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33334 +
33335 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33336 + sizeof(t_FmPcdCcNodeParams));
33337 + if (!p_IndxHashCcNodeParam)
33338 + {
33339 + XX_Free(p_ExactMatchCcNodeParam);
33340 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
33341 + return NULL;
33342 + }
33343 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33344 +
33345 + /* Calculate number of sets and number of ways of the hash table */
33346 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
33347 + while (countMask)
33348 + {
33349 + onesCount++;
33350 + countMask = (uint16_t)(countMask >> 1);
33351 + }
33352 +
33353 + numOfSets = (uint16_t)(1 << onesCount);
33354 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
33355 +
33356 + if (p_Param->maxNumOfKeys % numOfSets)
33357 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
33358 +
33359 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
33360 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33361 + {
33362 + /* Allocating a statistics counters table that will be used by all
33363 + 'miss' entries of the hash table */
33364 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
33365 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
33366 + FM_PCD_CC_AD_TABLE_ALIGN);
33367 + if (!h_MissStatsCounters)
33368 + {
33369 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
33370 + XX_Free(p_IndxHashCcNodeParam);
33371 + XX_Free(p_ExactMatchCcNodeParam);
33372 + return NULL;
33373 + }
33374 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33375 +
33376 + /* Always enable statistics for 'miss', so that a statistics AD will be
33377 + initialized from the start. We'll store the requested 'statistics enable'
33378 + value and it will be used when statistics are read by the user. */
33379 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
33380 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
33381 + }
33382 +
33383 + /* Building exact-match node params, will be used to create the hash buckets */
33384 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33385 +
33386 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
33387 + e_FM_PCD_EXTRACT_FROM_KEY;
33388 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
33389 + e_FM_PCD_ACTION_EXACT_MATCH;
33390 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
33391 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
33392 + p_Param->matchKeySize;
33393 +
33394 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
33395 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
33396 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
33397 + p_Param->statisticsMode;
33398 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
33399 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
33400 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
33401 + p_Param->ccNextEngineParamsForMiss;
33402 +
33403 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
33404 +
33405 + for (i = 0; i < numOfSets; i++)
33406 + {
33407 + /* Each exact-match node will be marked as a 'bucket' and provided with
33408 + a pointer to statistics counters, to be used for 'miss' entry
33409 + statistics */
33410 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
33411 + if (!p_CcNode)
33412 + break;
33413 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
33414 +
33415 + p_CcNode->isHashBucket = TRUE;
33416 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
33417 +
33418 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
33419 + if (err)
33420 + break;
33421 +
33422 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
33423 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
33424 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
33425 + p_CcNode;
33426 + }
33427 +
33428 + if (i < numOfSets)
33429 + {
33430 + for (i = i - 1; i >= 0; i--)
33431 + FM_PCD_MatchTableDelete(
33432 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
33433 +
33434 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33435 +
33436 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
33437 + XX_Free(p_IndxHashCcNodeParam);
33438 + XX_Free(p_ExactMatchCcNodeParam);
33439 + return NULL;
33440 + }
33441 +
33442 + /* Creating indexed-hash CC node */
33443 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33444 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
33445 + e_FM_PCD_EXTRACT_FROM_HASH;
33446 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
33447 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
33448 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
33449 + p_Param->hashResMask;
33450 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
33451 + p_Param->hashShift;
33452 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
33453 +
33454 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
33455 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
33456 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
33457 + e_FM_PCD_CC_STATS_MODE_NONE;
33458 + /* Number of keys of this node is number of sets of the hash */
33459 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
33460 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
33461 +
33462 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
33463 +
33464 + if (p_CcNodeHashTbl)
33465 + {
33466 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
33467 +
33468 + /* Storing the allocated counters for buckets 'miss' in the hash table
33469 + and if statistics for miss were enabled. */
33470 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
33471 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
33472 + }
33473 +
33474 + XX_Free(p_IndxHashCcNodeParam);
33475 + XX_Free(p_ExactMatchCcNodeParam);
33476 +
33477 + return p_CcNodeHashTbl;
33478 +}
33479 +
33480 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
33481 +{
33482 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33483 + t_Handle h_FmPcd;
33484 + t_Handle *p_HashBuckets, h_MissStatsCounters;
33485 + uint16_t i, numOfBuckets;
33486 + t_Error err;
33487 +
33488 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33489 +
33490 + /* Store all hash buckets before the hash is freed */
33491 + numOfBuckets = p_HashTbl->numOfKeys;
33492 +
33493 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
33494 + if (!p_HashBuckets)
33495 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
33496 +
33497 + for (i = 0; i < numOfBuckets; i++)
33498 + p_HashBuckets[i] =
33499 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33500 +
33501 + h_FmPcd = p_HashTbl->h_FmPcd;
33502 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
33503 +
33504 + /* Free the hash */
33505 + err = FM_PCD_MatchTableDelete(p_HashTbl);
33506 +
33507 + /* Free each hash bucket */
33508 + for (i = 0; i < numOfBuckets; i++)
33509 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
33510 +
33511 + XX_Free(p_HashBuckets);
33512 +
33513 + /* Free statistics counters for 'miss', if these were allocated */
33514 + if (h_MissStatsCounters)
33515 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33516 +
33517 + if (err)
33518 + RETURN_ERROR(MAJOR, err, NO_MSG);
33519 +
33520 + return E_OK;
33521 +}
33522 +
33523 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
33524 + t_FmPcdCcKeyParams *p_KeyParams)
33525 +{
33526 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33527 + t_Handle h_HashBucket;
33528 + uint8_t bucketIndex;
33529 + uint16_t lastIndex;
33530 + t_Error err;
33531 +
33532 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33533 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33534 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
33535 +
33536 + if (p_KeyParams->p_Mask)
33537 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33538 + ("Keys masks not supported for hash table"));
33539 +
33540 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
33541 + p_KeyParams->p_Key,
33542 + p_HashTbl->kgHashShift,
33543 + &h_HashBucket, &bucketIndex,
33544 + &lastIndex);
33545 + if (err)
33546 + RETURN_ERROR(MAJOR, err, NO_MSG);
33547 +
33548 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
33549 + p_KeyParams);
33550 +}
33551 +
33552 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
33553 + uint8_t *p_Key)
33554 +{
33555 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33556 + t_Handle h_HashBucket;
33557 + uint8_t bucketIndex;
33558 + uint16_t lastIndex;
33559 + t_Error err;
33560 +
33561 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33562 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33563 +
33564 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33565 + p_HashTbl->kgHashShift,
33566 + &h_HashBucket, &bucketIndex,
33567 + &lastIndex);
33568 + if (err)
33569 + RETURN_ERROR(MAJOR, err, NO_MSG);
33570 +
33571 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
33572 +}
33573 +
33574 +t_Error FM_PCD_HashTableModifyNextEngine(
33575 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33576 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33577 +{
33578 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33579 + t_Handle h_HashBucket;
33580 + uint8_t bucketIndex;
33581 + uint16_t lastIndex;
33582 + t_Error err;
33583 +
33584 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33585 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33586 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33587 +
33588 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33589 + p_HashTbl->kgHashShift,
33590 + &h_HashBucket, &bucketIndex,
33591 + &lastIndex);
33592 + if (err)
33593 + RETURN_ERROR(MAJOR, err, NO_MSG);
33594 +
33595 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
33596 + NULL,
33597 + p_FmPcdCcNextEngineParams);
33598 +}
33599 +
33600 +t_Error FM_PCD_HashTableModifyMissNextEngine(
33601 + t_Handle h_HashTbl,
33602 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33603 +{
33604 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33605 + t_Handle h_HashBucket;
33606 + uint8_t i;
33607 + bool nullifyMissStats = FALSE;
33608 + t_Error err;
33609 +
33610 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
33611 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33612 +
33613 + if ((!p_HashTbl->h_MissStatsCounters)
33614 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33615 + RETURN_ERROR(
33616 + MAJOR,
33617 + E_CONFLICT,
33618 + ("Statistics are requested for a key, but statistics mode was set"
33619 + "to 'NONE' upon initialization"));
33620 +
33621 + if (p_HashTbl->h_MissStatsCounters)
33622 + {
33623 + if ((!p_HashTbl->statsEnForMiss)
33624 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33625 + nullifyMissStats = TRUE;
33626 +
33627 + if ((p_HashTbl->statsEnForMiss)
33628 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
33629 + {
33630 + p_HashTbl->statsEnForMiss = FALSE;
33631 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
33632 + }
33633 + }
33634 +
33635 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
33636 + {
33637 + h_HashBucket =
33638 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33639 +
33640 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
33641 + p_FmPcdCcNextEngineParams);
33642 + if (err)
33643 + RETURN_ERROR(MAJOR, err, NO_MSG);
33644 + }
33645 +
33646 + if (nullifyMissStats)
33647 + {
33648 + memset(p_HashTbl->h_MissStatsCounters, 0,
33649 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33650 + memset(p_HashTbl->h_MissStatsCounters, 0,
33651 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33652 + p_HashTbl->statsEnForMiss = TRUE;
33653 + }
33654 +
33655 + return E_OK;
33656 +}
33657 +
33658 +
33659 +t_Error FM_PCD_HashTableGetMissNextEngine(
33660 + t_Handle h_HashTbl,
33661 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33662 +{
33663 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33664 + t_FmPcdCcNode *p_HashBucket;
33665 +
33666 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33667 +
33668 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
33669 + p_HashBucket =
33670 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33671 +
33672 + memcpy(p_FmPcdCcNextEngineParams,
33673 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
33674 + sizeof(t_FmPcdCcNextEngineParams));
33675 +
33676 + return E_OK;
33677 +}
33678 +
33679 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
33680 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33681 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33682 +{
33683 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33684 + t_Handle h_HashBucket;
33685 + uint8_t bucketIndex;
33686 + uint16_t lastIndex;
33687 + t_Error err;
33688 +
33689 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33690 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33691 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33692 +
33693 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33694 + p_HashTbl->kgHashShift,
33695 + &h_HashBucket, &bucketIndex,
33696 + &lastIndex);
33697 + if (err)
33698 + RETURN_ERROR(MAJOR, err, NO_MSG);
33699 +
33700 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
33701 + NULL, p_KeyStatistics);
33702 +}
33703 +
33704 +t_Error FM_PCD_HashTableGetMissStatistics(
33705 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
33706 +{
33707 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33708 + t_Handle h_HashBucket;
33709 +
33710 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33711 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33712 +
33713 + if (!p_HashTbl->statsEnForMiss)
33714 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33715 + ("Statistics were not enabled for miss"));
33716 +
33717 + h_HashBucket =
33718 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
33719 +
33720 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
33721 +}
33722 --- /dev/null
33723 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
33724 @@ -0,0 +1,399 @@
33725 +/*
33726 + * Copyright 2008-2012 Freescale Semiconductor Inc.
33727 + *
33728 + * Redistribution and use in source and binary forms, with or without
33729 + * modification, are permitted provided that the following conditions are met:
33730 + * * Redistributions of source code must retain the above copyright
33731 + * notice, this list of conditions and the following disclaimer.
33732 + * * Redistributions in binary form must reproduce the above copyright
33733 + * notice, this list of conditions and the following disclaimer in the
33734 + * documentation and/or other materials provided with the distribution.
33735 + * * Neither the name of Freescale Semiconductor nor the
33736 + * names of its contributors may be used to endorse or promote products
33737 + * derived from this software without specific prior written permission.
33738 + *
33739 + *
33740 + * ALTERNATIVELY, this software may be distributed under the terms of the
33741 + * GNU General Public License ("GPL") as published by the Free Software
33742 + * Foundation, either version 2 of that License or (at your option) any
33743 + * later version.
33744 + *
33745 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
33746 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33747 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33748 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
33749 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33750 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33751 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33752 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33753 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33754 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33755 + */
33756 +
33757 +
33758 +/******************************************************************************
33759 + @File fm_cc.h
33760 +
33761 + @Description FM PCD CC ...
33762 +*//***************************************************************************/
33763 +#ifndef __FM_CC_H
33764 +#define __FM_CC_H
33765 +
33766 +#include "std_ext.h"
33767 +#include "error_ext.h"
33768 +#include "list_ext.h"
33769 +
33770 +#include "fm_pcd.h"
33771 +
33772 +
33773 +/***********************************************************************/
33774 +/* Coarse classification defines */
33775 +/***********************************************************************/
33776 +
33777 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
33778 +
33779 +#define CC_PC_FF_MACDST 0x00
33780 +#define CC_PC_FF_MACSRC 0x01
33781 +#define CC_PC_FF_ETYPE 0x02
33782 +
33783 +#define CC_PC_FF_TCI1 0x03
33784 +#define CC_PC_FF_TCI2 0x04
33785 +
33786 +#define CC_PC_FF_MPLS1 0x06
33787 +#define CC_PC_FF_MPLS_LAST 0x07
33788 +
33789 +#define CC_PC_FF_IPV4DST1 0x08
33790 +#define CC_PC_FF_IPV4DST2 0x16
33791 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
33792 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
33793 +#define CC_PC_FF_IPV4PTYPE1 0x0A
33794 +#define CC_PC_FF_IPV4PTYPE2 0x18
33795 +#define CC_PC_FF_IPV4SRC1 0x0b
33796 +#define CC_PC_FF_IPV4SRC2 0x19
33797 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
33798 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
33799 +#define CC_PC_FF_IPV4TTL 0x29
33800 +
33801 +
33802 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
33803 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
33804 +#define CC_PC_FF_IPV6PTYPE1 0x0e
33805 +#define CC_PC_FF_IPV6PTYPE2 0x1c
33806 +#define CC_PC_FF_IPV6DST1 0x0f
33807 +#define CC_PC_FF_IPV6DST2 0x1d
33808 +#define CC_PC_FF_IPV6SRC1 0x10
33809 +#define CC_PC_FF_IPV6SRC2 0x1e
33810 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
33811 +#define CC_PC_FF_IPPID 0x24
33812 +#define CC_PC_FF_IPDSCP 0x76
33813 +
33814 +#define CC_PC_FF_GREPTYPE 0x11
33815 +
33816 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
33817 +#define CC_PC_FF_MINENCAP_IPDST 0x13
33818 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
33819 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
33820 +
33821 +#define CC_PC_FF_L4PSRC 0x1f
33822 +#define CC_PC_FF_L4PDST 0x20
33823 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
33824 +
33825 +#define CC_PC_FF_PPPPID 0x05
33826 +
33827 +#define CC_PC_PR_SHIM1 0x22
33828 +#define CC_PC_PR_SHIM2 0x23
33829 +
33830 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
33831 +#define CC_PC_GENERIC_WITH_MASK 0x28
33832 +#define CC_PC_GENERIC_IC_GMASK 0x2B
33833 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
33834 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
33835 +
33836 +#define CC_PR_OFFSET 0x25
33837 +#define CC_PR_WITHOUT_OFFSET 0x26
33838 +
33839 +#define CC_PC_PR_ETH_OFFSET 19
33840 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
33841 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
33842 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
33843 +#define CC_PC_PR_VLAN1_OFFSET 21
33844 +#define CC_PC_PR_VLAN2_OFFSET 22
33845 +#define CC_PC_PR_PPPOE_OFFSET 24
33846 +#define CC_PC_PR_MPLS1_OFFSET 25
33847 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
33848 +#define CC_PC_PR_IP1_OFFSET 27
33849 +#define CC_PC_PR_IP_LAST_OFFSET 28
33850 +#define CC_PC_PR_MINENC_OFFSET 28
33851 +#define CC_PC_PR_L4_OFFSET 30
33852 +#define CC_PC_PR_GRE_OFFSET 29
33853 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
33854 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
33855 +
33856 +#define CC_PC_ILLEGAL 0xff
33857 +#define CC_SIZE_ILLEGAL 0
33858 +
33859 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
33860 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
33861 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
33862 +#define FM_PCD_CC_NUM_OF_KEYS 255
33863 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
33864 +
33865 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
33866 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
33867 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
33868 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
33869 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
33870 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
33871 +
33872 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
33873 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
33874 +
33875 +#define FM_PCD_AD_STATS_TYPE 0x40000000
33876 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
33877 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
33878 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
33879 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
33880 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
33881 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
33882 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
33883 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
33884 +
33885 +
33886 +
33887 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
33888 +
33889 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
33890 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
33891 +
33892 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
33893 +#if (DPAA_VERSION >= 11)
33894 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
33895 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
33896 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
33897 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
33898 +#endif /* (DPAA_VERSION >= 11) */
33899 +
33900 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
33901 +#define CC_GLBL_MASK_SIZE 4
33902 +#define CC_AGING_MASK_SIZE 4
33903 +
33904 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
33905 +
33906 +#define CC_PRIVATE_INFO_NONE 0
33907 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
33908 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
33909 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
33910 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
33911 +
33912 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
33913 +/***********************************************************************/
33914 +/* Memory map */
33915 +/***********************************************************************/
33916 +#if defined(__MWERKS__) && !defined(__GNUC__)
33917 +#pragma pack(push,1)
33918 +#endif /* defined(__MWERKS__) && ... */
33919 +
33920 +typedef struct
33921 +{
33922 + volatile uint32_t fqid;
33923 + volatile uint32_t plcrProfile;
33924 + volatile uint32_t nia;
33925 + volatile uint32_t res;
33926 +} t_AdOfTypeResult;
33927 +
33928 +typedef struct
33929 +{
33930 + volatile uint32_t ccAdBase;
33931 + volatile uint32_t matchTblPtr;
33932 + volatile uint32_t pcAndOffsets;
33933 + volatile uint32_t gmask;
33934 +} t_AdOfTypeContLookup;
33935 +
33936 +typedef struct
33937 +{
33938 + volatile uint32_t profileTableAddr;
33939 + volatile uint32_t reserved;
33940 + volatile uint32_t nextActionIndx;
33941 + volatile uint32_t statsTableAddr;
33942 +} t_AdOfTypeStats;
33943 +
33944 +typedef union
33945 +{
33946 + volatile t_AdOfTypeResult adResult;
33947 + volatile t_AdOfTypeContLookup adContLookup;
33948 +} t_Ad;
33949 +
33950 +#if defined(__MWERKS__) && !defined(__GNUC__)
33951 +#pragma pack(pop)
33952 +#endif /* defined(__MWERKS__) && ... */
33953 +
33954 +
33955 +/***********************************************************************/
33956 +/* Driver's internal structures */
33957 +/***********************************************************************/
33958 +
33959 +typedef struct t_FmPcdStatsObj
33960 +{
33961 + t_Handle h_StatsAd;
33962 + t_Handle h_StatsCounters;
33963 + t_List node;
33964 +} t_FmPcdStatsObj;
33965 +
33966 +typedef struct
33967 +{
33968 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
33969 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
33970 +
33971 + t_FmPcdCcNextEngineParams nextEngineParams;
33972 + uint32_t requiredAction;
33973 + uint32_t shadowAction;
33974 +
33975 + t_FmPcdStatsObj *p_StatsObj;
33976 +
33977 +} t_FmPcdCcKeyAndNextEngineParams;
33978 +
33979 +typedef struct
33980 +{
33981 + t_Handle p_Ad;
33982 + e_FmPcdEngine fmPcdEngine;
33983 + bool adAllocated;
33984 + bool isTree;
33985 +
33986 + uint32_t myInfo;
33987 + t_List *h_CcNextNodesLst;
33988 + t_Handle h_AdditionalInfo;
33989 + t_Handle h_Node;
33990 +} t_FmPcdModifyCcAdditionalParams;
33991 +
33992 +typedef struct
33993 +{
33994 + t_Handle p_AdTableNew;
33995 + t_Handle p_KeysMatchTableNew;
33996 + t_Handle p_AdTableOld;
33997 + t_Handle p_KeysMatchTableOld;
33998 + uint16_t numOfKeys;
33999 + t_Handle h_CurrentNode;
34000 + uint16_t savedKeyIndex;
34001 + t_Handle h_NodeForAdd;
34002 + t_Handle h_NodeForRmv;
34003 + t_Handle h_ManipForRmv;
34004 + t_Handle h_ManipForAdd;
34005 + t_FmPcdStatsObj *p_StatsObjForRmv;
34006 +#if (DPAA_VERSION >= 11)
34007 + t_Handle h_FrmReplicForAdd;
34008 + t_Handle h_FrmReplicForRmv;
34009 +#endif /* (DPAA_VERSION >= 11) */
34010 + bool tree;
34011 +
34012 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34013 +} t_FmPcdModifyCcKeyAdditionalParams;
34014 +
34015 +typedef struct
34016 +{
34017 + t_Handle h_Manip;
34018 + t_Handle h_CcNode;
34019 +} t_CcNextEngineInfo;
34020 +
34021 +typedef struct
34022 +{
34023 + uint16_t numOfKeys;
34024 + uint16_t maxNumOfKeys;
34025 +
34026 + bool maskSupport;
34027 + uint32_t keysMatchTableMaxSize;
34028 +
34029 + e_FmPcdCcStatsMode statisticsMode;
34030 + uint32_t numOfStatsFLRs;
34031 + uint32_t countersArraySize;
34032 +
34033 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
34034 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
34035 + Holds the statistics counters allocated by the hash table and
34036 + are shared by all hash table buckets; */
34037 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
34038 + Holds the statistics counters that were allocated for this node
34039 + and replaced by the shared counters (allocated by the hash table); */
34040 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
34041 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
34042 + returned statistics count to user, statistics AD always present for 'miss'
34043 + for all hash buckets; */
34044 + bool glblMaskUpdated;
34045 + t_Handle p_GlblMask;
34046 + bool lclMask;
34047 + uint8_t parseCode;
34048 + uint8_t offset;
34049 + uint8_t prsArrayOffset;
34050 + bool ctrlFlow;
34051 + uint16_t owners;
34052 +
34053 + uint8_t ccKeySizeAccExtraction;
34054 + uint8_t sizeOfExtraction;
34055 + uint8_t glblMaskSize;
34056 +
34057 + t_Handle h_KeysMatchTable;
34058 + t_Handle h_AdTable;
34059 + t_Handle h_StatsAds;
34060 + t_Handle h_TmpAd;
34061 + t_Handle h_Ad;
34062 + t_Handle h_StatsFLRs;
34063 +
34064 + t_List availableStatsLst;
34065 +
34066 + t_List ccPrevNodesLst;
34067 +
34068 + t_List ccTreeIdLst;
34069 + t_List ccTreesLst;
34070 +
34071 + t_Handle h_FmPcd;
34072 + uint32_t shadowAction;
34073 + uint8_t userSizeOfExtraction;
34074 + uint8_t userOffset;
34075 + uint8_t kgHashShift; /* used in hash-table */
34076 +
34077 + t_Handle h_Spinlock;
34078 +
34079 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34080 +} t_FmPcdCcNode;
34081 +
34082 +typedef struct
34083 +{
34084 + t_FmPcdCcNode *p_FmPcdCcNode;
34085 + bool occupied;
34086 + uint16_t owners;
34087 + volatile bool lock;
34088 +} t_FmPcdCcNodeArray;
34089 +
34090 +typedef struct
34091 +{
34092 + uint8_t numOfEntriesInGroup;
34093 + uint32_t totalBitsMask;
34094 + uint8_t baseGroupEntry;
34095 +} t_FmPcdCcGroupParam;
34096 +
34097 +typedef struct
34098 +{
34099 + t_Handle h_FmPcd;
34100 + uint8_t netEnvId;
34101 + uintptr_t ccTreeBaseAddr;
34102 + uint8_t numOfGrps;
34103 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34104 + t_List fmPortsLst;
34105 + t_FmPcdLock *p_Lock;
34106 + uint8_t numOfEntries;
34107 + uint16_t owners;
34108 + t_Handle h_FmPcdCcSavedManipParams;
34109 + bool modifiedState;
34110 + uint32_t requiredAction;
34111 + t_Handle h_IpReassemblyManip;
34112 + t_Handle h_CapwapReassemblyManip;
34113 +
34114 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34115 +} t_FmPcdCcTree;
34116 +
34117 +
34118 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
34119 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
34120 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
34121 +
34122 +
34123 +#endif /* __FM_CC_H */
34124 --- /dev/null
34125 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34126 @@ -0,0 +1,3242 @@
34127 +/*
34128 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34129 + *
34130 + * Redistribution and use in source and binary forms, with or without
34131 + * modification, are permitted provided that the following conditions are met:
34132 + * * Redistributions of source code must retain the above copyright
34133 + * notice, this list of conditions and the following disclaimer.
34134 + * * Redistributions in binary form must reproduce the above copyright
34135 + * notice, this list of conditions and the following disclaimer in the
34136 + * documentation and/or other materials provided with the distribution.
34137 + * * Neither the name of Freescale Semiconductor nor the
34138 + * names of its contributors may be used to endorse or promote products
34139 + * derived from this software without specific prior written permission.
34140 + *
34141 + *
34142 + * ALTERNATIVELY, this software may be distributed under the terms of the
34143 + * GNU General Public License ("GPL") as published by the Free Software
34144 + * Foundation, either version 2 of that License or (at your option) any
34145 + * later version.
34146 + *
34147 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34148 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34149 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34150 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34151 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34152 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34153 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34154 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34155 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34156 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34157 + */
34158 +
34159 +
34160 +/******************************************************************************
34161 + @File fm_kg.c
34162 +
34163 + @Description FM PCD ...
34164 +*//***************************************************************************/
34165 +#include "std_ext.h"
34166 +#include "error_ext.h"
34167 +#include "string_ext.h"
34168 +#include "debug_ext.h"
34169 +#include "net_ext.h"
34170 +#include "fm_port_ext.h"
34171 +
34172 +#include "fm_common.h"
34173 +#include "fm_pcd.h"
34174 +#include "fm_hc.h"
34175 +#include "fm_pcd_ipc.h"
34176 +#include "fm_kg.h"
34177 +#include "fsl_fman_kg.h"
34178 +
34179 +
34180 +/****************************************/
34181 +/* static functions */
34182 +/****************************************/
34183 +
34184 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
34185 +{
34186 + ASSERT_COND(h_FmPcdKg);
34187 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
34188 +}
34189 +
34190 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
34191 +{
34192 + ASSERT_COND(h_FmPcdKg);
34193 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
34194 +}
34195 +
34196 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
34197 +{
34198 + ASSERT_COND(h_Scheme);
34199 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34200 +}
34201 +
34202 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
34203 +{
34204 + ASSERT_COND(h_Scheme);
34205 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
34206 +}
34207 +
34208 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
34209 +{
34210 + ASSERT_COND(h_Scheme);
34211 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34212 +}
34213 +
34214 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
34215 +{
34216 + ASSERT_COND(h_Scheme);
34217 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34218 +}
34219 +
34220 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
34221 +{
34222 +
34223 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34224 +
34225 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
34226 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
34227 +
34228 + return E_OK;
34229 +}
34230 +
34231 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
34232 +{
34233 + int i;
34234 +
34235 + switch (code)
34236 + {
34237 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
34238 + case (KG_SCH_GEN_DEFAULT):
34239 + case (KG_SCH_GEN_NEXTHDR):
34240 + for (i=0 ; i<numOfSwDefaults ; i++)
34241 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
34242 + return swDefaults[i].dfltSelect;
34243 + break;
34244 + case (KG_SCH_GEN_SHIM1):
34245 + case (KG_SCH_GEN_SHIM2):
34246 + case (KG_SCH_GEN_IP_PID_NO_V):
34247 + case (KG_SCH_GEN_ETH_NO_V):
34248 + case (KG_SCH_GEN_SNAP_NO_V):
34249 + case (KG_SCH_GEN_VLAN1_NO_V):
34250 + case (KG_SCH_GEN_VLAN2_NO_V):
34251 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
34252 + case (KG_SCH_GEN_PPP_NO_V):
34253 + case (KG_SCH_GEN_MPLS1_NO_V):
34254 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
34255 + case (KG_SCH_GEN_L3_NO_V):
34256 + case (KG_SCH_GEN_IP2_NO_V):
34257 + case (KG_SCH_GEN_GRE_NO_V):
34258 + case (KG_SCH_GEN_L4_NO_V):
34259 + for (i=0 ; i<numOfSwDefaults ; i++)
34260 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
34261 + return swDefaults[i].dfltSelect;
34262 + break;
34263 + case (KG_SCH_GEN_START_OF_FRM):
34264 + case (KG_SCH_GEN_ETH):
34265 + case (KG_SCH_GEN_SNAP):
34266 + case (KG_SCH_GEN_VLAN1):
34267 + case (KG_SCH_GEN_VLAN2):
34268 + case (KG_SCH_GEN_ETH_TYPE):
34269 + case (KG_SCH_GEN_PPP):
34270 + case (KG_SCH_GEN_MPLS1):
34271 + case (KG_SCH_GEN_MPLS2):
34272 + case (KG_SCH_GEN_MPLS3):
34273 + case (KG_SCH_GEN_MPLS_LAST):
34274 + case (KG_SCH_GEN_IPV4):
34275 + case (KG_SCH_GEN_IPV6):
34276 + case (KG_SCH_GEN_IPV4_TUNNELED):
34277 + case (KG_SCH_GEN_IPV6_TUNNELED):
34278 + case (KG_SCH_GEN_MIN_ENCAP):
34279 + case (KG_SCH_GEN_GRE):
34280 + case (KG_SCH_GEN_TCP):
34281 + case (KG_SCH_GEN_UDP):
34282 + case (KG_SCH_GEN_IPSEC_AH):
34283 + case (KG_SCH_GEN_SCTP):
34284 + case (KG_SCH_GEN_DCCP):
34285 + case (KG_SCH_GEN_IPSEC_ESP):
34286 + for (i=0 ; i<numOfSwDefaults ; i++)
34287 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
34288 + return swDefaults[i].dfltSelect;
34289 + break;
34290 + default:
34291 + break;
34292 + }
34293 +
34294 + return e_FM_PCD_KG_DFLT_ILLEGAL;
34295 +}
34296 +
34297 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
34298 +{
34299 + *p_Offset = 0;
34300 +
34301 + switch (src)
34302 + {
34303 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
34304 + return KG_SCH_GEN_START_OF_FRM;
34305 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
34306 + return KG_SCH_GEN_DEFAULT;
34307 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
34308 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34309 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
34310 + *p_Offset = 32;
34311 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34312 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
34313 + return KG_SCH_GEN_NEXTHDR;
34314 + default:
34315 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
34316 + return 0;
34317 + }
34318 +}
34319 +
34320 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
34321 +{
34322 + if (!ignoreProtocolValidation)
34323 + switch (hdr)
34324 + {
34325 + case (HEADER_TYPE_NONE):
34326 + ASSERT_COND(FALSE);
34327 + case (HEADER_TYPE_ETH):
34328 + return KG_SCH_GEN_ETH;
34329 + case (HEADER_TYPE_LLC_SNAP):
34330 + return KG_SCH_GEN_SNAP;
34331 + case (HEADER_TYPE_PPPoE):
34332 + return KG_SCH_GEN_PPP;
34333 + case (HEADER_TYPE_MPLS):
34334 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34335 + return KG_SCH_GEN_MPLS1;
34336 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
34337 + return KG_SCH_GEN_MPLS2;
34338 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
34339 + return KG_SCH_GEN_MPLS3;
34340 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34341 + return KG_SCH_GEN_MPLS_LAST;
34342 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34343 + return 0;
34344 + case (HEADER_TYPE_IPv4):
34345 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34346 + return KG_SCH_GEN_IPV4;
34347 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34348 + return KG_SCH_GEN_IPV4_TUNNELED;
34349 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
34350 + return 0;
34351 + case (HEADER_TYPE_IPv6):
34352 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34353 + return KG_SCH_GEN_IPV6;
34354 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34355 + return KG_SCH_GEN_IPV6_TUNNELED;
34356 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
34357 + return 0;
34358 + case (HEADER_TYPE_GRE):
34359 + return KG_SCH_GEN_GRE;
34360 + case (HEADER_TYPE_TCP):
34361 + return KG_SCH_GEN_TCP;
34362 + case (HEADER_TYPE_UDP):
34363 + return KG_SCH_GEN_UDP;
34364 + case (HEADER_TYPE_IPSEC_AH):
34365 + return KG_SCH_GEN_IPSEC_AH;
34366 + case (HEADER_TYPE_IPSEC_ESP):
34367 + return KG_SCH_GEN_IPSEC_ESP;
34368 + case (HEADER_TYPE_SCTP):
34369 + return KG_SCH_GEN_SCTP;
34370 + case (HEADER_TYPE_DCCP):
34371 + return KG_SCH_GEN_DCCP;
34372 + default:
34373 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34374 + return 0;
34375 + }
34376 + else
34377 + switch (hdr)
34378 + {
34379 + case (HEADER_TYPE_NONE):
34380 + ASSERT_COND(FALSE);
34381 + case (HEADER_TYPE_ETH):
34382 + return KG_SCH_GEN_ETH_NO_V;
34383 + case (HEADER_TYPE_LLC_SNAP):
34384 + return KG_SCH_GEN_SNAP_NO_V;
34385 + case (HEADER_TYPE_PPPoE):
34386 + return KG_SCH_GEN_PPP_NO_V;
34387 + case (HEADER_TYPE_MPLS):
34388 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34389 + return KG_SCH_GEN_MPLS1_NO_V;
34390 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34391 + return KG_SCH_GEN_MPLS_LAST_NO_V;
34392 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
34393 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
34394 + else
34395 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34396 + return 0;
34397 + case (HEADER_TYPE_IPv4):
34398 + case (HEADER_TYPE_IPv6):
34399 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34400 + return KG_SCH_GEN_L3_NO_V;
34401 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34402 + return KG_SCH_GEN_IP2_NO_V;
34403 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
34404 + case (HEADER_TYPE_MINENCAP):
34405 + return KG_SCH_GEN_IP2_NO_V;
34406 + case (HEADER_TYPE_USER_DEFINED_L3):
34407 + return KG_SCH_GEN_L3_NO_V;
34408 + case (HEADER_TYPE_GRE):
34409 + return KG_SCH_GEN_GRE_NO_V;
34410 + case (HEADER_TYPE_TCP):
34411 + case (HEADER_TYPE_UDP):
34412 + case (HEADER_TYPE_IPSEC_AH):
34413 + case (HEADER_TYPE_IPSEC_ESP):
34414 + case (HEADER_TYPE_SCTP):
34415 + case (HEADER_TYPE_DCCP):
34416 + return KG_SCH_GEN_L4_NO_V;
34417 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
34418 + return KG_SCH_GEN_SHIM1;
34419 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
34420 + return KG_SCH_GEN_SHIM2;
34421 + default:
34422 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34423 + return 0;
34424 + }
34425 +}
34426 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
34427 +{
34428 + if (!ignoreProtocolValidation)
34429 + switch (hdr)
34430 + {
34431 + case (HEADER_TYPE_NONE):
34432 + ASSERT_COND(FALSE);
34433 + break;
34434 + case (HEADER_TYPE_ETH):
34435 + switch (field.eth)
34436 + {
34437 + case (NET_HEADER_FIELD_ETH_TYPE):
34438 + return KG_SCH_GEN_ETH_TYPE;
34439 + default:
34440 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34441 + return 0;
34442 + }
34443 + break;
34444 + case (HEADER_TYPE_VLAN):
34445 + switch (field.vlan)
34446 + {
34447 + case (NET_HEADER_FIELD_VLAN_TCI):
34448 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34449 + return KG_SCH_GEN_VLAN1;
34450 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34451 + return KG_SCH_GEN_VLAN2;
34452 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34453 + return 0;
34454 + }
34455 + break;
34456 + case (HEADER_TYPE_MPLS):
34457 + case (HEADER_TYPE_IPSEC_AH):
34458 + case (HEADER_TYPE_IPSEC_ESP):
34459 + case (HEADER_TYPE_LLC_SNAP):
34460 + case (HEADER_TYPE_PPPoE):
34461 + case (HEADER_TYPE_IPv4):
34462 + case (HEADER_TYPE_IPv6):
34463 + case (HEADER_TYPE_GRE):
34464 + case (HEADER_TYPE_MINENCAP):
34465 + case (HEADER_TYPE_USER_DEFINED_L3):
34466 + case (HEADER_TYPE_TCP):
34467 + case (HEADER_TYPE_UDP):
34468 + case (HEADER_TYPE_SCTP):
34469 + case (HEADER_TYPE_DCCP):
34470 + case (HEADER_TYPE_USER_DEFINED_L4):
34471 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34472 + return 0;
34473 + default:
34474 + break;
34475 +
34476 + }
34477 + else
34478 + switch (hdr)
34479 + {
34480 + case (HEADER_TYPE_NONE):
34481 + ASSERT_COND(FALSE);
34482 + break;
34483 + case (HEADER_TYPE_ETH):
34484 + switch (field.eth)
34485 + {
34486 + case (NET_HEADER_FIELD_ETH_TYPE):
34487 + return KG_SCH_GEN_ETH_TYPE_NO_V;
34488 + default:
34489 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34490 + return 0;
34491 + }
34492 + break;
34493 + case (HEADER_TYPE_VLAN):
34494 + switch (field.vlan)
34495 + {
34496 + case (NET_HEADER_FIELD_VLAN_TCI) :
34497 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34498 + return KG_SCH_GEN_VLAN1_NO_V;
34499 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34500 + return KG_SCH_GEN_VLAN2_NO_V;
34501 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34502 + return 0;
34503 + }
34504 + break;
34505 + case (HEADER_TYPE_IPv4):
34506 + switch (field.ipv4)
34507 + {
34508 + case (NET_HEADER_FIELD_IPv4_PROTO):
34509 + return KG_SCH_GEN_IP_PID_NO_V;
34510 + default:
34511 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34512 + return 0;
34513 + }
34514 + break;
34515 + case (HEADER_TYPE_IPv6):
34516 + switch (field.ipv6)
34517 + {
34518 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34519 + return KG_SCH_GEN_IP_PID_NO_V;
34520 + default:
34521 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34522 + return 0;
34523 + }
34524 + break;
34525 + case (HEADER_TYPE_MPLS):
34526 + case (HEADER_TYPE_LLC_SNAP):
34527 + case (HEADER_TYPE_PPPoE):
34528 + case (HEADER_TYPE_GRE):
34529 + case (HEADER_TYPE_MINENCAP):
34530 + case (HEADER_TYPE_USER_DEFINED_L3):
34531 + case (HEADER_TYPE_TCP):
34532 + case (HEADER_TYPE_UDP):
34533 + case (HEADER_TYPE_IPSEC_AH):
34534 + case (HEADER_TYPE_IPSEC_ESP):
34535 + case (HEADER_TYPE_SCTP):
34536 + case (HEADER_TYPE_DCCP):
34537 + case (HEADER_TYPE_USER_DEFINED_L4):
34538 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34539 + return 0;
34540 + default:
34541 + break;
34542 + }
34543 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
34544 + return 0;
34545 +}
34546 +
34547 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
34548 +{
34549 + UNUSED(p_FmPcd);
34550 +
34551 + switch (hdr)
34552 + {
34553 + case (HEADER_TYPE_NONE):
34554 + ASSERT_COND(FALSE);
34555 + break;
34556 + case (HEADER_TYPE_ETH):
34557 + switch (field.eth)
34558 + {
34559 + case (NET_HEADER_FIELD_ETH_DA):
34560 + return KG_SCH_KN_MACDST;
34561 + case (NET_HEADER_FIELD_ETH_SA):
34562 + return KG_SCH_KN_MACSRC;
34563 + case (NET_HEADER_FIELD_ETH_TYPE):
34564 + return KG_SCH_KN_ETYPE;
34565 + default:
34566 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34567 + return 0;
34568 + }
34569 + case (HEADER_TYPE_LLC_SNAP):
34570 + switch (field.llcSnap)
34571 + {
34572 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
34573 + return KG_SCH_KN_ETYPE;
34574 + default:
34575 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34576 + return 0;
34577 + }
34578 + case (HEADER_TYPE_VLAN):
34579 + switch (field.vlan)
34580 + {
34581 + case (NET_HEADER_FIELD_VLAN_TCI):
34582 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34583 + return KG_SCH_KN_TCI1;
34584 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34585 + return KG_SCH_KN_TCI2;
34586 + else
34587 + {
34588 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34589 + return 0;
34590 + }
34591 + default:
34592 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34593 + return 0;
34594 + }
34595 + case (HEADER_TYPE_MPLS):
34596 + switch (field.mpls)
34597 + {
34598 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
34599 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34600 + return KG_SCH_KN_MPLS1;
34601 + if (index == e_FM_PCD_HDR_INDEX_2)
34602 + return KG_SCH_KN_MPLS2;
34603 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34604 + return KG_SCH_KN_MPLS_LAST;
34605 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
34606 + return 0;
34607 + default:
34608 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34609 + return 0;
34610 + }
34611 + case (HEADER_TYPE_IPv4):
34612 + switch (field.ipv4)
34613 + {
34614 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
34615 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34616 + return KG_SCH_KN_IPSRC1;
34617 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34618 + return KG_SCH_KN_IPSRC2;
34619 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34620 + return 0;
34621 + case (NET_HEADER_FIELD_IPv4_DST_IP):
34622 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34623 + return KG_SCH_KN_IPDST1;
34624 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34625 + return KG_SCH_KN_IPDST2;
34626 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34627 + return 0;
34628 + case (NET_HEADER_FIELD_IPv4_PROTO):
34629 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34630 + return KG_SCH_KN_PTYPE1;
34631 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34632 + return KG_SCH_KN_PTYPE2;
34633 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34634 + return 0;
34635 + case (NET_HEADER_FIELD_IPv4_TOS):
34636 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34637 + return KG_SCH_KN_IPTOS_TC1;
34638 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34639 + return KG_SCH_KN_IPTOS_TC2;
34640 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34641 + return 0;
34642 + default:
34643 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34644 + return 0;
34645 + }
34646 + case (HEADER_TYPE_IPv6):
34647 + switch (field.ipv6)
34648 + {
34649 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
34650 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34651 + return KG_SCH_KN_IPSRC1;
34652 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34653 + return KG_SCH_KN_IPSRC2;
34654 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34655 + return 0;
34656 + case (NET_HEADER_FIELD_IPv6_DST_IP):
34657 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34658 + return KG_SCH_KN_IPDST1;
34659 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34660 + return KG_SCH_KN_IPDST2;
34661 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34662 + return 0;
34663 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34664 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34665 + return KG_SCH_KN_PTYPE1;
34666 + if (index == e_FM_PCD_HDR_INDEX_2)
34667 + return KG_SCH_KN_PTYPE2;
34668 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34669 +#ifdef FM_KG_NO_IPPID_SUPPORT
34670 + if (p_FmPcd->fmRevInfo.majorRev < 6)
34671 + return KG_SCH_KN_PTYPE2;
34672 +#endif /* FM_KG_NO_IPPID_SUPPORT */
34673 + return KG_SCH_KN_IPPID;
34674 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34675 + return 0;
34676 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
34677 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34678 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
34679 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34680 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
34681 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34682 + return 0;
34683 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
34684 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34685 + return KG_SCH_KN_IPTOS_TC1;
34686 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34687 + return KG_SCH_KN_IPTOS_TC2;
34688 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34689 + return 0;
34690 + case (NET_HEADER_FIELD_IPv6_FL):
34691 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34692 + return KG_SCH_KN_IPV6FL1;
34693 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34694 + return KG_SCH_KN_IPV6FL2;
34695 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
34696 + return 0;
34697 + default:
34698 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34699 + return 0;
34700 + }
34701 + case (HEADER_TYPE_GRE):
34702 + switch (field.gre)
34703 + {
34704 + case (NET_HEADER_FIELD_GRE_TYPE):
34705 + return KG_SCH_KN_GREPTYPE;
34706 + default:
34707 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34708 + return 0;
34709 + }
34710 + case (HEADER_TYPE_MINENCAP):
34711 + switch (field.minencap)
34712 + {
34713 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
34714 + return KG_SCH_KN_IPSRC2;
34715 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
34716 + return KG_SCH_KN_IPDST2;
34717 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
34718 + return KG_SCH_KN_PTYPE2;
34719 + default:
34720 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34721 + return 0;
34722 + }
34723 + case (HEADER_TYPE_TCP):
34724 + switch (field.tcp)
34725 + {
34726 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
34727 + return KG_SCH_KN_L4PSRC;
34728 + case (NET_HEADER_FIELD_TCP_PORT_DST):
34729 + return KG_SCH_KN_L4PDST;
34730 + case (NET_HEADER_FIELD_TCP_FLAGS):
34731 + return KG_SCH_KN_TFLG;
34732 + default:
34733 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34734 + return 0;
34735 + }
34736 + case (HEADER_TYPE_UDP):
34737 + switch (field.udp)
34738 + {
34739 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
34740 + return KG_SCH_KN_L4PSRC;
34741 + case (NET_HEADER_FIELD_UDP_PORT_DST):
34742 + return KG_SCH_KN_L4PDST;
34743 + default:
34744 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34745 + return 0;
34746 + }
34747 + case (HEADER_TYPE_IPSEC_AH):
34748 + switch (field.ipsecAh)
34749 + {
34750 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
34751 + return KG_SCH_KN_IPSEC_SPI;
34752 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
34753 + return KG_SCH_KN_IPSEC_NH;
34754 + default:
34755 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34756 + return 0;
34757 + }
34758 + case (HEADER_TYPE_IPSEC_ESP):
34759 + switch (field.ipsecEsp)
34760 + {
34761 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
34762 + return KG_SCH_KN_IPSEC_SPI;
34763 + default:
34764 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34765 + return 0;
34766 + }
34767 + case (HEADER_TYPE_SCTP):
34768 + switch (field.sctp)
34769 + {
34770 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
34771 + return KG_SCH_KN_L4PSRC;
34772 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
34773 + return KG_SCH_KN_L4PDST;
34774 + default:
34775 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34776 + return 0;
34777 + }
34778 + case (HEADER_TYPE_DCCP):
34779 + switch (field.dccp)
34780 + {
34781 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
34782 + return KG_SCH_KN_L4PSRC;
34783 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
34784 + return KG_SCH_KN_L4PDST;
34785 + default:
34786 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34787 + return 0;
34788 + }
34789 + case (HEADER_TYPE_PPPoE):
34790 + switch (field.pppoe)
34791 + {
34792 + case (NET_HEADER_FIELD_PPPoE_PID):
34793 + return KG_SCH_KN_PPPID;
34794 + case (NET_HEADER_FIELD_PPPoE_SID):
34795 + return KG_SCH_KN_PPPSID;
34796 + default:
34797 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34798 + return 0;
34799 + }
34800 + default:
34801 + break;
34802 +
34803 + }
34804 +
34805 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34806 + return 0;
34807 +}
34808 +
34809 +
34810 +static uint8_t GetKnownFieldId(uint32_t bitMask)
34811 +{
34812 + uint8_t cnt = 0;
34813 +
34814 + while (bitMask)
34815 + if (bitMask & 0x80000000)
34816 + break;
34817 + else
34818 + {
34819 + cnt++;
34820 + bitMask <<= 1;
34821 + }
34822 + return cnt;
34823 +
34824 +}
34825 +
34826 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
34827 +{
34828 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
34829 +
34830 + /* bitOffset 1-7 --> mask 0x1-0x7F */
34831 + if (bitOffset<8)
34832 + {
34833 + mask = 0;
34834 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
34835 + mask |= walking1Mask;
34836 + }
34837 + else
34838 + {
34839 + mask = 0xFF;
34840 + numOfOnesToClear = 0;
34841 + if (fqid && bitOffset>24)
34842 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
34843 + numOfOnesToClear = (uint8_t)(bitOffset-24);
34844 + else
34845 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
34846 + if (!fqid && bitOffset>8)
34847 + numOfOnesToClear = (uint8_t)(bitOffset-8);
34848 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
34849 + mask &= ~walking1Mask;
34850 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
34851 + }
34852 + return mask;
34853 +}
34854 +
34855 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
34856 +{
34857 + t_FmPcdKg *p_FmPcdKg;
34858 + t_FmPcdKgScheme *p_Scheme;
34859 + uint32_t intFlags;
34860 + uint8_t relativeSchemeId;
34861 + int i;
34862 +
34863 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
34864 +
34865 + /* for each scheme - update owners counters */
34866 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
34867 + {
34868 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
34869 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
34870 +
34871 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
34872 +
34873 + /* increment owners number */
34874 + intFlags = KgSchemeLock(p_Scheme);
34875 + p_Scheme->owners++;
34876 + KgSchemeUnlock(p_Scheme, intFlags);
34877 + }
34878 +}
34879 +
34880 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
34881 +{
34882 + t_FmPcdKg *p_FmPcdKg;
34883 + t_FmPcdKgScheme *p_Scheme;
34884 + uint32_t intFlags;
34885 + uint8_t relativeSchemeId;
34886 + int i;
34887 +
34888 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
34889 +
34890 + /* for each scheme - update owners counters */
34891 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
34892 + {
34893 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
34894 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
34895 +
34896 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
34897 +
34898 + /* increment owners number */
34899 + ASSERT_COND(p_Scheme->owners);
34900 + intFlags = KgSchemeLock(p_Scheme);
34901 + p_Scheme->owners--;
34902 + KgSchemeUnlock(p_Scheme, intFlags);
34903 + }
34904 +}
34905 +
34906 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
34907 +{
34908 + /* this routine is locked by the calling routine */
34909 + ASSERT_COND(p_Scheme);
34910 + ASSERT_COND(p_Scheme->valid);
34911 +
34912 + if (set)
34913 + p_Scheme->requiredActionFlag = TRUE;
34914 + else
34915 + {
34916 + p_Scheme->requiredAction = 0;
34917 + p_Scheme->requiredActionFlag = FALSE;
34918 + }
34919 +}
34920 +
34921 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
34922 +{
34923 + struct fman_kg_regs *p_KgRegs;
34924 +
34925 + uint32_t tmpKgarReg = 0, intFlags;
34926 + t_Error err = E_OK;
34927 +
34928 + /* The calling routine had locked the port, so for each port only one core can access
34929 + * (so we don't need a lock here) */
34930 +
34931 + if (p_FmPcd->h_Hc)
34932 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
34933 +
34934 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34935 +
34936 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
34937 + /* lock a common KG reg */
34938 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
34939 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
34940 + if (err)
34941 + {
34942 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
34943 + RETURN_ERROR(MINOR, err, NO_MSG);
34944 + }
34945 +
34946 + fman_kg_write_sp(p_KgRegs, spReg, add);
34947 +
34948 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
34949 +
34950 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
34951 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
34952 + return err;
34953 +}
34954 +
34955 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
34956 +{
34957 + struct fman_kg_regs *p_KgRegs;
34958 + uint32_t tmpKgarReg, intFlags;
34959 + t_Error err;
34960 +
34961 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34962 +
34963 + if (p_FmPcd->h_Hc)
34964 + {
34965 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
34966 + return err;
34967 + }
34968 +
34969 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
34970 + fman_kg_write_cpp(p_KgRegs, cppReg);
34971 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
34972 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
34973 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
34974 +
34975 + return err;
34976 +}
34977 +
34978 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
34979 +{
34980 + uint32_t tmpKgpeCpp;
34981 +
34982 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
34983 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
34984 +
34985 + return tmpKgpeCpp;
34986 +}
34987 +
34988 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
34989 +{
34990 + uint32_t tmpKgpeCpp = 0;
34991 +
34992 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
34993 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
34994 +}
34995 +
34996 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
34997 +{
34998 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
34999 +}
35000 +
35001 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
35002 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
35003 +{
35004 + return (uint32_t)(FM_KG_KGAR_GO |
35005 + FM_KG_KGAR_READ |
35006 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
35007 + DUMMY_PORT_ID |
35008 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
35009 + FM_PCD_KG_KGAR_WSEL_MASK);
35010 +
35011 + /* if we ever want to write 1 by 1, use:
35012 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
35013 + */
35014 +}
35015 +#endif /* (defined(DEBUG_ERRORS) && ... */
35016 +
35017 +static void PcdKgErrorException(t_Handle h_FmPcd)
35018 +{
35019 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
35020 + uint32_t event,schemeIndexes = 0, index = 0;
35021 + struct fman_kg_regs *p_KgRegs;
35022 +
35023 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
35024 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35025 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
35026 +
35027 + if (event & FM_EX_KG_DOUBLE_ECC)
35028 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
35029 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
35030 + {
35031 + if (schemeIndexes)
35032 + {
35033 + while (schemeIndexes)
35034 + {
35035 + if (schemeIndexes & 0x1)
35036 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
35037 + schemeIndexes >>= 1;
35038 + index+=1;
35039 + }
35040 + }
35041 + else /* this should happen only when interrupt is forced. */
35042 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
35043 + }
35044 +}
35045 +
35046 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
35047 +{
35048 + t_Error err = E_OK;
35049 + t_FmPcdIpcKgSchemesParams kgAlloc;
35050 + uint32_t replyLength;
35051 + t_FmPcdIpcReply reply;
35052 + t_FmPcdIpcMsg msg;
35053 +
35054 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
35055 +
35056 + /* in GUEST_PARTITION, we use the IPC */
35057 + memset(&reply, 0, sizeof(reply));
35058 + memset(&msg, 0, sizeof(msg));
35059 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
35060 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
35061 + kgAlloc.guestId = p_FmPcd->guestId;
35062 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
35063 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
35064 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
35065 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
35066 + (uint8_t*)&msg,
35067 + sizeof(msg.msgId) + sizeof(kgAlloc),
35068 + (uint8_t*)&reply,
35069 + &replyLength,
35070 + NULL,
35071 + NULL)) != E_OK)
35072 + RETURN_ERROR(MAJOR, err, NO_MSG);
35073 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
35074 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
35075 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
35076 +
35077 + return (t_Error)reply.error;
35078 +}
35079 +
35080 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
35081 +{
35082 + t_Error err = E_OK;
35083 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35084 +
35085 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
35086 +
35087 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
35088 + FmEnableRamsEcc(p_FmPcd->h_Fm);
35089 +
35090 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
35091 +
35092 + /* register even if no interrupts enabled, to allow future enablement */
35093 + FmRegisterIntr(p_FmPcd->h_Fm,
35094 + e_FM_MOD_KG,
35095 + 0,
35096 + e_FM_INTR_TYPE_ERR,
35097 + PcdKgErrorException,
35098 + p_FmPcd);
35099 +
35100 + fman_kg_enable_scheme_interrupts(p_Regs);
35101 +
35102 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
35103 + {
35104 + err = FmPcdKgAllocSchemes(p_FmPcd,
35105 + p_FmPcd->p_FmPcdKg->numOfSchemes,
35106 + p_FmPcd->guestId,
35107 + p_FmPcd->p_FmPcdKg->schemesIds);
35108 + if (err)
35109 + RETURN_ERROR(MINOR, err, NO_MSG);
35110 + }
35111 +
35112 + return E_OK;
35113 +}
35114 +
35115 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35116 +{
35117 + ASSERT_COND(!p_Scheme->valid);
35118 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35119 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35120 + p_Scheme->valid = TRUE;
35121 +}
35122 +
35123 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35124 +{
35125 + if (p_Scheme->owners)
35126 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
35127 +
35128 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35129 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35130 + p_Scheme->valid = FALSE;
35131 +
35132 + return E_OK;
35133 +}
35134 +
35135 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
35136 + t_FmPcdKgSchemeParams *p_SchemeParams,
35137 + struct fman_kg_scheme_regs *p_SchemeRegs)
35138 +{
35139 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
35140 + uint32_t grpBits = 0;
35141 + uint8_t grpBase;
35142 + bool direct=TRUE, absolute=FALSE;
35143 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
35144 + t_Error err = E_OK;
35145 + int i = 0;
35146 + t_NetEnvParams netEnvParams;
35147 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
35148 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
35149 + uint8_t j, curr, idx;
35150 + uint8_t id, shift=0, code=0, offset=0, size=0;
35151 + t_FmPcdExtractEntry *p_Extract = NULL;
35152 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
35153 + bool generic = FALSE;
35154 + t_KnownFieldsMasks bitMask;
35155 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
35156 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
35157 + uint8_t numOfSwDefaults = 0;
35158 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
35159 + uint8_t currGenId = 0;
35160 +
35161 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
35162 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
35163 +
35164 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
35165 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35166 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
35167 +
35168 + /* by netEnv parameters, get match vector */
35169 + if (!p_SchemeParams->alwaysDirect)
35170 + {
35171 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
35172 + netEnvParams.netEnvId = p_Scheme->netEnvId;
35173 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
35174 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
35175 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
35176 + if (err)
35177 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
35178 + p_Scheme->matchVector = netEnvParams.vector;
35179 + }
35180 + else
35181 + {
35182 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
35183 + p_Scheme->netEnvId = ILLEGAL_NETENV;
35184 + }
35185 +
35186 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
35187 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
35188 +
35189 + if (p_SchemeParams->bypassFqidGeneration)
35190 + {
35191 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
35192 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35193 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
35194 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
35195 + if (p_SchemeParams->baseFqid)
35196 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
35197 + }
35198 + else
35199 + if (!p_SchemeParams->baseFqid)
35200 + DBG(WARNING, ("baseFqid is 0."));
35201 +
35202 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
35203 + {
35204 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
35205 + p_Scheme->directPlcr = direct;
35206 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
35207 + if (!direct && absolute)
35208 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
35209 +
35210 + if (direct)
35211 + {
35212 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
35213 + numOfProfiles = 1;
35214 + }
35215 + else
35216 + {
35217 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35218 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35219 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35220 + }
35221 + }
35222 +
35223 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
35224 + {
35225 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
35226 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35227 + {
35228 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35229 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
35230 + }
35231 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
35232 +
35233 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
35234 + p_SchemeParams->kgNextEngineParams.cc.grpId,
35235 + &grpBits,
35236 + &grpBase);
35237 + if (err)
35238 + RETURN_ERROR(MAJOR, err, NO_MSG);
35239 + p_Scheme->ccUnits = grpBits;
35240 +
35241 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35242 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35243 + {
35244 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
35245 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
35246 + absolute = FALSE;
35247 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
35248 + if (direct)
35249 + {
35250 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
35251 + numOfProfiles = 1;
35252 + }
35253 + else
35254 + {
35255 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35256 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35257 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35258 + }
35259 + }
35260 + }
35261 +
35262 + /* if policer is used directly after KG, or after CC */
35263 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
35264 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
35265 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35266 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
35267 + {
35268 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
35269 + if (absolute)
35270 + {
35271 + /* for absolute direct policy only, */
35272 + relativeProfileId = profileId;
35273 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
35274 + if (err)
35275 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
35276 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
35277 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
35278 + p_Scheme->relativeProfileId = profileId;
35279 + }
35280 + else
35281 + {
35282 + /* save relative profile id's for later check */
35283 + p_Scheme->nextRelativePlcrProfile = TRUE;
35284 + p_Scheme->relativeProfileId = profileId;
35285 + p_Scheme->numOfProfiles = numOfProfiles;
35286 + }
35287 + }
35288 + else
35289 + {
35290 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
35291 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
35292 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
35293 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35294 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
35295 + if (p_SchemeParams->bypassFqidGeneration &&
35296 + p_SchemeParams->useHash &&
35297 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
35298 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35299 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
35300 + }
35301 +
35302 + /* configure all 21 scheme registers */
35303 + tmpReg = KG_SCH_MODE_EN;
35304 + switch (p_SchemeParams->nextEngine)
35305 + {
35306 + case (e_FM_PCD_PLCR):
35307 + /* add to mode register - NIA */
35308 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
35309 + tmpReg |= NIA_ENG_PLCR;
35310 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
35311 + /* initialize policer profile command - */
35312 + /* configure kgse_ppc */
35313 + if (direct)
35314 + /* use profileId as base, other fields are 0 */
35315 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35316 + else
35317 + {
35318 + if (shift > MAX_PP_SHIFT)
35319 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35320 +
35321 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35322 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35323 +
35324 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35325 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35326 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35327 + ppcTmp |= (uint32_t)profileId;
35328 +
35329 + p_SchemeRegs->kgse_ppc = ppcTmp;
35330 + }
35331 + break;
35332 + case (e_FM_PCD_CC):
35333 + /* mode reg - define NIA */
35334 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
35335 +
35336 + p_SchemeRegs->kgse_ccbs = grpBits;
35337 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
35338 +
35339 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
35340 + {
35341 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
35342 + {
35343 + /* find out if absolute or relative */
35344 + if (absolute)
35345 + 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"));
35346 + if (direct)
35347 + {
35348 + /* mask = 0, base = directProfileId */
35349 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35350 + }
35351 + else
35352 + {
35353 + if (shift > MAX_PP_SHIFT)
35354 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35355 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35356 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35357 +
35358 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35359 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35360 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35361 + ppcTmp |= (uint32_t)profileId;
35362 +
35363 + p_SchemeRegs->kgse_ppc = ppcTmp;
35364 + }
35365 + }
35366 + }
35367 + break;
35368 + case (e_FM_PCD_DONE):
35369 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
35370 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
35371 + else
35372 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
35373 + break;
35374 + default:
35375 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
35376 + }
35377 + p_SchemeRegs->kgse_mode = tmpReg;
35378 +
35379 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
35380 +
35381 +#if (DPAA_VERSION >= 11)
35382 + if (p_SchemeParams->overrideStorageProfile)
35383 + {
35384 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
35385 +
35386 + if (p_SchemeParams->storageProfile.direct)
35387 + {
35388 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
35389 + shift = 0;
35390 + numOfProfiles = 1;
35391 + }
35392 + else
35393 + {
35394 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35395 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
35396 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
35397 + }
35398 + if (shift > MAX_SP_SHIFT)
35399 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
35400 +
35401 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35402 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35403 +
35404 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
35405 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
35406 + tmpReg |= (uint32_t)profileId;
35407 +
35408 +
35409 + p_SchemeRegs->kgse_vsp = tmpReg;
35410 +
35411 + p_Scheme->vspe = TRUE;
35412 +
35413 + }
35414 + else
35415 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
35416 +#endif /* (DPAA_VERSION >= 11) */
35417 +
35418 + if (p_SchemeParams->useHash)
35419 + {
35420 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
35421 +
35422 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
35423 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
35424 +
35425 + /* configure kgse_dv0 */
35426 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
35427 +
35428 + /* configure kgse_dv1 */
35429 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
35430 +
35431 + if (!p_SchemeParams->bypassFqidGeneration)
35432 + {
35433 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
35434 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
35435 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
35436 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
35437 + }
35438 +
35439 + /* configure kgse_ekdv */
35440 + tmpReg = 0;
35441 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
35442 + {
35443 + switch (p_KeyAndHash->dflts[i].type)
35444 + {
35445 + case (e_FM_PCD_KG_MAC_ADDR):
35446 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
35447 + break;
35448 + case (e_FM_PCD_KG_TCI):
35449 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
35450 + break;
35451 + case (e_FM_PCD_KG_ENET_TYPE):
35452 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
35453 + break;
35454 + case (e_FM_PCD_KG_PPP_SESSION_ID):
35455 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
35456 + break;
35457 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
35458 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
35459 + break;
35460 + case (e_FM_PCD_KG_MPLS_LABEL):
35461 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
35462 + break;
35463 + case (e_FM_PCD_KG_IP_ADDR):
35464 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
35465 + break;
35466 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
35467 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
35468 + break;
35469 + case (e_FM_PCD_KG_IP_TOS_TC):
35470 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
35471 + break;
35472 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
35473 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35474 + break;
35475 + case (e_FM_PCD_KG_IPSEC_SPI):
35476 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
35477 + break;
35478 + case (e_FM_PCD_KG_L4_PORT):
35479 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35480 + break;
35481 + case (e_FM_PCD_KG_TCP_FLAG):
35482 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
35483 + break;
35484 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
35485 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
35486 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35487 + numOfSwDefaults ++;
35488 + break;
35489 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
35490 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
35491 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35492 + numOfSwDefaults ++;
35493 + break;
35494 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
35495 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
35496 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35497 + numOfSwDefaults ++;
35498 + break;
35499 + default:
35500 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35501 + }
35502 + }
35503 + p_SchemeRegs->kgse_ekdv = tmpReg;
35504 +
35505 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
35506 + if (!p_LocalExtractsArray)
35507 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
35508 +
35509 + /* configure kgse_ekfc and kgse_gec */
35510 + knownTmp = 0;
35511 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35512 + {
35513 + p_Extract = &p_KeyAndHash->extractArray[i];
35514 + switch (p_Extract->type)
35515 + {
35516 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35517 + knownTmp |= KG_SCH_KN_PORT_ID;
35518 + /* save in driver structure */
35519 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
35520 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35521 + break;
35522 + case (e_FM_PCD_EXTRACT_BY_HDR):
35523 + switch (p_Extract->extractByHdr.hdr)
35524 + {
35525 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
35526 + case (HEADER_TYPE_UDP_LITE):
35527 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35528 + break;
35529 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
35530 + case (HEADER_TYPE_UDP_ENCAP_ESP):
35531 + switch (p_Extract->extractByHdr.type)
35532 + {
35533 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35534 + /* case where extraction from ESP only */
35535 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
35536 + {
35537 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35538 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
35539 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35540 + }
35541 + else
35542 + {
35543 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35544 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
35545 + }
35546 + break;
35547 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35548 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
35549 + {
35550 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35551 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35552 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35553 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35554 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35555 + break;
35556 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35557 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35558 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35559 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
35560 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35561 + break;
35562 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35563 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35564 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35565 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
35566 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35567 + break;
35568 + }
35569 + break;
35570 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35571 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
35572 + {
35573 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35574 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35575 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35576 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35577 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35578 + break;
35579 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35580 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35581 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35582 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
35583 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
35584 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35585 + break;
35586 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35587 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35588 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35589 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
35590 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
35591 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35592 + break;
35593 + }
35594 + break;
35595 + }
35596 + break;
35597 + default:
35598 + break;
35599 + }
35600 + switch (p_Extract->extractByHdr.type)
35601 + {
35602 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35603 + generic = TRUE;
35604 + /* get the header code for the generic extract */
35605 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
35606 + /* set generic register fields */
35607 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
35608 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
35609 + break;
35610 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35611 + generic = TRUE;
35612 + /* get the field code for the generic extract */
35613 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
35614 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
35615 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
35616 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
35617 + break;
35618 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35619 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
35620 + {
35621 + /* if we have a known field for it - use it, otherwise use generic */
35622 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
35623 + p_Extract->extractByHdr.extractByHdrType.fullField);
35624 + if (bitMask)
35625 + {
35626 + knownTmp |= bitMask;
35627 + /* save in driver structure */
35628 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
35629 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35630 + }
35631 + else
35632 + generic = TRUE;
35633 + }
35634 + else
35635 + generic = TRUE;
35636 + if (generic)
35637 + {
35638 + /* tmp - till we cover more headers under generic */
35639 + XX_Free(p_LocalExtractsArray);
35640 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
35641 + }
35642 + break;
35643 + default:
35644 + XX_Free(p_LocalExtractsArray);
35645 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35646 + }
35647 + break;
35648 + case (e_FM_PCD_EXTRACT_NON_HDR):
35649 + /* use generic */
35650 + generic = TRUE;
35651 + offset = 0;
35652 + /* get the field code for the generic extract */
35653 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
35654 + offset += p_Extract->extractNonHdr.offset;
35655 + size = p_Extract->extractNonHdr.size;
35656 + break;
35657 + default:
35658 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35659 + }
35660 +
35661 + if (generic)
35662 + {
35663 + /* set generic register fields */
35664 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
35665 + {
35666 + XX_Free(p_LocalExtractsArray);
35667 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35668 + }
35669 + if (!code)
35670 + {
35671 + XX_Free(p_LocalExtractsArray);
35672 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35673 + }
35674 +
35675 + genTmp = KG_SCH_GEN_VALID;
35676 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35677 + genTmp |= offset;
35678 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
35679 + {
35680 + XX_Free(p_LocalExtractsArray);
35681 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
35682 + }
35683 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
35684 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
35685 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
35686 + DBG(WARNING, ("No sw default configured"));
35687 + else
35688 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
35689 +
35690 + genTmp |= KG_SCH_GEN_MASK;
35691 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
35692 + /* save in driver structure */
35693 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
35694 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
35695 + generic = FALSE;
35696 + }
35697 + }
35698 + p_SchemeRegs->kgse_ekfc = knownTmp;
35699 +
35700 + selectTmp = 0;
35701 + maskTmp = 0xFFFFFFFF;
35702 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
35703 +
35704 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
35705 + {
35706 + XX_Free(p_LocalExtractsArray);
35707 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
35708 + }
35709 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
35710 + {
35711 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
35712 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
35713 + /* Get the shift of the select field (depending on i) */
35714 + GET_MASK_SEL_SHIFT(shift,i);
35715 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
35716 + selectTmp |= id << shift;
35717 + else
35718 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
35719 +
35720 + /* Get the shift of the offset field (depending on i) - may
35721 + be in kgse_bmch or in kgse_fqb (depending on i) */
35722 + GET_MASK_OFFSET_SHIFT(shift,i);
35723 + if (i<=1)
35724 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
35725 + else
35726 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
35727 +
35728 + /* Get the shift of the mask field (depending on i) */
35729 + GET_MASK_SHIFT(shift,i);
35730 + /* pass all bits */
35731 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
35732 + /* clear bits that need masking */
35733 + maskTmp &= ~(0xFF << shift) ;
35734 + /* set mask bits */
35735 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
35736 + }
35737 + p_SchemeRegs->kgse_bmch = selectTmp;
35738 + p_SchemeRegs->kgse_bmcl = maskTmp;
35739 + /* kgse_fqb will be written t the end of the routine */
35740 +
35741 + /* configure kgse_hc */
35742 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
35743 + {
35744 + XX_Free(p_LocalExtractsArray);
35745 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
35746 + }
35747 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
35748 + {
35749 + XX_Free(p_LocalExtractsArray);
35750 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
35751 + }
35752 +
35753 + tmpReg = 0;
35754 +
35755 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
35756 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
35757 +
35758 + if (p_KeyAndHash->symmetricHash)
35759 + {
35760 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
35761 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
35762 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
35763 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
35764 + {
35765 + XX_Free(p_LocalExtractsArray);
35766 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
35767 + }
35768 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
35769 + }
35770 + p_SchemeRegs->kgse_hc = tmpReg;
35771 +
35772 + /* build the return array describing the order of the extractions */
35773 +
35774 + /* the last currGenId places of the array
35775 + are for generic extracts that are always last.
35776 + We now sort for the calculation of the order of the known
35777 + extractions we sort the known extracts between orderedArray[0] and
35778 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
35779 + for the calculation of the order of the generic extractions we use:
35780 + num_of_generic - currGenId
35781 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
35782 + first_generic_index = num_of_known */
35783 + curr = 0;
35784 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35785 + {
35786 + if (p_LocalExtractsArray->extractsArray[i].known)
35787 + {
35788 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
35789 + j = curr;
35790 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
35791 + index in the user's extractions array */
35792 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
35793 + location */
35794 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
35795 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
35796 + {
35797 + p_Scheme->orderedArray[j] =
35798 + p_Scheme->orderedArray[j-1];
35799 + j--;
35800 + }
35801 + p_Scheme->orderedArray[j] = (uint8_t)i;
35802 + curr++;
35803 + }
35804 + else
35805 + {
35806 + /* index is first_generic_index + generic index (id) */
35807 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
35808 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
35809 + p_Scheme->orderedArray[idx]= (uint8_t)i;
35810 + }
35811 + }
35812 + XX_Free(p_LocalExtractsArray);
35813 + }
35814 + else
35815 + {
35816 + /* clear all unused registers: */
35817 + p_SchemeRegs->kgse_ekfc = 0;
35818 + p_SchemeRegs->kgse_ekdv = 0;
35819 + p_SchemeRegs->kgse_bmch = 0;
35820 + p_SchemeRegs->kgse_bmcl = 0;
35821 + p_SchemeRegs->kgse_hc = 0;
35822 + p_SchemeRegs->kgse_dv0 = 0;
35823 + p_SchemeRegs->kgse_dv1 = 0;
35824 + }
35825 +
35826 + if (p_SchemeParams->bypassFqidGeneration)
35827 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
35828 +
35829 + /* configure kgse_spc */
35830 + if ( p_SchemeParams->schemeCounter.update)
35831 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
35832 +
35833 +
35834 + /* check that are enough generic registers */
35835 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
35836 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
35837 +
35838 + /* extracted OR mask on Qid */
35839 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
35840 + {
35841 +
35842 + p_Scheme->extractedOrs = TRUE;
35843 + /* configure kgse_gec[i] */
35844 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
35845 + switch (p_ExtractOr->type)
35846 + {
35847 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35848 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
35849 + offset = 0;
35850 + break;
35851 + case (e_FM_PCD_EXTRACT_BY_HDR):
35852 + /* get the header code for the generic extract */
35853 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
35854 + /* set generic register fields */
35855 + offset = p_ExtractOr->extractionOffset;
35856 + break;
35857 + case (e_FM_PCD_EXTRACT_NON_HDR):
35858 + /* get the field code for the generic extract */
35859 + offset = 0;
35860 + code = GetGenCode(p_ExtractOr->src, &offset);
35861 + offset += p_ExtractOr->extractionOffset;
35862 + break;
35863 + default:
35864 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35865 + }
35866 +
35867 + /* set generic register fields */
35868 + if (!code)
35869 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
35870 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
35871 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
35872 + genTmp |= offset;
35873 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
35874 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
35875 +
35876 + /************************************************************************************
35877 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
35878 + in the following way:
35879 +
35880 + Driver API and implementation:
35881 + ==============================
35882 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
35883 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
35884 + are not overlapping FQID.
35885 + ------------------------
35886 + | FQID (24) |
35887 + ------------------------
35888 + --------
35889 + | | extracted OR byte
35890 + --------
35891 +
35892 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
35893 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
35894 + are not overlapping PP id.
35895 +
35896 + --------
35897 + | PP (8) |
35898 + --------
35899 + --------
35900 + | | extracted OR byte
35901 + --------
35902 +
35903 + HW implementation
35904 + =================
35905 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
35906 + as the highest byte of that word and may be rotated to effect any part os the FQID or
35907 + the PP.
35908 + ------------------------ --------
35909 + | FQID (24) || PP (8) |
35910 + ------------------------ --------
35911 + --------
35912 + | | extracted OR byte
35913 + --------
35914 +
35915 + ************************************************************************************/
35916 +
35917 + if (p_ExtractOr->bitOffsetInFqid)
35918 + {
35919 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
35920 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
35921 + if (p_ExtractOr->bitOffsetInFqid<8)
35922 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
35923 + else
35924 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
35925 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
35926 + }
35927 + else /* effect policer profile */
35928 + {
35929 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
35930 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
35931 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
35932 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
35933 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
35934 + }
35935 +
35936 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
35937 + /* clear bits that need masking */
35938 + genTmp &= ~KG_SCH_GEN_MASK ;
35939 + /* set mask bits */
35940 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
35941 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
35942 +
35943 + }
35944 + /* clear all unused GEC registers */
35945 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
35946 + p_SchemeRegs->kgse_gec[i] = 0;
35947 +
35948 + /* add base Qid for this scheme */
35949 + /* add configuration for kgse_fqb */
35950 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
35951 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
35952 +
35953 + fqbTmp |= p_SchemeParams->baseFqid;
35954 + p_SchemeRegs->kgse_fqb = fqbTmp;
35955 +
35956 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
35957 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
35958 +
35959 + return E_OK;
35960 +}
35961 +
35962 +
35963 +/*****************************************************************************/
35964 +/* Inter-module API routines */
35965 +/*****************************************************************************/
35966 +
35967 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
35968 +{
35969 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
35970 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
35971 + t_FmPcdIpcKgClsPlanParams kgAlloc;
35972 + t_Error err = E_OK;
35973 + uint32_t oredVectors = 0;
35974 + int i, j;
35975 +
35976 + /* this routine is protected by the calling routine ! */
35977 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
35978 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
35979 +
35980 + /* find a new clsPlan group */
35981 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
35982 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
35983 + break;
35984 + if (i == FM_MAX_NUM_OF_PORTS)
35985 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
35986 +
35987 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
35988 +
35989 + p_Grp->clsPlanGrpId = (uint8_t)i;
35990 +
35991 + if (p_Grp->numOfOptions == 0)
35992 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
35993 +
35994 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
35995 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
35996 + p_ClsPlanGrp->owners = 0;
35997 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
35998 + if (p_Grp->numOfOptions != 0)
35999 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
36000 +
36001 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
36002 + /* a minimal group of 8 is required */
36003 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
36004 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
36005 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36006 + {
36007 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
36008 +
36009 + if (err)
36010 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
36011 + }
36012 + else
36013 + {
36014 + t_FmPcdIpcMsg msg;
36015 + uint32_t replyLength;
36016 + t_FmPcdIpcReply reply;
36017 +
36018 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36019 + memset(&reply, 0, sizeof(reply));
36020 + memset(&msg, 0, sizeof(msg));
36021 + memset(&kgAlloc, 0, sizeof(kgAlloc));
36022 + kgAlloc.guestId = p_FmPcd->guestId;
36023 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36024 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
36025 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36026 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
36027 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36028 + (uint8_t*)&msg,
36029 + sizeof(msg.msgId) + sizeof(kgAlloc),
36030 + (uint8_t*)&reply,
36031 + &replyLength,
36032 + NULL,
36033 + NULL)) != E_OK)
36034 + RETURN_ERROR(MAJOR, err, NO_MSG);
36035 +
36036 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
36037 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36038 + if ((t_Error)reply.error != E_OK)
36039 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
36040 +
36041 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
36042 + }
36043 +
36044 + /* build classification plan entries parameters */
36045 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
36046 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36047 +
36048 + oredVectors = 0;
36049 + for (i = 0; i<p_Grp->numOfOptions; i++)
36050 + {
36051 + oredVectors |= p_Grp->optVectors[i];
36052 + /* save an array of used options - the indexes represent the power of 2 index */
36053 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
36054 + }
36055 + /* set the classification plan relevant entries so that all bits
36056 + * relevant to the list of options is cleared
36057 + */
36058 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36059 + p_ClsPlanSet->vectors[j] = ~oredVectors;
36060 +
36061 + for (i = 0; i<p_Grp->numOfOptions; i++)
36062 + {
36063 + /* option i got the place 2^i in the clsPlan array. all entries that
36064 + * have bit i set, should have the vector bit cleared. So each option
36065 + * has one location that it is exclusive (1,2,4,8...) and represent the
36066 + * presence of that option only, and other locations that represent a
36067 + * combination of options.
36068 + * e.g:
36069 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
36070 + * now represents a frame with ethernet-BC header - so the bit
36071 + * representing ethernet-BC should be set and all other option bits
36072 + * should be cleared.
36073 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
36074 + * vector[1] set, but they also have other bits set:
36075 + * 3=1+2, options 0 and 1
36076 + * 6=2+4, options 1 and 2
36077 + * 7=1+2+4, options 0,1,and 2
36078 + * 10=2+8, options 1 and 3
36079 + * etc.
36080 + * */
36081 +
36082 + /* now for each option (i), we set their bits in all entries (j)
36083 + * that contain bit 2^i.
36084 + */
36085 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36086 + {
36087 + if (j & (1<<i))
36088 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
36089 + }
36090 + }
36091 +
36092 + return E_OK;
36093 +}
36094 +
36095 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
36096 +{
36097 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36098 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36099 + t_Error err;
36100 + t_FmPcdIpcMsg msg;
36101 + uint32_t replyLength;
36102 + t_FmPcdIpcReply reply;
36103 +
36104 + /* check that no port is bound to this clsPlan */
36105 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
36106 + {
36107 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
36108 + return;
36109 + }
36110 +
36111 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
36112 +
36113 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36114 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36115 + else
36116 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
36117 +
36118 + /* free blocks */
36119 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36120 + KgFreeClsPlanEntries(h_FmPcd,
36121 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
36122 + p_FmPcd->guestId,
36123 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
36124 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36125 + {
36126 + memset(&reply, 0, sizeof(reply));
36127 + memset(&msg, 0, sizeof(msg));
36128 + kgAlloc.guestId = p_FmPcd->guestId;
36129 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
36130 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
36131 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
36132 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36133 + replyLength = sizeof(uint32_t);
36134 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36135 + (uint8_t*)&msg,
36136 + sizeof(msg.msgId) + sizeof(kgAlloc),
36137 + (uint8_t*)&reply,
36138 + &replyLength,
36139 + NULL,
36140 + NULL);
36141 + if (err != E_OK)
36142 + {
36143 + REPORT_ERROR(MINOR, err, NO_MSG);
36144 + return;
36145 + }
36146 + if (replyLength != sizeof(uint32_t))
36147 + {
36148 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36149 + return;
36150 + }
36151 + if ((t_Error)reply.error != E_OK)
36152 + {
36153 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
36154 + return;
36155 + }
36156 + }
36157 +
36158 + /* clear clsPlan driver structure */
36159 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
36160 +}
36161 +
36162 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
36163 +{
36164 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36165 + uint32_t j, schemesPerPortVector = 0;
36166 + t_FmPcdKgScheme *p_Scheme;
36167 + uint8_t i, relativeSchemeId;
36168 + uint32_t tmp, walking1Mask;
36169 + uint8_t swPortIndex = 0;
36170 +
36171 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36172 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36173 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
36174 +
36175 + /* for each scheme */
36176 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
36177 + {
36178 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36179 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36180 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36181 +
36182 + if (add)
36183 + {
36184 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36185 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
36186 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
36187 + /* check netEnvId of the port against the scheme netEnvId */
36188 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
36189 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
36190 +
36191 + /* if next engine is private port policer profile, we need to check that it is valid */
36192 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
36193 + if (p_Scheme->nextRelativePlcrProfile)
36194 + {
36195 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
36196 + {
36197 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
36198 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
36199 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
36200 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
36201 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
36202 + }
36203 + }
36204 + if (!p_BindPort->useClsPlan)
36205 + {
36206 + /* This check may be redundant as port is a assigned to the whole NetEnv */
36207 +
36208 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
36209 + cls plan options. Schemes that are used only directly, should not be checked.
36210 + it also may not be bound to schemes that go to CC with units that are options - so we OR
36211 + the match vector and the grpBits (= ccUnits) */
36212 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
36213 + {
36214 + uint8_t netEnvId;
36215 + walking1Mask = 0x80000000;
36216 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
36217 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
36218 + tmp |= p_Scheme->ccUnits;
36219 + while (tmp)
36220 + {
36221 + if (tmp & walking1Mask)
36222 + {
36223 + tmp &= ~walking1Mask;
36224 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
36225 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
36226 + }
36227 + walking1Mask >>= 1;
36228 + }
36229 + }
36230 + }
36231 + }
36232 + /* build vector */
36233 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
36234 + }
36235 +
36236 + *p_SpReg = schemesPerPortVector;
36237 +
36238 + return E_OK;
36239 +}
36240 +
36241 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36242 +{
36243 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36244 + uint32_t spReg;
36245 + t_Error err = E_OK;
36246 +
36247 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
36248 + if (err)
36249 + RETURN_ERROR(MAJOR, err, NO_MSG);
36250 +
36251 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
36252 + if (err)
36253 + RETURN_ERROR(MAJOR, err, NO_MSG);
36254 +
36255 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
36256 +
36257 + return E_OK;
36258 +}
36259 +
36260 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36261 +{
36262 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36263 + uint32_t spReg;
36264 + t_Error err = E_OK;
36265 +
36266 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
36267 + if (err)
36268 + RETURN_ERROR(MAJOR, err, NO_MSG);
36269 +
36270 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
36271 + if (err)
36272 + RETURN_ERROR(MAJOR, err, NO_MSG);
36273 +
36274 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
36275 +
36276 + return E_OK;
36277 +}
36278 +
36279 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
36280 +{
36281 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36282 +
36283 + return p_Scheme->valid;
36284 +}
36285 +
36286 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
36287 +{
36288 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36289 +
36290 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
36291 + return TRUE;
36292 + else
36293 + return FALSE;
36294 +}
36295 +
36296 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36297 +{
36298 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36299 + uint8_t i, j;
36300 +
36301 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36302 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36303 +
36304 + /* This routine is issued only on master core of master partition -
36305 + either directly or through IPC, so no need for lock */
36306 +
36307 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
36308 + {
36309 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
36310 + {
36311 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
36312 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
36313 + p_SchemesIds[j] = i;
36314 + j++;
36315 + }
36316 + }
36317 +
36318 + if (j != numOfSchemes)
36319 + {
36320 + /* roll back */
36321 + for (j--; j; j--)
36322 + {
36323 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
36324 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
36325 + p_SchemesIds[j] = 0;
36326 + }
36327 +
36328 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
36329 + }
36330 +
36331 + return E_OK;
36332 +}
36333 +
36334 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36335 +{
36336 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36337 + uint8_t i;
36338 +
36339 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36340 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36341 +
36342 + /* This routine is issued only on master core of master partition -
36343 + either directly or through IPC */
36344 +
36345 + for (i = 0; i < numOfSchemes; i++)
36346 + {
36347 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
36348 + {
36349 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
36350 + }
36351 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
36352 + {
36353 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
36354 + }
36355 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
36356 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
36357 + }
36358 +
36359 + return E_OK;
36360 +}
36361 +
36362 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
36363 +{
36364 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36365 + uint8_t numOfBlocks, blocksFound=0, first=0;
36366 + uint8_t i, j;
36367 +
36368 + /* This routine is issued only on master core of master partition -
36369 + either directly or through IPC, so no need for lock */
36370 +
36371 + if (!numOfClsPlanEntries)
36372 + return E_OK;
36373 +
36374 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
36375 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
36376 +
36377 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36378 +
36379 + /* try to find consequent blocks */
36380 + first = 0;
36381 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
36382 + {
36383 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
36384 + {
36385 + blocksFound++;
36386 + i++;
36387 + if (blocksFound == numOfBlocks)
36388 + break;
36389 + }
36390 + else
36391 + {
36392 + blocksFound = 0;
36393 + /* advance i to the next aligned address */
36394 + first = i = (uint8_t)(first + numOfBlocks);
36395 + }
36396 + }
36397 +
36398 + if (blocksFound == numOfBlocks)
36399 + {
36400 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
36401 + for (j = first; j < (first + numOfBlocks); j++)
36402 + {
36403 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
36404 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
36405 + }
36406 + return E_OK;
36407 + }
36408 + else
36409 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
36410 +}
36411 +
36412 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
36413 +{
36414 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36415 + uint8_t numOfBlocks;
36416 + uint8_t i, baseBlock;
36417 +
36418 +#ifdef DISABLE_ASSERTIONS
36419 +UNUSED(guestId);
36420 +#endif /* DISABLE_ASSERTIONS */
36421 +
36422 + /* This routine is issued only on master core of master partition -
36423 + either directly or through IPC, so no need for lock */
36424 +
36425 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36426 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
36427 +
36428 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
36429 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
36430 + {
36431 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
36432 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
36433 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
36434 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
36435 + }
36436 +}
36437 +
36438 +void KgEnable(t_FmPcd *p_FmPcd)
36439 +{
36440 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36441 +
36442 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36443 + fman_kg_enable(p_Regs);
36444 +}
36445 +
36446 +void KgDisable(t_FmPcd *p_FmPcd)
36447 +{
36448 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36449 +
36450 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36451 + fman_kg_disable(p_Regs);
36452 +}
36453 +
36454 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
36455 +{
36456 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36457 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
36458 + uint32_t tmpKgarReg = 0, intFlags;
36459 + uint16_t i, j;
36460 +
36461 + /* This routine is protected by the calling routine ! */
36462 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36463 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
36464 +
36465 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36466 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
36467 + {
36468 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
36469 +
36470 + for (j = i; j < i+8; j++)
36471 + {
36472 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
36473 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
36474 + }
36475 +
36476 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
36477 + {
36478 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
36479 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36480 + return;
36481 + }
36482 + }
36483 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36484 +}
36485 +
36486 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
36487 +{
36488 + t_FmPcdKg *p_FmPcdKg;
36489 +
36490 + UNUSED(p_FmPcd);
36491 +
36492 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
36493 + {
36494 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
36495 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
36496 + return NULL;
36497 + }
36498 +
36499 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
36500 + if (!p_FmPcdKg)
36501 + {
36502 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
36503 + return NULL;
36504 + }
36505 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
36506 +
36507 +
36508 + if (FmIsMaster(p_FmPcd->h_Fm))
36509 + {
36510 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
36511 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
36512 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
36513 + }
36514 +
36515 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
36516 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
36517 + {
36518 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
36519 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
36520 + }
36521 +
36522 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36523 +
36524 + return p_FmPcdKg;
36525 +}
36526 +
36527 +t_Error KgInit(t_FmPcd *p_FmPcd)
36528 +{
36529 + t_Error err = E_OK;
36530 +
36531 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
36532 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36533 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
36534 +
36535 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36536 + err = KgInitMaster(p_FmPcd);
36537 + else
36538 + err = KgInitGuest(p_FmPcd);
36539 +
36540 + if (err != E_OK)
36541 + {
36542 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36543 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36544 + }
36545 +
36546 + return err;
36547 +}
36548 +
36549 +t_Error KgFree(t_FmPcd *p_FmPcd)
36550 +{
36551 + t_FmPcdIpcKgSchemesParams kgAlloc;
36552 + t_Error err = E_OK;
36553 + t_FmPcdIpcMsg msg;
36554 + uint32_t replyLength;
36555 + t_FmPcdIpcReply reply;
36556 +
36557 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
36558 +
36559 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36560 + {
36561 + err = FmPcdKgFreeSchemes(p_FmPcd,
36562 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36563 + p_FmPcd->guestId,
36564 + p_FmPcd->p_FmPcdKg->schemesIds);
36565 + if (err)
36566 + RETURN_ERROR(MAJOR, err, NO_MSG);
36567 +
36568 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36569 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36570 +
36571 + return E_OK;
36572 + }
36573 +
36574 + /* guest */
36575 + memset(&reply, 0, sizeof(reply));
36576 + memset(&msg, 0, sizeof(msg));
36577 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36578 + kgAlloc.guestId = p_FmPcd->guestId;
36579 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
36580 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
36581 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
36582 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36583 + replyLength = sizeof(uint32_t);
36584 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36585 + (uint8_t*)&msg,
36586 + sizeof(msg.msgId) + sizeof(kgAlloc),
36587 + (uint8_t*)&reply,
36588 + &replyLength,
36589 + NULL,
36590 + NULL)) != E_OK)
36591 + RETURN_ERROR(MAJOR, err, NO_MSG);
36592 + if (replyLength != sizeof(uint32_t))
36593 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36594 +
36595 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36596 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36597 +
36598 + return (t_Error)reply.error;
36599 +}
36600 +
36601 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
36602 +{
36603 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36604 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
36605 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36606 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36607 + t_Error err;
36608 +
36609 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
36610 + so no need for lock here */
36611 +
36612 + memset(&grpParams, 0, sizeof(grpParams));
36613 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
36614 + p_GrpParams = &grpParams;
36615 +
36616 + p_GrpParams->netEnvId = netEnvId;
36617 +
36618 + /* Get from the NetEnv the information of the clsPlan (can be already created,
36619 + * or needs to build) */
36620 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
36621 + if (err)
36622 + RETURN_ERROR(MINOR,err,NO_MSG);
36623 +
36624 + if (p_GrpParams->grpExists)
36625 + {
36626 + /* this group was already updated (at least) in SW */
36627 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36628 + }
36629 + else
36630 + {
36631 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36632 + if (!p_ClsPlanSet)
36633 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36634 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36635 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
36636 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
36637 + if (err)
36638 + {
36639 + XX_Free(p_ClsPlanSet);
36640 + RETURN_ERROR(MINOR, err, NO_MSG);
36641 + }
36642 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36643 +
36644 + if (p_FmPcd->h_Hc)
36645 + {
36646 + /* write clsPlan entries to memory */
36647 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
36648 + if (err)
36649 + {
36650 + XX_Free(p_ClsPlanSet);
36651 + RETURN_ERROR(MAJOR, err, NO_MSG);
36652 + }
36653 + }
36654 + else
36655 + /* write clsPlan entries to memory */
36656 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36657 +
36658 + XX_Free(p_ClsPlanSet);
36659 + }
36660 +
36661 + /* Set caller parameters */
36662 +
36663 + /* mark if this is an empty classification group */
36664 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36665 + *p_IsEmptyClsPlanGrp = TRUE;
36666 + else
36667 + *p_IsEmptyClsPlanGrp = FALSE;
36668 +
36669 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
36670 +
36671 + /* increment owners number */
36672 + p_ClsPlanGrp->owners++;
36673 +
36674 + /* copy options array for port */
36675 + 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));
36676 +
36677 + /* bind port to the new or existing group */
36678 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
36679 + if (err)
36680 + RETURN_ERROR(MINOR, err, NO_MSG);
36681 +
36682 + return E_OK;
36683 +}
36684 +
36685 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
36686 +{
36687 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36688 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
36689 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36690 + t_Error err;
36691 +
36692 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
36693 + so no need for lock here */
36694 +
36695 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
36696 +
36697 + /* decrement owners number */
36698 + ASSERT_COND(p_ClsPlanGrp->owners);
36699 + p_ClsPlanGrp->owners--;
36700 +
36701 + if (!p_ClsPlanGrp->owners)
36702 + {
36703 + if (p_FmPcd->h_Hc)
36704 + {
36705 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
36706 + return err;
36707 + }
36708 + else
36709 + {
36710 + /* clear clsPlan entries in memory */
36711 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36712 + if (!p_ClsPlanSet)
36713 + {
36714 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36715 + }
36716 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36717 +
36718 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
36719 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
36720 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
36721 + XX_Free(p_ClsPlanSet);
36722 +
36723 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
36724 + }
36725 + }
36726 + return E_OK;
36727 +}
36728 +
36729 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
36730 +{
36731 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36732 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36733 +
36734 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
36735 +}
36736 +
36737 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
36738 +{
36739 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36740 +
36741 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36742 +
36743 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
36744 +}
36745 +
36746 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
36747 +{
36748 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36749 +
36750 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36751 +
36752 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
36753 +}
36754 +
36755 +
36756 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
36757 +{
36758 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36759 +
36760 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36761 +
36762 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
36763 +}
36764 +
36765 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
36766 +{
36767 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36768 +
36769 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36770 +
36771 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
36772 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
36773 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
36774 + return TRUE;
36775 + else
36776 + return FALSE;
36777 +
36778 +}
36779 +
36780 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
36781 +{
36782 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36783 +
36784 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
36785 +
36786 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
36787 +}
36788 +
36789 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
36790 +{
36791 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36792 +
36793 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
36794 +
36795 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
36796 +}
36797 +
36798 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
36799 +{
36800 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
36801 +
36802 + /* this routine is protected by calling routine */
36803 +
36804 + ASSERT_COND(p_Scheme->valid);
36805 +
36806 + p_Scheme->requiredAction |= requiredAction;
36807 +}
36808 +
36809 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
36810 +{
36811 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
36812 +}
36813 +
36814 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
36815 +{
36816 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36817 + FM_KG_KGAR_GO |
36818 + FM_KG_KGAR_WRITE |
36819 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
36820 + DUMMY_PORT_ID |
36821 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
36822 +}
36823 +
36824 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
36825 +{
36826 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36827 + FM_KG_KGAR_GO |
36828 + FM_KG_KGAR_READ |
36829 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
36830 + DUMMY_PORT_ID |
36831 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
36832 +
36833 +}
36834 +
36835 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
36836 +{
36837 + return (uint32_t)(FM_KG_KGAR_GO |
36838 + FM_KG_KGAR_WRITE |
36839 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
36840 + DUMMY_PORT_ID |
36841 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
36842 + FM_PCD_KG_KGAR_WSEL_MASK);
36843 +
36844 + /* if we ever want to write 1 by 1, use:
36845 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
36846 + */
36847 +}
36848 +
36849 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
36850 +{
36851 +
36852 + return (uint32_t)(FM_KG_KGAR_GO |
36853 + FM_KG_KGAR_WRITE |
36854 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
36855 + hardwarePortId |
36856 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
36857 +}
36858 +
36859 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
36860 +{
36861 +
36862 + return (uint32_t)(FM_KG_KGAR_GO |
36863 + FM_KG_KGAR_READ |
36864 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
36865 + hardwarePortId |
36866 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
36867 +}
36868 +
36869 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
36870 +{
36871 +
36872 + return (uint32_t)(FM_KG_KGAR_GO |
36873 + FM_KG_KGAR_WRITE |
36874 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
36875 + hardwarePortId |
36876 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
36877 +}
36878 +
36879 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
36880 +{
36881 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36882 +
36883 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
36884 +}
36885 +
36886 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
36887 +{
36888 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36889 +
36890 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
36891 +}
36892 +
36893 +
36894 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
36895 +{
36896 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
36897 +
36898 +}
36899 +
36900 +#if (DPAA_VERSION >= 11)
36901 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
36902 +{
36903 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
36904 +
36905 +}
36906 +#endif /* (DPAA_VERSION >= 11) */
36907 +
36908 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
36909 +{
36910 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36911 + uint8_t i;
36912 +
36913 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
36914 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
36915 + return i;
36916 +
36917 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
36918 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
36919 +
36920 + return FM_PCD_KG_NUM_OF_SCHEMES;
36921 +}
36922 +
36923 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
36924 +{
36925 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36926 +
36927 + ASSERT_COND(p_FmPcd);
36928 +
36929 + /* check that schemeId is in range */
36930 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
36931 + {
36932 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
36933 + return NULL;
36934 + }
36935 +
36936 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
36937 + return NULL;
36938 +
36939 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36940 +}
36941 +
36942 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
36943 +{
36944 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
36945 +}
36946 +
36947 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
36948 +{
36949 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36950 + uint8_t relativeSchemeId, physicalSchemeId;
36951 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
36952 + t_Error err;
36953 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36954 +
36955 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
36956 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
36957 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
36958 +
36959 + /* Calling function locked all PCD modules, so no need to lock here */
36960 +
36961 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
36962 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
36963 +
36964 + if (p_FmPcd->h_Hc)
36965 + {
36966 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
36967 +
36968 + UpdateRequiredActionFlag(h_Scheme,TRUE);
36969 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
36970 + return err;
36971 + }
36972 +
36973 + physicalSchemeId = p_Scheme->schemeId;
36974 +
36975 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
36976 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36977 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36978 +
36979 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
36980 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
36981 + {
36982 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
36983 + {
36984 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
36985 + {
36986 + case (e_FM_PCD_DONE):
36987 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
36988 + {
36989 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
36990 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36991 + WriteKgarWait(p_FmPcd, tmpKgarReg);
36992 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
36993 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
36994 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
36995 + /* call indirect command for scheme write */
36996 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
36997 + WriteKgarWait(p_FmPcd, tmpKgarReg);
36998 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36999 + }
37000 + break;
37001 + case (e_FM_PCD_PLCR):
37002 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
37003 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
37004 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
37005 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
37006 + {
37007 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
37008 + }
37009 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
37010 + if (err)
37011 + {
37012 + RETURN_ERROR(MAJOR, err, NO_MSG);
37013 + }
37014 + break;
37015 + default:
37016 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
37017 + }
37018 + }
37019 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
37020 + {
37021 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
37022 + {
37023 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37024 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37025 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37026 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37027 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
37028 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
37029 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
37030 + /* call indirect command for scheme write */
37031 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37032 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37033 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37034 + }
37035 + }
37036 + if (requiredAction & UPDATE_KG_OPT_MODE)
37037 + {
37038 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37039 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37040 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37041 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
37042 + /* call indirect command for scheme write */
37043 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37044 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37045 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37046 + }
37047 + if (requiredAction & UPDATE_KG_NIA)
37048 + {
37049 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37050 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37051 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37052 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37053 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
37054 + tmpReg32 |= value;
37055 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
37056 + /* call indirect command for scheme write */
37057 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37058 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37059 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37060 + }
37061 + }
37062 +
37063 + UpdateRequiredActionFlag(h_Scheme, TRUE);
37064 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
37065 +
37066 + return E_OK;
37067 +}
37068 +/*********************** End of inter-module routines ************************/
37069 +
37070 +
37071 +/****************************************/
37072 +/* API routines */
37073 +/****************************************/
37074 +
37075 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
37076 +{
37077 + t_FmPcd *p_FmPcd;
37078 + struct fman_kg_scheme_regs schemeRegs;
37079 + struct fman_kg_scheme_regs *p_MemRegs;
37080 + uint8_t i;
37081 + t_Error err = E_OK;
37082 + uint32_t tmpKgarReg;
37083 + uint32_t intFlags;
37084 + uint8_t physicalSchemeId, relativeSchemeId = 0;
37085 + t_FmPcdKgScheme *p_Scheme;
37086 +
37087 + if (p_SchemeParams->modify)
37088 + {
37089 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
37090 + p_FmPcd = p_Scheme->h_FmPcd;
37091 +
37092 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37093 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37094 +
37095 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37096 + {
37097 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37098 + ("Scheme is invalid"));
37099 + return NULL;
37100 + }
37101 +
37102 + if (!KgSchemeFlagTryLock(p_Scheme))
37103 + {
37104 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
37105 + /* Signal to caller BUSY condition */
37106 + p_SchemeParams->id.h_Scheme = NULL;
37107 + return NULL;
37108 + }
37109 + }
37110 + else
37111 + {
37112 + p_FmPcd = (t_FmPcd*)h_FmPcd;
37113 +
37114 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37115 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37116 +
37117 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
37118 + /* check that schemeId is in range */
37119 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37120 + {
37121 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37122 + return NULL;
37123 + }
37124 +
37125 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37126 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
37127 + {
37128 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37129 + ("Scheme id (%d)!", relativeSchemeId));
37130 + return NULL;
37131 + }
37132 + /* Clear all fields, scheme may have beed previously used */
37133 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
37134 +
37135 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
37136 + p_Scheme->h_FmPcd = p_FmPcd;
37137 +
37138 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
37139 + if (!p_Scheme->p_Lock)
37140 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
37141 + }
37142 +
37143 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
37144 + if (err)
37145 + {
37146 + REPORT_ERROR(MAJOR, err, NO_MSG);
37147 + if (p_SchemeParams->modify)
37148 + KgSchemeFlagUnlock(p_Scheme);
37149 + if (!p_SchemeParams->modify &&
37150 + p_Scheme->p_Lock)
37151 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37152 + return NULL;
37153 + }
37154 +
37155 + if (p_FmPcd->h_Hc)
37156 + {
37157 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
37158 + (t_Handle)p_Scheme,
37159 + &schemeRegs,
37160 + p_SchemeParams->schemeCounter.update);
37161 + if (p_SchemeParams->modify)
37162 + KgSchemeFlagUnlock(p_Scheme);
37163 + if (err)
37164 + {
37165 + if (!p_SchemeParams->modify &&
37166 + p_Scheme->p_Lock)
37167 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37168 + return NULL;
37169 + }
37170 + if (!p_SchemeParams->modify)
37171 + ValidateSchemeSw(p_Scheme);
37172 + return (t_Handle)p_Scheme;
37173 + }
37174 +
37175 + physicalSchemeId = p_Scheme->schemeId;
37176 +
37177 + /* configure all 21 scheme registers */
37178 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
37179 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37180 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
37181 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
37182 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
37183 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
37184 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
37185 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
37186 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
37187 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
37188 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
37189 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
37190 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
37191 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
37192 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
37193 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
37194 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
37195 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37196 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
37197 +
37198 + /* call indirect command for scheme write */
37199 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
37200 +
37201 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37202 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37203 +
37204 + if (!p_SchemeParams->modify)
37205 + ValidateSchemeSw(p_Scheme);
37206 + else
37207 + KgSchemeFlagUnlock(p_Scheme);
37208 +
37209 + return (t_Handle)p_Scheme;
37210 +}
37211 +
37212 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
37213 +{
37214 + t_FmPcd *p_FmPcd;
37215 + uint8_t physicalSchemeId;
37216 + uint32_t tmpKgarReg, intFlags;
37217 + t_Error err = E_OK;
37218 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37219 +
37220 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
37221 +
37222 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
37223 +
37224 + UpdateRequiredActionFlag(h_Scheme, FALSE);
37225 +
37226 + /* check that no port is bound to this scheme */
37227 + err = InvalidateSchemeSw(h_Scheme);
37228 + if (err)
37229 + RETURN_ERROR(MINOR, err, NO_MSG);
37230 +
37231 + if (p_FmPcd->h_Hc)
37232 + {
37233 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
37234 + if (p_Scheme->p_Lock)
37235 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37236 + return err;
37237 + }
37238 +
37239 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37240 +
37241 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37242 + /* clear mode register, including enable bit */
37243 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
37244 +
37245 + /* call indirect command for scheme write */
37246 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37247 +
37248 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37249 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37250 +
37251 + if (p_Scheme->p_Lock)
37252 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37253 +
37254 + return E_OK;
37255 +}
37256 +
37257 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
37258 +{
37259 + t_FmPcd *p_FmPcd;
37260 + uint32_t tmpKgarReg, spc, intFlags;
37261 + uint8_t physicalSchemeId;
37262 +
37263 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37264 +
37265 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37266 + if (p_FmPcd->h_Hc)
37267 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
37268 +
37269 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37270 +
37271 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37272 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37273 +
37274 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37275 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37276 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37277 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37278 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37279 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
37280 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37281 +
37282 + return spc;
37283 +}
37284 +
37285 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
37286 +{
37287 + t_FmPcd *p_FmPcd;
37288 + uint32_t tmpKgarReg, intFlags;
37289 + uint8_t physicalSchemeId;
37290 +
37291 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37292 +
37293 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37294 +
37295 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37296 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37297 +
37298 + if (p_FmPcd->h_Hc)
37299 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
37300 +
37301 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37302 + /* check that schemeId is in range */
37303 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37304 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37305 +
37306 + /* read specified scheme into scheme registers */
37307 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37308 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37309 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37310 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37311 + {
37312 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37313 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37314 + }
37315 +
37316 + /* change counter value */
37317 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
37318 +
37319 + /* call indirect command for scheme write */
37320 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
37321 +
37322 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37323 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37324 +
37325 + return E_OK;
37326 +}
37327 +
37328 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
37329 +{
37330 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37331 + struct fman_kg_regs *p_Regs;
37332 +
37333 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37334 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37335 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37336 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37337 +
37338 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37339 + if (!FmIsMaster(p_FmPcd->h_Fm))
37340 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
37341 +
37342 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
37343 +
37344 + return E_OK;
37345 +}
37346 +
37347 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
37348 +{
37349 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37350 + struct fman_kg_regs *p_Regs;
37351 +
37352 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37353 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
37354 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37355 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37356 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37357 +
37358 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37359 +
37360 + if (!FmIsMaster(p_FmPcd->h_Fm))
37361 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
37362 +
37363 + if (valueId == 0)
37364 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
37365 + else
37366 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
37367 + return E_OK;
37368 +}
37369 --- /dev/null
37370 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37371 @@ -0,0 +1,206 @@
37372 +/*
37373 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37374 + *
37375 + * Redistribution and use in source and binary forms, with or without
37376 + * modification, are permitted provided that the following conditions are met:
37377 + * * Redistributions of source code must retain the above copyright
37378 + * notice, this list of conditions and the following disclaimer.
37379 + * * Redistributions in binary form must reproduce the above copyright
37380 + * notice, this list of conditions and the following disclaimer in the
37381 + * documentation and/or other materials provided with the distribution.
37382 + * * Neither the name of Freescale Semiconductor nor the
37383 + * names of its contributors may be used to endorse or promote products
37384 + * derived from this software without specific prior written permission.
37385 + *
37386 + *
37387 + * ALTERNATIVELY, this software may be distributed under the terms of the
37388 + * GNU General Public License ("GPL") as published by the Free Software
37389 + * Foundation, either version 2 of that License or (at your option) any
37390 + * later version.
37391 + *
37392 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37393 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37394 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37395 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37396 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37397 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37398 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37399 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37400 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37401 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37402 + */
37403 +
37404 +
37405 +/******************************************************************************
37406 + @File fm_kg.h
37407 +
37408 + @Description FM KG private header
37409 +*//***************************************************************************/
37410 +#ifndef __FM_KG_H
37411 +#define __FM_KG_H
37412 +
37413 +#include "std_ext.h"
37414 +
37415 +/***********************************************************************/
37416 +/* Keygen defines */
37417 +/***********************************************************************/
37418 +/* maskes */
37419 +#if (DPAA_VERSION >= 11)
37420 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
37421 +#define KG_SCH_OM_VSPE 0x00000001
37422 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
37423 +
37424 +#define MAX_SP_SHIFT 23
37425 +#define KG_SCH_VSP_MASK_SHIFT 12
37426 +#define KG_SCH_VSP_SHIFT 24
37427 +#endif /* (DPAA_VERSION >= 11) */
37428 +
37429 +typedef uint32_t t_KnownFieldsMasks;
37430 +#define KG_SCH_KN_PORT_ID 0x80000000
37431 +#define KG_SCH_KN_MACDST 0x40000000
37432 +#define KG_SCH_KN_MACSRC 0x20000000
37433 +#define KG_SCH_KN_TCI1 0x10000000
37434 +#define KG_SCH_KN_TCI2 0x08000000
37435 +#define KG_SCH_KN_ETYPE 0x04000000
37436 +#define KG_SCH_KN_PPPSID 0x02000000
37437 +#define KG_SCH_KN_PPPID 0x01000000
37438 +#define KG_SCH_KN_MPLS1 0x00800000
37439 +#define KG_SCH_KN_MPLS2 0x00400000
37440 +#define KG_SCH_KN_MPLS_LAST 0x00200000
37441 +#define KG_SCH_KN_IPSRC1 0x00100000
37442 +#define KG_SCH_KN_IPDST1 0x00080000
37443 +#define KG_SCH_KN_PTYPE1 0x00040000
37444 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
37445 +#define KG_SCH_KN_IPV6FL1 0x00010000
37446 +#define KG_SCH_KN_IPSRC2 0x00008000
37447 +#define KG_SCH_KN_IPDST2 0x00004000
37448 +#define KG_SCH_KN_PTYPE2 0x00002000
37449 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
37450 +#define KG_SCH_KN_IPV6FL2 0x00000800
37451 +#define KG_SCH_KN_GREPTYPE 0x00000400
37452 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
37453 +#define KG_SCH_KN_IPSEC_NH 0x00000100
37454 +#define KG_SCH_KN_IPPID 0x00000080
37455 +#define KG_SCH_KN_L4PSRC 0x00000004
37456 +#define KG_SCH_KN_L4PDST 0x00000002
37457 +#define KG_SCH_KN_TFLG 0x00000001
37458 +
37459 +typedef uint8_t t_GenericCodes;
37460 +#define KG_SCH_GEN_SHIM1 0x70
37461 +#define KG_SCH_GEN_DEFAULT 0x10
37462 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
37463 +#define KG_SCH_GEN_START_OF_FRM 0x40
37464 +#define KG_SCH_GEN_SHIM2 0x71
37465 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
37466 +#define KG_SCH_GEN_ETH 0x03
37467 +#define KG_SCH_GEN_ETH_NO_V 0x73
37468 +#define KG_SCH_GEN_SNAP 0x04
37469 +#define KG_SCH_GEN_SNAP_NO_V 0x74
37470 +#define KG_SCH_GEN_VLAN1 0x05
37471 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
37472 +#define KG_SCH_GEN_VLAN2 0x06
37473 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
37474 +#define KG_SCH_GEN_ETH_TYPE 0x07
37475 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
37476 +#define KG_SCH_GEN_PPP 0x08
37477 +#define KG_SCH_GEN_PPP_NO_V 0x78
37478 +#define KG_SCH_GEN_MPLS1 0x09
37479 +#define KG_SCH_GEN_MPLS2 0x19
37480 +#define KG_SCH_GEN_MPLS3 0x29
37481 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
37482 +#define KG_SCH_GEN_MPLS_LAST 0x0a
37483 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
37484 +#define KG_SCH_GEN_IPV4 0x0b
37485 +#define KG_SCH_GEN_IPV6 0x1b
37486 +#define KG_SCH_GEN_L3_NO_V 0x7b
37487 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
37488 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
37489 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
37490 +#define KG_SCH_GEN_IP2_NO_V 0x7c
37491 +#define KG_SCH_GEN_GRE 0x0d
37492 +#define KG_SCH_GEN_GRE_NO_V 0x7d
37493 +#define KG_SCH_GEN_TCP 0x0e
37494 +#define KG_SCH_GEN_UDP 0x1e
37495 +#define KG_SCH_GEN_IPSEC_AH 0x2e
37496 +#define KG_SCH_GEN_SCTP 0x3e
37497 +#define KG_SCH_GEN_DCCP 0x4e
37498 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
37499 +#define KG_SCH_GEN_L4_NO_V 0x7e
37500 +#define KG_SCH_GEN_NEXTHDR 0x7f
37501 +/* shifts */
37502 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
37503 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
37504 +#define KG_SCH_PP_MASK_SHIFT 16
37505 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
37506 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
37507 +#define KG_SCH_DEF_TCI_SHIFT 28
37508 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
37509 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
37510 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
37511 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
37512 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
37513 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
37514 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
37515 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
37516 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
37517 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
37518 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
37519 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
37520 +#define KG_SCH_GEN_MASK_SHIFT 16
37521 +#define KG_SCH_GEN_HT_SHIFT 8
37522 +#define KG_SCH_GEN_SIZE_SHIFT 24
37523 +#define KG_SCH_GEN_DEF_SHIFT 29
37524 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
37525 +
37526 +/* others */
37527 +#define NUM_OF_SW_DEFAULTS 3
37528 +#define MAX_PP_SHIFT 23
37529 +#define MAX_KG_SCH_SIZE 16
37530 +#define MASK_FOR_GENERIC_BASE_ID 0x20
37531 +#define MAX_HASH_SHIFT 40
37532 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
37533 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
37534 +#define MAX_DIST_FQID_SHIFT 23
37535 +
37536 +#define GET_MASK_SEL_SHIFT(shift,i) \
37537 +switch (i) { \
37538 + case (0):shift = 26;break; \
37539 + case (1):shift = 20;break; \
37540 + case (2):shift = 10;break; \
37541 + case (3):shift = 4;break; \
37542 + default: \
37543 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37544 +}
37545 +
37546 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
37547 +switch (i) { \
37548 + case (0):shift = 16;break; \
37549 + case (1):shift = 0;break; \
37550 + case (2):shift = 28;break; \
37551 + case (3):shift = 24;break; \
37552 + default: \
37553 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37554 +}
37555 +
37556 +#define GET_MASK_SHIFT(shift,i) \
37557 +switch (i) { \
37558 + case (0):shift = 24;break; \
37559 + case (1):shift = 16;break; \
37560 + case (2):shift = 8;break; \
37561 + case (3):shift = 0;break; \
37562 + default: \
37563 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37564 +}
37565 +
37566 +/***********************************************************************/
37567 +/* Keygen defines */
37568 +/***********************************************************************/
37569 +
37570 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
37571 +#define NO_VALIDATION 0x70
37572 +#define KG_ACTION_REG_TO 1024
37573 +#define KG_MAX_PROFILE 255
37574 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
37575 +
37576 +
37577 +#endif /* __FM_KG_H */
37578 --- /dev/null
37579 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37580 @@ -0,0 +1,5571 @@
37581 +/*
37582 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37583 + *
37584 + * Redistribution and use in source and binary forms, with or without
37585 + * modification, are permitted provided that the following conditions are met:
37586 + * * Redistributions of source code must retain the above copyright
37587 + * notice, this list of conditions and the following disclaimer.
37588 + * * Redistributions in binary form must reproduce the above copyright
37589 + * notice, this list of conditions and the following disclaimer in the
37590 + * documentation and/or other materials provided with the distribution.
37591 + * * Neither the name of Freescale Semiconductor nor the
37592 + * names of its contributors may be used to endorse or promote products
37593 + * derived from this software without specific prior written permission.
37594 + *
37595 + *
37596 + * ALTERNATIVELY, this software may be distributed under the terms of the
37597 + * GNU General Public License ("GPL") as published by the Free Software
37598 + * Foundation, either version 2 of that License or (at your option) any
37599 + * later version.
37600 + *
37601 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37602 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37603 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37604 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37605 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37606 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37607 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37608 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37609 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37610 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37611 + */
37612 +
37613 +
37614 +/******************************************************************************
37615 + @File fm_manip.c
37616 +
37617 + @Description FM PCD manip ...
37618 + *//***************************************************************************/
37619 +#include "std_ext.h"
37620 +#include "error_ext.h"
37621 +#include "string_ext.h"
37622 +#include "debug_ext.h"
37623 +#include "fm_pcd_ext.h"
37624 +#include "fm_port_ext.h"
37625 +#include "fm_muram_ext.h"
37626 +#include "memcpy_ext.h"
37627 +
37628 +#include "fm_common.h"
37629 +#include "fm_hc.h"
37630 +#include "fm_manip.h"
37631 +
37632 +/****************************************/
37633 +/* static functions */
37634 +/****************************************/
37635 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
37636 +{
37637 + t_FmPcdManip *p_CurManip = p_Manip;
37638 +
37639 + if (!MANIP_IS_UNIFIED(p_Manip))
37640 + p_CurManip = p_Manip;
37641 + else
37642 + {
37643 + /* go to first unified */
37644 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37645 + p_CurManip = p_CurManip->h_PrevManip;
37646 + }
37647 +
37648 + switch (manipInfo)
37649 + {
37650 + case (e_MANIP_HMCT):
37651 + return p_CurManip->p_Hmct;
37652 + case (e_MANIP_HMTD):
37653 + return p_CurManip->h_Ad;
37654 + case (e_MANIP_HANDLER_TABLE_OWNER):
37655 + return (t_Handle)p_CurManip;
37656 + default:
37657 + return NULL;
37658 + }
37659 +}
37660 +
37661 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
37662 +{
37663 + uint16_t size = 0;
37664 + t_FmPcdManip *p_CurManip = p_Manip;
37665 +
37666 + if (!MANIP_IS_UNIFIED(p_Manip))
37667 + return p_Manip->tableSize;
37668 +
37669 + /* accumulate sizes, starting with the first node */
37670 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37671 + p_CurManip = p_CurManip->h_PrevManip;
37672 +
37673 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37674 + {
37675 + size += p_CurManip->tableSize;
37676 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37677 + }
37678 + size += p_CurManip->tableSize; /* add last size */
37679 +
37680 + return (size);
37681 +}
37682 +
37683 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
37684 +{
37685 + uint16_t size = 0;
37686 + t_FmPcdManip *p_CurManip = p_Manip;
37687 +
37688 + if (!MANIP_IS_UNIFIED(p_Manip))
37689 + return p_Manip->dataSize;
37690 +
37691 + /* accumulate sizes, starting with the first node */
37692 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
37693 + p_CurManip = p_CurManip->h_PrevManip;
37694 +
37695 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
37696 + {
37697 + size += p_CurManip->dataSize;
37698 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
37699 + }
37700 + size += p_CurManip->dataSize; /* add last size */
37701 +
37702 + return (size);
37703 +}
37704 +
37705 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
37706 + uint16_t *p_TableSize, uint8_t *p_DataSize)
37707 +{
37708 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
37709 +
37710 + if (p_FmPcdManipParams->u.hdr.rmv)
37711 + {
37712 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
37713 + {
37714 + case (e_FM_PCD_MANIP_RMV_GENERIC):
37715 + tableSize += HMCD_BASIC_SIZE;
37716 + break;
37717 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
37718 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
37719 + {
37720 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
37721 +#if (DPAA_VERSION >= 11)
37722 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
37723 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
37724 +#endif /* (DPAA_VERSION >= 11) */
37725 + tableSize += HMCD_BASIC_SIZE;
37726 + break;
37727 + default:
37728 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37729 + ("Unknown byHdr.type"));
37730 + }
37731 + break;
37732 + default:
37733 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37734 + ("Unknown rmvParams.type"));
37735 + }
37736 + }
37737 +
37738 + if (p_FmPcdManipParams->u.hdr.insrt)
37739 + {
37740 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
37741 + {
37742 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
37743 + remain =
37744 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37745 + % 4);
37746 + if (remain)
37747 + localDataSize =
37748 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
37749 + + 4 - remain);
37750 + else
37751 + localDataSize =
37752 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
37753 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
37754 + break;
37755 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
37756 + {
37757 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
37758 + {
37759 +
37760 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
37761 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
37762 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
37763 + {
37764 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
37765 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
37766 + dataSize +=
37767 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
37768 + break;
37769 + default:
37770 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
37771 + }
37772 + break;
37773 +#if (DPAA_VERSION >= 11)
37774 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
37775 + tableSize +=
37776 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
37777 + + HMCD_PARAM_SIZE
37778 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
37779 + dataSize += 2;
37780 + break;
37781 +
37782 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
37783 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
37784 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
37785 +
37786 + break;
37787 +
37788 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
37789 + tableSize +=
37790 + (HMCD_BASIC_SIZE
37791 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
37792 + break;
37793 +#endif /* (DPAA_VERSION >= 11) */
37794 + default:
37795 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37796 + ("Unknown byHdr.type"));
37797 + }
37798 + }
37799 + break;
37800 + default:
37801 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37802 + ("Unknown insrtParams.type"));
37803 + }
37804 + }
37805 +
37806 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
37807 + {
37808 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
37809 + {
37810 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
37811 + tableSize += HMCD_BASIC_SIZE;
37812 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
37813 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
37814 + {
37815 + tableSize += HMCD_PTR_SIZE;
37816 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
37817 + }
37818 + break;
37819 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
37820 + tableSize += HMCD_BASIC_SIZE;
37821 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37822 + & HDR_MANIP_IPV4_ID)
37823 + {
37824 + tableSize += HMCD_PARAM_SIZE;
37825 + dataSize += 2;
37826 + }
37827 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37828 + & HDR_MANIP_IPV4_SRC)
37829 + tableSize += HMCD_IPV4_ADDR_SIZE;
37830 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37831 + & HDR_MANIP_IPV4_DST)
37832 + tableSize += HMCD_IPV4_ADDR_SIZE;
37833 + break;
37834 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
37835 + tableSize += HMCD_BASIC_SIZE;
37836 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37837 + & HDR_MANIP_IPV6_SRC)
37838 + tableSize += HMCD_IPV6_ADDR_SIZE;
37839 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
37840 + & HDR_MANIP_IPV6_DST)
37841 + tableSize += HMCD_IPV6_ADDR_SIZE;
37842 + break;
37843 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
37844 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
37845 + == HDR_MANIP_TCP_UDP_CHECKSUM)
37846 + /* we implement this case with the update-checksum descriptor */
37847 + tableSize += HMCD_BASIC_SIZE;
37848 + else
37849 + /* we implement this case with the TCP/UDP-update descriptor */
37850 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
37851 + break;
37852 + default:
37853 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37854 + ("Unknown fieldUpdateParams.type"));
37855 + }
37856 + }
37857 +
37858 + if (p_FmPcdManipParams->u.hdr.custom)
37859 + {
37860 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
37861 + {
37862 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
37863 + {
37864 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
37865 + dataSize +=
37866 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
37867 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
37868 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
37869 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
37870 + dataSize += 2;
37871 + }
37872 + break;
37873 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
37874 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
37875 + break;
37876 + default:
37877 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
37878 + ("Unknown customParams.type"));
37879 + }
37880 + }
37881 +
37882 + *p_TableSize = tableSize;
37883 + *p_DataSize = dataSize;
37884 +
37885 + return E_OK;
37886 +}
37887 +
37888 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
37889 + uint8_t *parseArrayOffset)
37890 +{
37891 + e_NetHeaderType hdr = p_HdrInfo->hdr;
37892 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
37893 + bool byField = p_HdrInfo->byField;
37894 + t_FmPcdFields field;
37895 +
37896 + if (byField)
37897 + field = p_HdrInfo->fullField;
37898 +
37899 + if (byField)
37900 + {
37901 + switch (hdr)
37902 + {
37903 + case (HEADER_TYPE_ETH):
37904 + switch (field.eth)
37905 + {
37906 + case (NET_HEADER_FIELD_ETH_TYPE):
37907 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
37908 + break;
37909 + default:
37910 + RETURN_ERROR(
37911 + MAJOR,
37912 + E_NOT_SUPPORTED,
37913 + ("Header manipulation of the type Ethernet with this field not supported"));
37914 + }
37915 + break;
37916 + case (HEADER_TYPE_VLAN):
37917 + switch (field.vlan)
37918 + {
37919 + case (NET_HEADER_FIELD_VLAN_TCI):
37920 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
37921 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
37922 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
37923 + else
37924 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
37925 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
37926 + break;
37927 + default:
37928 + RETURN_ERROR(
37929 + MAJOR,
37930 + E_NOT_SUPPORTED,
37931 + ("Header manipulation of the type VLAN with this field not supported"));
37932 + }
37933 + break;
37934 + default:
37935 + RETURN_ERROR(
37936 + MAJOR,
37937 + E_NOT_SUPPORTED,
37938 + ("Header manipulation of this header by field not supported"));
37939 + }
37940 + }
37941 + else
37942 + {
37943 + switch (hdr)
37944 + {
37945 + case (HEADER_TYPE_ETH):
37946 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
37947 + break;
37948 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
37949 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
37950 + break;
37951 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
37952 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
37953 + break;
37954 + case (HEADER_TYPE_LLC_SNAP):
37955 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
37956 + break;
37957 + case (HEADER_TYPE_PPPoE):
37958 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
37959 + break;
37960 + case (HEADER_TYPE_MPLS):
37961 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
37962 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
37963 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
37964 + else
37965 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
37966 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
37967 + break;
37968 + case (HEADER_TYPE_IPv4):
37969 + case (HEADER_TYPE_IPv6):
37970 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
37971 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
37972 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
37973 + else
37974 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
37975 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
37976 + break;
37977 + case (HEADER_TYPE_MINENCAP):
37978 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
37979 + break;
37980 + case (HEADER_TYPE_GRE):
37981 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
37982 + break;
37983 + case (HEADER_TYPE_TCP):
37984 + case (HEADER_TYPE_UDP):
37985 + case (HEADER_TYPE_IPSEC_AH):
37986 + case (HEADER_TYPE_IPSEC_ESP):
37987 + case (HEADER_TYPE_DCCP):
37988 + case (HEADER_TYPE_SCTP):
37989 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
37990 + break;
37991 + case (HEADER_TYPE_CAPWAP):
37992 + case (HEADER_TYPE_CAPWAP_DTLS):
37993 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
37994 + break;
37995 + default:
37996 + RETURN_ERROR(
37997 + MAJOR,
37998 + E_NOT_SUPPORTED,
37999 + ("Header manipulation of this header is not supported"));
38000 + }
38001 + }
38002 + return E_OK;
38003 +}
38004 +
38005 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
38006 + t_FmPcdManipParams *p_FmPcdManipParams,
38007 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
38008 +{
38009 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
38010 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
38011 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
38012 + p_DestData;
38013 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
38014 + uint8_t j = 0;
38015 +
38016 + if (p_FmPcdManipParams->u.hdr.rmv)
38017 + {
38018 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38019 + == e_FM_PCD_MANIP_RMV_GENERIC)
38020 + {
38021 + /* initialize HMCD */
38022 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
38023 + /* tmp, should be conditional */
38024 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
38025 + << HMCD_RMV_OFFSET_SHIFT;
38026 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
38027 + << HMCD_RMV_SIZE_SHIFT;
38028 + }
38029 + else
38030 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38031 + == e_FM_PCD_MANIP_RMV_BY_HDR)
38032 + {
38033 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38034 + {
38035 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38036 + {
38037 + uint8_t hmcdOpt;
38038 +
38039 + /* initialize HMCD */
38040 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
38041 +
38042 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
38043 + {
38044 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
38045 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
38046 + break;
38047 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
38048 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
38049 + break;
38050 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
38051 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
38052 + break;
38053 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
38054 + hmcdOpt = HMCD_RMV_L2_MPLS;
38055 + break;
38056 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
38057 + hmcdOpt = HMCD_RMV_L2_PPPOE;
38058 + break;
38059 + default:
38060 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38061 + }
38062 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38063 + break;
38064 + }
38065 +#if (DPAA_VERSION >= 11)
38066 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38067 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
38068 + << HMCD_OC_SHIFT;
38069 + break;
38070 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38071 + {
38072 + uint8_t prsArrayOffset;
38073 + t_Error err = E_OK;
38074 +
38075 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
38076 + << HMCD_OC_SHIFT;
38077 +
38078 + err =
38079 + GetPrOffsetByHeaderOrField(
38080 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
38081 + &prsArrayOffset);
38082 + ASSERT_COND(!err);
38083 + /* was previously checked */
38084 +
38085 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
38086 + }
38087 + break;
38088 +#endif /* (DPAA_VERSION >= 11) */
38089 + default:
38090 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38091 + ("manip header remove by hdr type!"));
38092 + }
38093 + }
38094 +
38095 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38096 + /* save a pointer to the "last" indication word */
38097 + p_Last = p_TmpHmct;
38098 + /* advance to next command */
38099 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38100 + }
38101 +
38102 + if (p_FmPcdManipParams->u.hdr.insrt)
38103 + {
38104 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38105 + == e_FM_PCD_MANIP_INSRT_GENERIC)
38106 + {
38107 + /* initialize HMCD */
38108 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
38109 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
38110 + << HMCD_OC_SHIFT;
38111 + else
38112 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
38113 +
38114 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
38115 + << HMCD_INSRT_OFFSET_SHIFT;
38116 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38117 + << HMCD_INSRT_SIZE_SHIFT;
38118 +
38119 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38120 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
38121 +
38122 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38123 + /* save a pointer to the "last" indication word */
38124 + p_Last = p_TmpHmct;
38125 +
38126 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38127 +
38128 + /* initialize data to be inserted */
38129 + /* if size is not a multiple of 4, padd with 0's */
38130 + origSize = size;
38131 + remain = (uint8_t)(size % 4);
38132 + if (remain)
38133 + {
38134 + size += (uint8_t)(4 - remain);
38135 + p_LocalData = (uint32_t *)XX_Malloc(size);
38136 + memset((uint8_t *)p_LocalData, 0, size);
38137 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
38138 + }
38139 + else
38140 + p_LocalData = (uint32_t*)p_UsrData;
38141 +
38142 + /* initialize data and advance pointer to next command */
38143 + MemCpy8(p_TmpHmct, p_LocalData, size);
38144 + p_TmpHmct += size / sizeof(uint32_t);
38145 +
38146 + if (remain)
38147 + XX_Free(p_LocalData);
38148 + }
38149 +
38150 + else
38151 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38152 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
38153 + {
38154 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38155 + {
38156 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38157 + {
38158 + uint8_t hmcdOpt;
38159 +
38160 + /* initialize HMCD */
38161 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
38162 + << HMCD_OC_SHIFT;
38163 +
38164 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38165 + {
38166 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38167 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
38168 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
38169 + else
38170 + hmcdOpt = HMCD_INSRT_L2_MPLS;
38171 + break;
38172 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38173 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
38174 + break;
38175 + default:
38176 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38177 + }
38178 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38179 +
38180 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38181 + /* save a pointer to the "last" indication word */
38182 + p_Last = p_TmpHmct;
38183 +
38184 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38185 +
38186 + /* set size and pointer of user's data */
38187 + size =
38188 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38189 +
38190 + ASSERT_COND(p_TmpData);
38191 + MemCpy8(
38192 + p_TmpData,
38193 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
38194 + size);
38195 + tmpReg =
38196 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
38197 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
38198 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38199 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38200 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38201 + p_TmpData += size;
38202 + }
38203 + break;
38204 +#if (DPAA_VERSION >= 11)
38205 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38206 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
38207 + << HMCD_OC_SHIFT;
38208 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
38209 + tmpReg |= HMCD_IP_L4_CS_CALC;
38210 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
38211 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
38212 + tmpReg |= HMCD_IP_OR_QOS;
38213 + tmpReg |=
38214 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
38215 + & HMCD_IP_LAST_PID_MASK;
38216 + tmpReg |=
38217 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38218 + << HMCD_IP_SIZE_SHIFT)
38219 + & HMCD_IP_SIZE_MASK);
38220 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
38221 + tmpReg |= HMCD_IP_DF_MODE;
38222 +
38223 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38224 +
38225 + /* save a pointer to the "last" indication word */
38226 + p_Last = p_TmpHmct;
38227 +
38228 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38229 +
38230 + /* set IP id */
38231 + ASSERT_COND(p_TmpData);
38232 + WRITE_UINT16(
38233 + *(uint16_t*)p_TmpData,
38234 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
38235 + WRITE_UINT32(
38236 + *p_TmpHmct,
38237 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38238 + p_TmpData += 2;
38239 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38240 +
38241 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
38242 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
38243 +
38244 + MemCpy8(
38245 + p_TmpHmct,
38246 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
38247 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38248 + p_TmpHmct +=
38249 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38250 + / 4;
38251 + break;
38252 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38253 + tmpReg = HMCD_INSRT_UDP_LITE;
38254 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38255 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
38256 + << HMCD_OC_SHIFT;
38257 +
38258 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38259 +
38260 + /* save a pointer to the "last" indication word */
38261 + p_Last = p_TmpHmct;
38262 +
38263 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38264 +
38265 + MemCpy8(
38266 + p_TmpHmct,
38267 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38268 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38269 + p_TmpHmct +=
38270 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38271 + / 4;
38272 + break;
38273 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38274 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
38275 + << HMCD_OC_SHIFT;
38276 + tmpReg |= HMCD_CAPWAP_INSRT;
38277 +
38278 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38279 +
38280 + /* save a pointer to the "last" indication word */
38281 + p_Last = p_TmpHmct;
38282 +
38283 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38284 +
38285 + MemCpy8(
38286 + p_TmpHmct,
38287 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38288 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38289 + p_TmpHmct +=
38290 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38291 + / 4;
38292 + break;
38293 +#endif /* (DPAA_VERSION >= 11) */
38294 + default:
38295 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38296 + ("manip header insert by header type!"));
38297 +
38298 + }
38299 + }
38300 + }
38301 +
38302 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38303 + {
38304 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38305 + {
38306 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38307 + /* set opcode */
38308 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
38309 + << HMCD_OC_SHIFT;
38310 +
38311 + /* set mode & table pointer */
38312 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38313 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38314 + {
38315 + /* set Mode */
38316 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
38317 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
38318 + /* set VPRI default */
38319 + tmpReg |=
38320 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
38321 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38322 + /* save a pointer to the "last" indication word */
38323 + p_Last = p_TmpHmct;
38324 + /* write the table pointer into the Manip descriptor */
38325 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38326 +
38327 + tmpReg = 0;
38328 + ASSERT_COND(p_TmpData);
38329 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
38330 + {
38331 + /* first we build from each 8 values a 32bit register */
38332 + tmpReg |=
38333 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
38334 + << (32 - 4 * (j + 1));
38335 + j++;
38336 + /* Than we write this register to the next table word
38337 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
38338 + if ((i % 8) == 7)
38339 + {
38340 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
38341 + tmpReg);
38342 + tmpReg = 0;
38343 + j = 0;
38344 + }
38345 + }
38346 +
38347 + WRITE_UINT32(
38348 + *p_TmpHmct,
38349 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38350 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38351 +
38352 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
38353 + }
38354 + else
38355 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38356 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
38357 + {
38358 + /* set Mode */
38359 + /* line commented out as it has no-side-effect ('0' value). */
38360 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
38361 + /* set VPRI parameter */
38362 + tmpReg |=
38363 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
38364 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38365 + /* save a pointer to the "last" indication word */
38366 + p_Last = p_TmpHmct;
38367 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38368 + }
38369 + break;
38370 +
38371 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38372 + /* set opcode */
38373 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
38374 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38375 + & HDR_MANIP_IPV4_TTL)
38376 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
38377 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38378 + & HDR_MANIP_IPV4_TOS)
38379 + {
38380 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
38381 + tmpReg |=
38382 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
38383 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
38384 + }
38385 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38386 + & HDR_MANIP_IPV4_ID)
38387 + tmpReg |= HMCD_IPV4_UPDATE_ID;
38388 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38389 + & HDR_MANIP_IPV4_SRC)
38390 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
38391 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38392 + & HDR_MANIP_IPV4_DST)
38393 + tmpReg |= HMCD_IPV4_UPDATE_DST;
38394 + /* write the first 4 bytes of the descriptor */
38395 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38396 + /* save a pointer to the "last" indication word */
38397 + p_Last = p_TmpHmct;
38398 +
38399 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38400 +
38401 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38402 + & HDR_MANIP_IPV4_ID)
38403 + {
38404 + ASSERT_COND(p_TmpData);
38405 + WRITE_UINT16(
38406 + *(uint16_t*)p_TmpData,
38407 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
38408 + WRITE_UINT32(
38409 + *p_TmpHmct,
38410 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38411 + p_TmpData += 2;
38412 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38413 + }
38414 +
38415 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38416 + & HDR_MANIP_IPV4_SRC)
38417 + {
38418 + WRITE_UINT32(
38419 + *p_TmpHmct,
38420 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
38421 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38422 + }
38423 +
38424 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38425 + & HDR_MANIP_IPV4_DST)
38426 + {
38427 + WRITE_UINT32(
38428 + *p_TmpHmct,
38429 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
38430 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38431 + }
38432 + break;
38433 +
38434 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38435 + /* set opcode */
38436 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
38437 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38438 + & HDR_MANIP_IPV6_HL)
38439 + tmpReg |= HMCD_IPV6_UPDATE_HL;
38440 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38441 + & HDR_MANIP_IPV6_TC)
38442 + {
38443 + tmpReg |= HMCD_IPV6_UPDATE_TC;
38444 + tmpReg |=
38445 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
38446 + << HMCD_IPV6_UPDATE_TC_SHIFT;
38447 + }
38448 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38449 + & HDR_MANIP_IPV6_SRC)
38450 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
38451 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38452 + & HDR_MANIP_IPV6_DST)
38453 + tmpReg |= HMCD_IPV6_UPDATE_DST;
38454 + /* write the first 4 bytes of the descriptor */
38455 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38456 + /* save a pointer to the "last" indication word */
38457 + p_Last = p_TmpHmct;
38458 +
38459 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38460 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38461 + & HDR_MANIP_IPV6_SRC)
38462 + {
38463 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38464 + {
38465 + memcpy(&tmp_ipv6_addr,
38466 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
38467 + sizeof(uint32_t));
38468 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38469 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38470 + }
38471 + }
38472 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38473 + & HDR_MANIP_IPV6_DST)
38474 + {
38475 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38476 + {
38477 + memcpy(&tmp_ipv6_addr,
38478 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
38479 + sizeof(uint32_t));
38480 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38481 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38482 + }
38483 + }
38484 + break;
38485 +
38486 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38487 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38488 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38489 + {
38490 + /* we implement this case with the update-checksum descriptor */
38491 + /* set opcode */
38492 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
38493 + << HMCD_OC_SHIFT;
38494 + /* write the first 4 bytes of the descriptor */
38495 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38496 + /* save a pointer to the "last" indication word */
38497 + p_Last = p_TmpHmct;
38498 +
38499 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38500 + }
38501 + else
38502 + {
38503 + /* we implement this case with the TCP/UDP update descriptor */
38504 + /* set opcode */
38505 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
38506 + << HMCD_OC_SHIFT;
38507 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38508 + & HDR_MANIP_TCP_UDP_DST)
38509 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
38510 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38511 + & HDR_MANIP_TCP_UDP_SRC)
38512 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
38513 + /* write the first 4 bytes of the descriptor */
38514 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38515 + /* save a pointer to the "last" indication word */
38516 + p_Last = p_TmpHmct;
38517 +
38518 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38519 +
38520 + tmpReg = 0;
38521 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38522 + & HDR_MANIP_TCP_UDP_SRC)
38523 + tmpReg |=
38524 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
38525 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
38526 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38527 + & HDR_MANIP_TCP_UDP_DST)
38528 + tmpReg |=
38529 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
38530 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38531 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38532 + }
38533 + break;
38534 +
38535 + default:
38536 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38537 + ("Unknown fieldUpdateParams.type"));
38538 + }
38539 + }
38540 +
38541 + if (p_FmPcdManipParams->u.hdr.custom)
38542 + {
38543 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38544 + {
38545 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38546 + /* set opcode */
38547 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
38548 +
38549 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
38550 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
38551 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38552 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
38553 + /* line commented out as it has no-side-effect ('0' value). */
38554 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
38555 + else
38556 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38557 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38558 + {
38559 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
38560 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
38561 + tmpReg |= HMCD_IP_REPLACE_ID;
38562 + }
38563 + else
38564 + RETURN_ERROR(
38565 + MINOR,
38566 + E_NOT_SUPPORTED,
38567 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
38568 +
38569 + /* write the first 4 bytes of the descriptor */
38570 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38571 + /* save a pointer to the "last" indication word */
38572 + p_Last = p_TmpHmct;
38573 +
38574 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38575 +
38576 + size =
38577 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38578 + ASSERT_COND(p_TmpData);
38579 + MemCpy8(
38580 + p_TmpData,
38581 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
38582 + size);
38583 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
38584 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
38585 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38586 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38587 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38588 + p_TmpData += size;
38589 +
38590 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38591 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38592 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38593 + {
38594 + WRITE_UINT16(
38595 + *(uint16_t*)p_TmpData,
38596 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
38597 + WRITE_UINT32(
38598 + *p_TmpHmct,
38599 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38600 + p_TmpData += 2;
38601 + }
38602 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38603 + break;
38604 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38605 + /* set opcode */
38606 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
38607 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
38608 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
38609 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
38610 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38611 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
38612 +
38613 + /* write the first 4 bytes of the descriptor */
38614 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38615 + /* save a pointer to the "last" indication word */
38616 + p_Last = p_TmpHmct;
38617 +
38618 + p_TmpHmct += HMCD_BASIC_SIZE/4;
38619 +
38620 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38621 + {
38622 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
38623 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
38624 + /* write the next 4 bytes of the descriptor */
38625 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38626 + }
38627 + p_TmpHmct += HMCD_PARAM_SIZE/4;
38628 + break;
38629 + default:
38630 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38631 + ("Unknown customParams.type"));
38632 + }
38633 + }
38634 +
38635 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
38636 + the old table and should be freed */
38637 + if (p_FmPcdManipParams->h_NextManip
38638 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38639 + && (MANIP_DONT_REPARSE(p_Manip)))
38640 + {
38641 + if (new)
38642 + {
38643 + /* If this is the first time this manip is created we need to free unused memory. If it
38644 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
38645 + * table - no allocation, no free */
38646 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
38647 +
38648 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
38649 + }
38650 + }
38651 + else
38652 + {
38653 + ASSERT_COND(p_Last);
38654 + /* set the "last" indication on the last command of the current table */
38655 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
38656 + }
38657 +
38658 + return E_OK;
38659 +}
38660 +
38661 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
38662 + t_FmPcdManipParams *p_FmPcdManipParams)
38663 +{
38664 + t_FmPcdManip *p_CurManip;
38665 + t_Error err;
38666 + uint32_t nextSize = 0, totalSize;
38667 + uint16_t tmpReg;
38668 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
38669 +
38670 + /* set Manip structure */
38671 +
38672 + p_Manip->dontParseAfterManip =
38673 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
38674 +
38675 + if (p_FmPcdManipParams->h_NextManip)
38676 + { /* Next Header manipulation exists */
38677 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
38678 +
38679 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
38680 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
38681 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
38682 + else /* either parsing is required or next manip is Frag; no table merging. */
38683 + p_Manip->cascaded = TRUE;
38684 + /* pass up the "cascaded" attribute. The whole chain is cascaded
38685 + * if something is cascaded along the way. */
38686 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
38687 + p_Manip->cascaded = TRUE;
38688 + }
38689 +
38690 + /* Allocate new table */
38691 + /* calculate table size according to manip parameters */
38692 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
38693 + &p_Manip->dataSize);
38694 + if (err)
38695 + RETURN_ERROR(MINOR, err, NO_MSG);
38696 +
38697 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
38698 +
38699 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
38700 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
38701 + if (!p_Manip->p_Hmct)
38702 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
38703 +
38704 + if (p_Manip->dataSize)
38705 + p_Manip->p_Data =
38706 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
38707 +
38708 + /* update shadow size to allow runtime replacement of Header manipulation */
38709 + /* The allocated shadow is divided as follows:
38710 + 0 . . . 16 . . .
38711 + --------------------------------
38712 + | Shadow | Shadow HMTD |
38713 + | HMTD | Match Table |
38714 + | (16 bytes) | (maximal size) |
38715 + --------------------------------
38716 + */
38717 +
38718 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
38719 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
38720 + if (err != E_OK)
38721 + {
38722 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38723 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
38724 + ("MURAM allocation for HdrManip node shadow"));
38725 + }
38726 +
38727 + if (p_FmPcdManipParams->h_NextManip
38728 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38729 + && (MANIP_DONT_REPARSE(p_Manip)))
38730 + {
38731 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
38732 + e_MANIP_HMCT);
38733 + p_CurManip = p_FmPcdManipParams->h_NextManip;
38734 + /* Run till the last Manip (which is the first to configure) */
38735 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38736 + p_CurManip = p_CurManip->h_NextManip;
38737 +
38738 + while (p_CurManip)
38739 + {
38740 + /* If this is a unified table, point to the part of the table
38741 + * which is the relative offset in HMCT.
38742 + */
38743 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38744 + (p_Manip->tableSize +
38745 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
38746 + PTR_TO_UINT(p_OldHmct))));
38747 + if (p_CurManip->p_Data)
38748 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
38749 + (p_Manip->tableSize +
38750 + (PTR_TO_UINT(p_CurManip->p_Data) -
38751 + PTR_TO_UINT(p_OldHmct))));
38752 + else
38753 + p_TmpDataPtr = NULL;
38754 +
38755 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
38756 + p_TmpDataPtr, FALSE);
38757 + /* update old manip table pointer */
38758 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
38759 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
38760 +
38761 + p_CurManip = p_CurManip->h_PrevManip;
38762 + }
38763 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
38764 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
38765 + p_OldHmct);
38766 + }
38767 +
38768 + /* Fill table */
38769 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
38770 + p_Manip->p_Data, TRUE);
38771 + if (err)
38772 + {
38773 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
38774 + RETURN_ERROR(MINOR, err, NO_MSG);
38775 + }
38776 +
38777 + /* Build HMTD (table descriptor) */
38778 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
38779 +
38780 + /* add parseAfterManip */
38781 + if (!p_Manip->dontParseAfterManip)
38782 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
38783 +
38784 + /* create cascade */
38785 + /*if (p_FmPcdManipParams->h_NextManip
38786 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
38787 + if (p_Manip->cascaded)
38788 + {
38789 + uint16_t nextAd;
38790 + /* indicate that there's another HM table descriptor */
38791 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
38792 + /* get address of next HMTD (table descriptor; h_Ad).
38793 + * If the next HMTD was removed due to table unifing, get the address
38794 + * of the "next next" as written in the h_Ad of the next h_Manip node.
38795 + */
38796 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
38797 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
38798 + else
38799 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
38800 +
38801 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
38802 + }
38803 +
38804 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
38805 + WRITE_UINT32(
38806 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
38807 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38808 +
38809 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
38810 +
38811 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
38812 + {
38813 + /* The HMTD of the next Manip is never going to be used */
38814 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
38815 + FM_MURAM_FreeMem(
38816 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
38817 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
38818 + else
38819 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
38820 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
38821 + }
38822 +
38823 + return E_OK;
38824 +}
38825 +
38826 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
38827 + t_FmPcdManipParams *p_FmPcdManipParams)
38828 +{
38829 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
38830 + uint16_t newSize;
38831 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
38832 + t_Error err;
38833 + t_FmPcdManip *p_CurManip = p_Manip;
38834 +
38835 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
38836 + if (err)
38837 + RETURN_ERROR(MINOR, err, NO_MSG);
38838 +
38839 + /* check coherency of new table parameters */
38840 + if (newSize > p_Manip->tableSize)
38841 + RETURN_ERROR(
38842 + MINOR,
38843 + E_INVALID_VALUE,
38844 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
38845 + if (newDataSize > p_Manip->dataSize)
38846 + RETURN_ERROR(
38847 + MINOR,
38848 + E_INVALID_VALUE,
38849 + ("New Hdr Manip configuration requires larger size than current one (data)."));
38850 + if (p_FmPcdManipParams->h_NextManip)
38851 + RETURN_ERROR(
38852 + MINOR, E_INVALID_VALUE,
38853 + ("New Hdr Manip configuration can not contain h_NextManip."));
38854 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
38855 + RETURN_ERROR(
38856 + MINOR,
38857 + E_INVALID_VALUE,
38858 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
38859 + if (p_Manip->dontParseAfterManip
38860 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
38861 + RETURN_ERROR(
38862 + MINOR,
38863 + E_INVALID_VALUE,
38864 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
38865 +
38866 + p_Manip->tableSize = newSize;
38867 + p_Manip->dataSize = newDataSize;
38868 +
38869 + /* Build the new table in the shadow */
38870 + if (!MANIP_IS_UNIFIED(p_Manip))
38871 + {
38872 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
38873 + if (p_Manip->p_Data)
38874 + p_TmpDataPtr =
38875 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
38876 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
38877 +
38878 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
38879 + FALSE);
38880 + }
38881 + else
38882 + {
38883 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
38884 + ASSERT_COND(p_WholeHmct);
38885 +
38886 + /* Run till the last Manip (which is the first to configure) */
38887 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38888 + p_CurManip = p_CurManip->h_NextManip;
38889 +
38890 + while (p_CurManip)
38891 + {
38892 + /* If this is a non-head node in a unified table, point to the part of the shadow
38893 + * which is the relative offset in HMCT.
38894 + * else, point to the beginning of the
38895 + * shadow table (we save 16 for the HMTD.
38896 + */
38897 + p_TmpHmctPtr =
38898 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
38899 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
38900 + if (p_CurManip->p_Data)
38901 + p_TmpDataPtr =
38902 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
38903 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
38904 +
38905 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
38906 + p_TmpDataPtr, FALSE);
38907 + p_CurManip = p_CurManip->h_PrevManip;
38908 + }
38909 + }
38910 +
38911 + return E_OK;
38912 +}
38913 +
38914 +static t_Error CreateManipActionBackToOrig(
38915 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
38916 +{
38917 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
38918 + t_FmPcdManip *p_CurManip = p_Manip;
38919 +
38920 + /* Build the new table in the shadow */
38921 + if (!MANIP_IS_UNIFIED(p_Manip))
38922 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
38923 + FALSE);
38924 + else
38925 + {
38926 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
38927 + ASSERT_COND(p_WholeHmct);
38928 +
38929 + /* Run till the last Manip (which is the first to configure) */
38930 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38931 + p_CurManip = p_CurManip->h_NextManip;
38932 +
38933 + while (p_CurManip)
38934 + {
38935 + /* If this is a unified table, point to the part of the table
38936 + * which is the relative offset in HMCT.
38937 + */
38938 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
38939 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
38940 +
38941 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
38942 + p_TmpDataPtr, FALSE);
38943 +
38944 + p_CurManip = p_CurManip->h_PrevManip;
38945 + }
38946 + }
38947 +
38948 + return E_OK;
38949 +}
38950 +
38951 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
38952 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
38953 +{
38954 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
38955 + t_Handle p_Ad;
38956 + uint32_t tmpReg32 = 0;
38957 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
38958 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
38959 +
38960 + switch (p_Manip->opcode)
38961 + {
38962 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
38963 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
38964 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
38965 + {
38966 + tmpReg32 =
38967 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
38968 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
38969 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
38970 + tmpReg32;
38971 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
38972 + p_Manip->icOffset = icOffset;
38973 + }
38974 + else
38975 + {
38976 + if (p_Manip->icOffset != icOffset)
38977 + RETURN_ERROR(
38978 + MAJOR,
38979 + E_INVALID_VALUE,
38980 + ("this manipulation was updated previously by different value"););
38981 + }
38982 + break;
38983 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
38984 + if (p_Manip->h_Frag)
38985 + {
38986 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
38987 + {
38988 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
38989 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
38990 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
38991 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
38992 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
38993 + p_Manip->icOffset = icOffset;
38994 + }
38995 + else
38996 + {
38997 + if (p_Manip->icOffset != icOffset)
38998 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
38999 + }
39000 + }
39001 + break;
39002 + }
39003 +
39004 + return E_OK;
39005 +}
39006 +
39007 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
39008 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
39009 +{
39010 +
39011 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39012 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39013 + t_Error err;
39014 + uint32_t tmpReg32;
39015 +
39016 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39017 +
39018 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39019 + SANITY_CHECK_RETURN_ERROR(
39020 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
39021 + E_INVALID_STATE);
39022 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
39023 +
39024 + if (p_Manip->updateParams)
39025 + {
39026 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
39027 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39028 + RETURN_ERROR(
39029 + MAJOR, E_INVALID_STATE,
39030 + ("in this stage parameters from Port has not be updated"));
39031 +
39032 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39033 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39034 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39035 +
39036 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39037 + if (err)
39038 + RETURN_ERROR(MAJOR, err, NO_MSG);
39039 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39040 + RETURN_ERROR(
39041 + MAJOR, E_INVALID_STATE,
39042 + ("Parser result offset wasn't configured previousely"));
39043 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39044 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
39045 +#endif
39046 + }
39047 + else
39048 + if (validate)
39049 + {
39050 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39051 + || (p_Manip->updateParams & OFFSET_OF_PR))
39052 + RETURN_ERROR(
39053 + MAJOR, E_INVALID_STATE,
39054 + ("in this stage parameters from Port has be updated"));
39055 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39056 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39057 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39058 +
39059 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39060 + if (err)
39061 + RETURN_ERROR(MAJOR, err, NO_MSG);
39062 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39063 + RETURN_ERROR(
39064 + MAJOR, E_INVALID_STATE,
39065 + ("Parser result offset wasn't configured previousely"));
39066 +
39067 + }
39068 +
39069 + ASSERT_COND(p_Ad);
39070 +
39071 + if (p_Manip->updateParams & OFFSET_OF_PR)
39072 + {
39073 + tmpReg32 = 0;
39074 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
39075 + WRITE_UINT32(p_Ad->matchTblPtr,
39076 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
39077 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39078 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39079 + }
39080 + else
39081 + if (validate)
39082 + {
39083 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
39084 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
39085 + RETURN_ERROR(
39086 + MAJOR,
39087 + E_INVALID_STATE,
39088 + ("this manipulation was updated previousely by different value"););
39089 + }
39090 +
39091 + return E_OK;
39092 +}
39093 +
39094 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
39095 +{
39096 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39097 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
39098 + uint32_t tmpReg32 = 0;
39099 +
39100 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39101 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39102 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39103 + 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);
39104 +
39105 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39106 +
39107 + if (p_Manip->updateParams)
39108 + {
39109 +
39110 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39111 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39112 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39113 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39114 + if (!p_SavedManipParams)
39115 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39116 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
39117 +
39118 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39119 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
39120 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39121 +
39122 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39123 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39124 + }
39125 + else if (validate)
39126 + {
39127 +
39128 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39129 + if (!p_SavedManipParams)
39130 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39131 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
39132 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39133 + }
39134 +
39135 + return E_OK;
39136 +}
39137 +
39138 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
39139 + t_FmPcdManip *p_Manip,
39140 + t_Handle h_Ad,
39141 + bool validate,
39142 + t_Handle h_FmTree)
39143 +{
39144 + t_AdOfTypeContLookup *p_Ad;
39145 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39146 + t_Error err;
39147 + uint32_t tmpReg32 = 0;
39148 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
39149 +
39150 + UNUSED(h_Ad);
39151 +
39152 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39153 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39154 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39155 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
39156 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39157 +
39158 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39159 +
39160 + if (p_Manip->updateParams)
39161 + {
39162 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39163 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39164 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39165 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39166 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39167 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39168 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
39169 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
39170 +
39171 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39172 + if (err)
39173 + RETURN_ERROR(MAJOR, err, NO_MSG);
39174 +
39175 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39176 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39177 +
39178 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
39179 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39180 +
39181 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39182 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
39183 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39184 +
39185 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
39186 + }
39187 + else if (validate)
39188 + {
39189 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
39190 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
39191 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39192 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39193 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39194 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39195 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39196 + if (err)
39197 + RETURN_ERROR(MAJOR, err, NO_MSG);
39198 +
39199 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39200 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39201 + }
39202 +
39203 + if (p_Manip->updateParams)
39204 + {
39205 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39206 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
39207 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39208 +
39209 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39210 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39211 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39212 + }
39213 + else if (validate)
39214 + {
39215 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
39216 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39217 + }
39218 +
39219 + return E_OK;
39220 +}
39221 +
39222 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
39223 + t_Handle h_FmPort,
39224 + t_FmPcdManip *p_Manip,
39225 + t_Handle h_Ad,
39226 + bool validate)
39227 +{
39228 + t_CapwapReasmPram *p_ReassmTbl;
39229 + t_Error err;
39230 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39231 + uint8_t i = 0;
39232 + uint16_t size;
39233 + uint32_t tmpReg32;
39234 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39235 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
39236 +
39237 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39238 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39239 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
39240 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
39241 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
39242 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
39243 +
39244 + if (p_Manip->h_FmPcd != h_FmPcd)
39245 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39246 + ("handler of PCD previously was initiated by different value"));
39247 +
39248 + UNUSED(h_Ad);
39249 +
39250 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39251 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
39252 +
39253 + if (p_Manip->updateParams)
39254 + {
39255 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
39256 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
39257 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
39258 + !(p_Manip->updateParams & HW_PORT_ID)) ||
39259 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
39260 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
39261 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
39262 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39263 +
39264 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39265 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39266 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39267 +
39268 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39269 + if (err)
39270 + RETURN_ERROR(MAJOR, err, NO_MSG);
39271 +
39272 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39273 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
39274 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39275 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
39276 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39277 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39278 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39279 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
39280 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39281 + }
39282 + else if (validate)
39283 + {
39284 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
39285 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
39286 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
39287 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
39288 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
39289 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
39290 + (p_Manip->updateParams & HW_PORT_ID)))
39291 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39292 +
39293 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39294 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39295 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39296 +
39297 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39298 + if (err)
39299 + RETURN_ERROR(MAJOR, err, NO_MSG);
39300 +
39301 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39302 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
39303 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39304 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
39305 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39306 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39307 + }
39308 +
39309 + if (p_Manip->updateParams)
39310 + {
39311 + if (p_Manip->updateParams & NUM_OF_TASKS)
39312 + {
39313 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
39314 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
39315 + if (size > 255)
39316 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
39317 +
39318 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
39319 +
39320 + /*p_ReassmFrmDescrIndxPoolTbl*/
39321 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
39322 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39323 + (uint32_t)(size + 1),
39324 + 4);
39325 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
39326 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
39327 +
39328 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
39329 +
39330 + for ( i = 0; i < size; i++)
39331 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
39332 +
39333 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
39334 +
39335 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
39336 +
39337 + /*p_ReassmFrmDescrPoolTbl*/
39338 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
39339 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39340 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
39341 + 4);
39342 +
39343 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
39344 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
39345 +
39346 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
39347 +
39348 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
39349 +
39350 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
39351 +
39352 + /*p_TimeOutTbl*/
39353 +
39354 + p_Manip->capwapFragParams.p_TimeOutTbl =
39355 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39356 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
39357 + 4);
39358 +
39359 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
39360 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
39361 +
39362 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
39363 +
39364 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
39365 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
39366 +
39367 + p_Manip->updateParams &= ~NUM_OF_TASKS;
39368 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
39369 + }
39370 +
39371 + if (p_Manip->updateParams & OFFSET_OF_DATA)
39372 + {
39373 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39374 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39375 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
39376 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39377 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39378 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39379 + }
39380 +
39381 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39382 + {
39383 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
39384 +
39385 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39386 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
39387 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39388 +
39389 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
39390 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
39391 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
39392 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39393 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39394 + }
39395 + else
39396 + {
39397 + p_Manip->capwapFragParams.prOffset = 0xff;
39398 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39399 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39400 + }
39401 +
39402 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
39403 + p_Manip->updateParams &= ~HW_PORT_ID;
39404 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
39405 +
39406 + /*timeout hc */
39407 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
39408 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
39409 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
39410 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
39411 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
39412 + }
39413 +
39414 + else if (validate)
39415 + {
39416 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
39417 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
39418 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
39419 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
39420 +
39421 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39422 + {
39423 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
39424 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39425 + }
39426 + else
39427 + {
39428 + if (p_Manip->capwapFragParams.prOffset != 0xff)
39429 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39430 + }
39431 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
39432 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
39433 + }
39434 +
39435 + return E_OK;
39436 +}
39437 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
39438 +
39439 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
39440 +{
39441 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39442 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
39443 + t_Error err = E_OK;
39444 + uint8_t result;
39445 + uint32_t bitFor1Micro, tsbs, log2num;
39446 +
39447 + ASSERT_COND(p_FmPcd);
39448 + ASSERT_COND(h_ReasmCommonPramTbl);
39449 +
39450 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39451 + if (bitFor1Micro == 0)
39452 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39453 +
39454 + bitFor1Micro = 32 - bitFor1Micro;
39455 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
39456 + tsbs = bitFor1Micro - log2num;
39457 +
39458 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
39459 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
39460 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
39461 + ccReassmTimeoutParams.activate = TRUE;
39462 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
39463 + &result)) != E_OK)
39464 + RETURN_ERROR(MAJOR, err, NO_MSG);
39465 +
39466 + switch (result)
39467 + {
39468 + case (0):
39469 + return E_OK;
39470 + case (1):
39471 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
39472 + case (2):
39473 + RETURN_ERROR(
39474 + MAJOR, E_NO_MEMORY,
39475 + ("failed to allocate internal buffer from the HC-Port"));
39476 + case (3):
39477 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
39478 + ("'Disable Timeout Task' with invalid IPRCPT"));
39479 + case (4):
39480 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
39481 + case (5):
39482 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
39483 + default:
39484 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
39485 + }
39486 + return E_OK;
39487 +}
39488 +
39489 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
39490 +{
39491 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
39492 + uint64_t tmpReg64, size;
39493 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39494 + t_Error err = E_OK;
39495 +
39496 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39497 + if (bitFor1Micro == 0)
39498 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39499 +
39500 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
39501 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
39502 + p_Manip->reassmParams.p_ReassCommonTbl =
39503 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
39504 + p_FmPcd->h_FmMuram,
39505 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
39506 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
39507 +
39508 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
39509 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39510 + ("MURAM alloc for Reassembly common parameters table"));
39511 +
39512 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
39513 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
39514 +
39515 + /* Setting the TimeOut Mode.*/
39516 + tmpReg32 = 0;
39517 + if (p_Manip->reassmParams.timeOutMode
39518 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
39519 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
39520 +
39521 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
39522 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
39523 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
39524 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
39525 + tmpReg32);
39526 +
39527 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
39528 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
39529 +
39530 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
39531 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
39532 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39533 + (uint32_t)(size * 2),
39534 + 256));
39535 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
39536 + RETURN_ERROR(
39537 + MAJOR, E_NO_MEMORY,
39538 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
39539 +
39540 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
39541 + 0, (uint32_t)(size * 2));
39542 +
39543 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
39544 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
39545 + The last entry in this pool must contain the index zero*/
39546 + for (i = 0; i < (size - 1); i++)
39547 + WRITE_UINT16(
39548 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
39549 + (uint16_t)(i+1));
39550 +
39551 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
39552 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39553 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
39554 + - p_FmPcd->physicalMuramBase);
39555 + WRITE_UINT32(
39556 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
39557 + tmpReg32);
39558 +
39559 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
39560 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
39561 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
39562 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
39563 +
39564 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
39565 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39566 +
39567 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
39568 + (uint32_t)(size * 64));
39569 +
39570 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
39571 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
39572 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
39573 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39574 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39575 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39576 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39577 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39578 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39579 + WRITE_UINT32(
39580 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
39581 + (uint32_t)(tmpReg64 >> 32));
39582 + WRITE_UINT32(
39583 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
39584 + (uint32_t)tmpReg64);
39585 +
39586 + /*Allocation of the TimeOut table - This table resides in the MURAM.
39587 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
39588 + p_Manip->reassmParams.timeOutTblAddr =
39589 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
39590 +
39591 + if (!p_Manip->reassmParams.timeOutTblAddr)
39592 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39593 + ("MURAM alloc for Reassembly timeout table"));
39594 +
39595 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
39596 + (uint16_t)(size * 8));
39597 +
39598 + /* Sets the TimeOut table offset from MURAM */
39599 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39600 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
39601 + - p_FmPcd->physicalMuramBase);
39602 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
39603 + tmpReg32);
39604 +
39605 + /* Sets the Expiration Delay */
39606 + tmpReg32 = 0;
39607 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
39608 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
39609 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
39610 + tmpReg32);
39611 +
39612 + err = FmPcdRegisterReassmPort(p_FmPcd,
39613 + p_Manip->reassmParams.p_ReassCommonTbl);
39614 + if (err != E_OK)
39615 + {
39616 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
39617 + p_Manip->reassmParams.p_ReassCommonTbl);
39618 + RETURN_ERROR(MAJOR, err, ("port registration"));
39619 + }
39620 +
39621 + return err;
39622 +}
39623 +
39624 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
39625 +{
39626 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
39627 + uint32_t tmpReg32, autoLearnHashTblSize;
39628 + uint32_t numOfWays, setSize, setSizeCode, keySize;
39629 + uint32_t waySize, numOfSets, numOfEntries;
39630 + uint64_t tmpReg64;
39631 + uint16_t minFragSize;
39632 + uint16_t maxReassemSize;
39633 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
39634 + t_ReassTbl **p_ReassTbl;
39635 +
39636 + switch (hdr)
39637 + {
39638 + case HEADER_TYPE_IPv4:
39639 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
39640 + p_AutoLearnHashTblAddr =
39641 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
39642 + p_AutoLearnSetLockTblAddr =
39643 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
39644 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
39645 + maxReassemSize = 0;
39646 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
39647 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
39648 + break;
39649 + case HEADER_TYPE_IPv6:
39650 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
39651 + p_AutoLearnHashTblAddr =
39652 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
39653 + p_AutoLearnSetLockTblAddr =
39654 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
39655 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
39656 + maxReassemSize = 0;
39657 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
39658 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
39659 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
39660 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
39661 + break;
39662 + case HEADER_TYPE_CAPWAP:
39663 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
39664 + p_AutoLearnHashTblAddr =
39665 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
39666 + p_AutoLearnSetLockTblAddr =
39667 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
39668 + minFragSize = 0;
39669 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
39670 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
39671 + keySize = 4;
39672 + break;
39673 + default:
39674 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
39675 + }
39676 + keySize += 2; /* 2 bytes reserved for RFDIndex */
39677 +#if (DPAA_VERSION >= 11)
39678 + keySize += 2; /* 2 bytes reserved */
39679 +#endif /* (DPAA_VERSION >= 11) */
39680 + waySize = ROUND_UP(keySize, 8);
39681 +
39682 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
39683 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
39684 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
39685 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
39686 + if (!*p_ReassTbl)
39687 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
39688 + ("MURAM alloc for Reassembly specific parameters table"));
39689 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
39690 +
39691 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
39692 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
39693 + - p_FmPcd->physicalMuramBase);
39694 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
39695 +
39696 + /* Calculate set size (set size is rounded-up to next power of 2) */
39697 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
39698 +
39699 + /* Get set size code */
39700 + LOG2(setSize, setSizeCode);
39701 +
39702 + /* Sets ways number and set size code */
39703 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
39704 + (uint16_t)((numOfWays << 8) | setSizeCode));
39705 +
39706 + /* It is recommended that the total number of entries in this table
39707 + (number of sets * number of ways) will be twice the number of frames that
39708 + are expected to be reassembled simultaneously.*/
39709 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
39710 +
39711 + /* sets number calculation - number of entries = number of sets * number of ways */
39712 + numOfSets = numOfEntries / numOfWays;
39713 +
39714 + /* Sets AutoLearnHashKeyMask*/
39715 + NEXT_POWER_OF_2(numOfSets, numOfSets);
39716 +
39717 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
39718 + (uint16_t)(numOfSets - 1));
39719 +
39720 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
39721 + The size of this table is determined by the number of sets and the set size.
39722 + Table size = set size * number of sets
39723 + This table base address should be aligned to SetSize.*/
39724 + autoLearnHashTblSize = numOfSets * setSize;
39725 +
39726 + *p_AutoLearnHashTblAddr =
39727 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
39728 + if (!*p_AutoLearnHashTblAddr)
39729 + {
39730 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39731 + *p_ReassTbl = NULL;
39732 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39733 + }
39734 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
39735 +
39736 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
39737 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39738 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39739 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39740 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39741 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39742 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39743 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39744 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
39745 + (uint32_t)(tmpReg64 >> 32));
39746 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
39747 +
39748 + /* Allocation of the Set Lock table - This table resides in external memory
39749 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
39750 + This table resides in external memory and its base address should be 4-byte aligned */
39751 + *p_AutoLearnSetLockTblAddr =
39752 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
39753 + if (!*p_AutoLearnSetLockTblAddr)
39754 + {
39755 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
39756 + *p_ReassTbl = NULL;
39757 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
39758 + *p_AutoLearnHashTblAddr = 0;
39759 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39760 + }
39761 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
39762 +
39763 + /* sets Set Lock table pointer and liodn offset*/
39764 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39765 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39766 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39767 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39768 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39769 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39770 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
39771 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
39772 + (uint32_t)(tmpReg64 >> 32));
39773 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
39774 +
39775 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
39776 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
39777 +
39778 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
39779 +
39780 + return E_OK;
39781 +}
39782 +
39783 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
39784 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
39785 + t_Handle h_Ad, bool validate)
39786 +{
39787 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39788 + uint32_t tmpReg32;
39789 + t_Error err;
39790 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
39791 +#if (DPAA_VERSION >= 11)
39792 + t_FmPcdCtrlParamsPage *p_ParamsPage;
39793 +#endif /* (DPAA_VERSION >= 11) */
39794 +
39795 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39796 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
39797 + SANITY_CHECK_RETURN_ERROR(
39798 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
39799 + E_INVALID_STATE);
39800 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
39801 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
39802 + E_INVALID_HANDLE);
39803 +
39804 + UNUSED(h_Ad);
39805 +
39806 + if (!p_Manip->updateParams)
39807 + return E_OK;
39808 +
39809 + if (p_Manip->h_FmPcd != h_FmPcd)
39810 + RETURN_ERROR(
39811 + MAJOR, E_INVALID_STATE,
39812 + ("handler of PCD previously was initiated by different value"));
39813 +
39814 + if (p_Manip->updateParams)
39815 + {
39816 + if ((!(p_Manip->updateParams
39817 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
39818 + || ((p_Manip->shadowUpdateParams
39819 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
39820 + RETURN_ERROR(
39821 + MAJOR, E_INVALID_STATE,
39822 + ("in this stage parameters from Port has not be updated"));
39823 +
39824 + fmPortGetSetCcParams.setCcParams.type = 0;
39825 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
39826 + {
39827 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
39828 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
39829 + }
39830 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
39831 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
39832 + != E_OK)
39833 + RETURN_ERROR(MAJOR, err, NO_MSG);
39834 + if (fmPortGetSetCcParams.getCcParams.type
39835 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
39836 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39837 + ("offset of the data wasn't configured previously"));
39838 + if (p_Manip->updateParams
39839 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
39840 + {
39841 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39842 + uint8_t *p_Ptr, i, totalNumOfTnums;
39843 +
39844 + totalNumOfTnums =
39845 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
39846 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
39847 +
39848 + p_Manip->reassmParams.internalBufferPoolAddr =
39849 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39850 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
39851 + BMI_FIFO_UNITS));
39852 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
39853 + RETURN_ERROR(
39854 + MAJOR, E_NO_MEMORY,
39855 + ("MURAM alloc for Reassembly internal buffers pool"));
39856 + MemSet8(
39857 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
39858 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
39859 +
39860 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
39861 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39862 + (uint32_t)(5 + totalNumOfTnums),
39863 + 4));
39864 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
39865 + RETURN_ERROR(
39866 + MAJOR,
39867 + E_NO_MEMORY,
39868 + ("MURAM alloc for Reassembly internal buffers management"));
39869 +
39870 + p_Ptr =
39871 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
39872 + WRITE_UINT32(
39873 + *(uint32_t*)p_Ptr,
39874 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
39875 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
39876 + WRITE_UINT8(*p_Ptr, i);
39877 + WRITE_UINT8(*p_Ptr, 0xFF);
39878 +
39879 + tmpReg32 =
39880 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
39881 + | ((uint32_t)(XX_VirtToPhys(
39882 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
39883 + - p_FmPcd->physicalMuramBase));
39884 + WRITE_UINT32(
39885 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
39886 + tmpReg32);
39887 +
39888 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
39889 + | DISCARD_MASK);
39890 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
39891 + | DISCARD_MASK);
39892 + }
39893 + }
39894 +
39895 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
39896 + {
39897 + if (p_Manip->reassmParams.capwap.h_Scheme)
39898 + {
39899 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
39900 + p_Manip->reassmParams.capwap.h_Scheme;
39901 + p_PcdParams->p_KgParams->numOfSchemes++;
39902 + }
39903 +
39904 + }
39905 + else
39906 + {
39907 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
39908 + {
39909 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
39910 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
39911 + p_PcdParams->p_KgParams->numOfSchemes++;
39912 + }
39913 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
39914 + {
39915 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
39916 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
39917 + p_PcdParams->p_KgParams->numOfSchemes++;
39918 + }
39919 +#if (DPAA_VERSION >= 11)
39920 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
39921 + {
39922 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
39923 + (void**)&p_ParamsPage)) != E_OK)
39924 + RETURN_ERROR(MAJOR, err, NO_MSG);
39925 +
39926 + tmpReg32 = NIA_ENG_KG;
39927 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
39928 + {
39929 + tmpReg32 |= NIA_KG_DIRECT;
39930 + tmpReg32 |= NIA_KG_CC_EN;
39931 + tmpReg32 |= FmPcdKgGetSchemeId(
39932 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
39933 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
39934 + }
39935 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
39936 + {
39937 + tmpReg32 &= ~NIA_AC_MASK;
39938 + tmpReg32 |= NIA_KG_DIRECT;
39939 + tmpReg32 |= NIA_KG_CC_EN;
39940 + tmpReg32 |= FmPcdKgGetSchemeId(
39941 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
39942 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
39943 + }
39944 + }
39945 +#else
39946 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
39947 + {
39948 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
39949 + fmPortGetSetCcParams.getCcParams.discardMask);
39950 + }
39951 +#endif /* (DPAA_VERSION >= 11) */
39952 + }
39953 + return E_OK;
39954 +}
39955 +
39956 +#if (DPAA_VERSION == 10)
39957 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
39958 +{
39959 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39960 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
39961 + t_Error err;
39962 +
39963 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
39964 +
39965 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
39966 +
39967 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
39968 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
39969 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
39970 + RETURN_ERROR(MAJOR, err, NO_MSG);
39971 +
39972 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
39973 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
39974 + "Failed to release %d buffers to the BM (missing FBPRs)",
39975 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
39976 +
39977 + return E_OK;
39978 +}
39979 +
39980 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
39981 +{
39982 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39983 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
39984 + t_Error err;
39985 +
39986 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
39987 +
39988 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
39989 +
39990 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
39991 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
39992 + RETURN_ERROR(MAJOR, err, NO_MSG);
39993 +
39994 + return E_OK;
39995 +}
39996 +#endif /* (DPAA_VERSION == 10) */
39997 +
39998 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
39999 +{
40000 + if (p_Manip->h_Ad)
40001 + {
40002 + if (p_Manip->muramAllocate)
40003 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
40004 + else
40005 + XX_Free(p_Manip->h_Ad);
40006 + p_Manip->h_Ad = NULL;
40007 + }
40008 + if (p_Manip->p_Template)
40009 + {
40010 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
40011 + p_Manip->p_Template = NULL;
40012 + }
40013 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40014 + if (p_Manip->h_Frag)
40015 + {
40016 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40017 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40018 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
40019 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
40020 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40021 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
40022 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40023 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40024 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
40025 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
40026 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40027 + p_Manip->capwapFragParams.p_TimeOutTbl);
40028 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
40029 +
40030 + }
40031 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40032 + if (p_Manip->frag)
40033 + {
40034 + if (p_Manip->fragParams.p_Frag)
40035 + {
40036 +#if (DPAA_VERSION == 10)
40037 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
40038 +#endif /* (DPAA_VERSION == 10) */
40039 +
40040 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
40041 + }
40042 + }
40043 + else
40044 + if (p_Manip->reassm)
40045 + {
40046 + FmPcdUnregisterReassmPort(p_FmPcd,
40047 + p_Manip->reassmParams.p_ReassCommonTbl);
40048 +
40049 + if (p_Manip->reassmParams.timeOutTblAddr)
40050 + FM_MURAM_FreeMem(
40051 + p_FmPcd->h_FmMuram,
40052 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
40053 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
40054 + XX_FreeSmart(
40055 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
40056 + if (p_Manip->reassmParams.p_ReassCommonTbl)
40057 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40058 + p_Manip->reassmParams.p_ReassCommonTbl);
40059 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
40060 + FM_MURAM_FreeMem(
40061 + p_FmPcd->h_FmMuram,
40062 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
40063 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40064 + FM_MURAM_FreeMem(
40065 + p_FmPcd->h_FmMuram,
40066 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
40067 + if (p_Manip->reassmParams.internalBufferPoolAddr)
40068 + FM_MURAM_FreeMem(
40069 + p_FmPcd->h_FmMuram,
40070 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
40071 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
40072 + {
40073 +
40074 + }
40075 + else
40076 + {
40077 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
40078 + XX_FreeSmart(
40079 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
40080 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
40081 + XX_FreeSmart(
40082 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
40083 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
40084 + XX_FreeSmart(
40085 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
40086 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
40087 + XX_FreeSmart(
40088 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
40089 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
40090 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40091 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
40092 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
40093 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40094 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
40095 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
40096 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
40097 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
40098 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
40099 + }
40100 + }
40101 +
40102 + if (p_Manip->p_StatsTbl)
40103 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
40104 +}
40105 +
40106 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40107 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
40108 +{
40109 + if (p_ManipParams->u.hdr.rmv)
40110 + {
40111 + switch (p_ManipParams->u.hdr.rmvParams.type)
40112 + {
40113 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40114 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40115 + {
40116 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
40117 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
40118 + {
40119 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40120 + {
40121 + case (HEADER_TYPE_CAPWAP_DTLS) :
40122 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40123 + p_Manip->muramAllocate = TRUE;
40124 + if (p_ManipParams->u.hdr.insrt)
40125 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
40126 + if (p_ManipParams->fragOrReasm)
40127 + {
40128 + if (!p_ManipParams->fragOrReasmParams.frag)
40129 + {
40130 + switch (p_ManipParams->fragOrReasmParams.hdr)
40131 + {
40132 + case (HEADER_TYPE_CAPWAP):
40133 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40134 + break;
40135 + default:
40136 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
40137 + }
40138 + }
40139 + else
40140 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
40141 + }
40142 + break;
40143 + default:
40144 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
40145 + }
40146 + }
40147 + else
40148 + {
40149 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40150 + {
40151 + case (HEADER_TYPE_CAPWAP_DTLS) :
40152 + case (HEADER_TYPE_CAPWAP) :
40153 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
40154 + 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"));
40155 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40156 + p_Manip->muramAllocate = TRUE;
40157 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
40158 + break;
40159 + default :
40160 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40161 + }
40162 + }
40163 + break;
40164 + default :
40165 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40166 + }
40167 + break;
40168 + default:
40169 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40170 + }
40171 + }
40172 + else if (p_ManipParams->u.hdr.insrt)
40173 + {
40174 + switch (p_ManipParams->u.hdr.insrtParams.type)
40175 + {
40176 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
40177 +
40178 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
40179 + p_Manip->muramAllocate = FALSE;
40180 + if (p_ManipParams->fragOrReasm)
40181 + {
40182 + if (p_ManipParams->fragOrReasmParams.frag)
40183 + {
40184 + switch (p_ManipParams->fragOrReasmParams.hdr)
40185 + {
40186 + case (HEADER_TYPE_CAPWAP):
40187 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40188 + break;
40189 + default:
40190 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
40191 + }
40192 + }
40193 + else
40194 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
40195 + }
40196 + break;
40197 +
40198 + default:
40199 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
40200 + }
40201 + }
40202 + else if (p_ManipParams->fragOrReasm)
40203 + {
40204 + if (p_ManipParams->fragOrReasmParams.frag)
40205 + {
40206 + switch (p_ManipParams->fragOrReasmParams.hdr)
40207 + {
40208 + case (HEADER_TYPE_CAPWAP):
40209 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40210 + p_Manip->muramAllocate = FALSE;
40211 + break;
40212 + default:
40213 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
40214 + }
40215 + }
40216 + else
40217 + {
40218 + switch (p_ManipParams->fragOrReasmParams.hdr)
40219 + {
40220 + case (HEADER_TYPE_CAPWAP):
40221 + 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"));
40222 + default:
40223 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
40224 + }
40225 + }
40226 +
40227 + }
40228 + else
40229 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
40230 +
40231 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
40232 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
40233 +
40234 + return E_OK;
40235 +}
40236 +
40237 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40238 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
40239 + t_FmPcdManipParams *p_ManipParams)
40240 +{
40241 + switch (p_ManipParams->type)
40242 + {
40243 + case e_FM_PCD_MANIP_HDR:
40244 + /* Check that next-manip is not already used */
40245 + if (p_ManipParams->h_NextManip)
40246 + {
40247 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
40248 + RETURN_ERROR(
40249 + MAJOR, E_INVALID_STATE,
40250 + ("h_NextManip is already a part of another chain"));
40251 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40252 + != e_FM_PCD_MANIP_HDR) &&
40253 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40254 + != e_FM_PCD_MANIP_FRAG))
40255 + RETURN_ERROR(
40256 + MAJOR,
40257 + E_NOT_SUPPORTED,
40258 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
40259 + }
40260 +
40261 + if (p_ManipParams->u.hdr.rmv)
40262 + {
40263 + switch (p_ManipParams->u.hdr.rmvParams.type)
40264 + {
40265 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40266 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40267 + {
40268 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40269 + break;
40270 +#if (DPAA_VERSION >= 11)
40271 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40272 + break;
40273 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40274 + {
40275 + t_Error err;
40276 + uint8_t prsArrayOffset;
40277 +
40278 + err =
40279 + GetPrOffsetByHeaderOrField(
40280 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40281 + &prsArrayOffset);
40282 + if (err)
40283 + RETURN_ERROR(MAJOR, err, NO_MSG);
40284 + break;
40285 + }
40286 +#endif /* (DPAA_VERSION >= 11) */
40287 + default:
40288 + RETURN_ERROR(
40289 + MAJOR,
40290 + E_INVALID_STATE,
40291 + ("invalid type of remove manipulation"));
40292 + }
40293 + break;
40294 + case (e_FM_PCD_MANIP_RMV_GENERIC):
40295 + break;
40296 + default:
40297 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40298 + ("invalid type of remove manipulation"));
40299 + }
40300 + p_Manip->opcode = HMAN_OC;
40301 + p_Manip->muramAllocate = TRUE;
40302 + p_Manip->rmv = TRUE;
40303 + }
40304 + else
40305 + if (p_ManipParams->u.hdr.insrt)
40306 + {
40307 + switch (p_ManipParams->u.hdr.insrtParams.type)
40308 + {
40309 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
40310 + {
40311 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
40312 + {
40313 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40314 + /* nothing to check */
40315 + break;
40316 +#if (DPAA_VERSION >= 11)
40317 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40318 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40319 + % 4)
40320 + RETURN_ERROR(
40321 + MAJOR,
40322 + E_INVALID_VALUE,
40323 + ("IP inserted header must be of size which is a multiple of four bytes"));
40324 + break;
40325 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40326 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40327 + % 4)
40328 + RETURN_ERROR(
40329 + MAJOR,
40330 + E_INVALID_VALUE,
40331 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
40332 + break;
40333 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40334 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40335 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40336 + != 8)
40337 + RETURN_ERROR(
40338 + MAJOR,
40339 + E_INVALID_VALUE,
40340 + ("Inserted header must be of size 8"));
40341 + break;
40342 +#endif /* (DPAA_VERSION >= 11) */
40343 + default:
40344 + RETURN_ERROR(
40345 + MAJOR,
40346 + E_INVALID_STATE,
40347 + ("unsupported insert by header type"));
40348 + }
40349 + }
40350 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
40351 + break;
40352 + default:
40353 + RETURN_ERROR(
40354 + MAJOR,
40355 + E_INVALID_STATE,
40356 + ("for only insert manipulation unsupported type"));
40357 + }
40358 + p_Manip->opcode = HMAN_OC;
40359 + p_Manip->muramAllocate = TRUE;
40360 + p_Manip->insrt = TRUE;
40361 + }
40362 + else
40363 + if (p_ManipParams->u.hdr.fieldUpdate)
40364 + {
40365 + /* Check parameters */
40366 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
40367 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
40368 + {
40369 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40370 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40371 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
40372 + > 7))
40373 + RETURN_ERROR(
40374 + MAJOR, E_INVALID_VALUE,
40375 + ("vpri should get values of 0-7 "));
40376 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40377 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40378 + {
40379 + int i;
40380 +
40381 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
40382 + > 7)
40383 + RETURN_ERROR(
40384 + MAJOR,
40385 + E_INVALID_VALUE,
40386 + ("vpriDefVal should get values of 0-7 "));
40387 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
40388 + i++)
40389 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
40390 + & 0xf0)
40391 + RETURN_ERROR(
40392 + MAJOR,
40393 + E_INVALID_VALUE,
40394 + ("dscpToVpriTabl value out of range (0-15)"));
40395 + }
40396 +
40397 + }
40398 +
40399 + p_Manip->opcode = HMAN_OC;
40400 + p_Manip->muramAllocate = TRUE;
40401 + p_Manip->fieldUpdate = TRUE;
40402 + }
40403 + else
40404 + if (p_ManipParams->u.hdr.custom)
40405 + {
40406 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
40407 + {
40408 +
40409 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
40410 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
40411 + RETURN_ERROR(
40412 + MAJOR, E_INVALID_VALUE,
40413 + ("size should get values of 1-8 "));
40414 +
40415 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
40416 + RETURN_ERROR(
40417 + MAJOR, E_INVALID_VALUE,
40418 + ("srcOffset should be <= 7"));
40419 +
40420 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
40421 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
40422 + RETURN_ERROR(
40423 + MAJOR, E_INVALID_VALUE,
40424 + ("(srcOffset + size) should be <= 8"));
40425 +
40426 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
40427 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
40428 + RETURN_ERROR(
40429 + MAJOR, E_INVALID_VALUE,
40430 + ("(dstOffset + size) should be <= 256"));
40431 +
40432 + }
40433 +
40434 + p_Manip->opcode = HMAN_OC;
40435 + p_Manip->muramAllocate = TRUE;
40436 + p_Manip->custom = TRUE;
40437 + }
40438 + break;
40439 + case e_FM_PCD_MANIP_REASSEM:
40440 + if (p_ManipParams->h_NextManip)
40441 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40442 + ("next manip with reassembly"));
40443 + switch (p_ManipParams->u.reassem.hdr)
40444 + {
40445 + case (HEADER_TYPE_IPv4):
40446 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
40447 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40448 + break;
40449 + case (HEADER_TYPE_IPv6):
40450 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
40451 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40452 + break;
40453 +#if (DPAA_VERSION >= 11)
40454 + case (HEADER_TYPE_CAPWAP):
40455 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
40456 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40457 + break;
40458 +#endif /* (DPAA_VERSION >= 11) */
40459 + default:
40460 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40461 + ("header for reassembly"));
40462 + }
40463 + break;
40464 + case e_FM_PCD_MANIP_FRAG:
40465 + if (p_ManipParams->h_NextManip)
40466 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40467 + ("next manip with fragmentation"));
40468 + switch (p_ManipParams->u.frag.hdr)
40469 + {
40470 + case (HEADER_TYPE_IPv4):
40471 + case (HEADER_TYPE_IPv6):
40472 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
40473 + break;
40474 +#if (DPAA_VERSION >= 11)
40475 + case (HEADER_TYPE_CAPWAP):
40476 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40477 + break;
40478 +#endif /* (DPAA_VERSION >= 11) */
40479 + default:
40480 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40481 + ("header for fragmentation"));
40482 + }
40483 + p_Manip->muramAllocate = TRUE;
40484 + break;
40485 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
40486 + switch (p_ManipParams->u.specialOffload.type)
40487 + {
40488 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
40489 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
40490 + p_Manip->muramAllocate = TRUE;
40491 + break;
40492 +#if (DPAA_VERSION >= 11)
40493 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
40494 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
40495 + p_Manip->muramAllocate = TRUE;
40496 + break;
40497 +#endif /* (DPAA_VERSION >= 11) */
40498 + default:
40499 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40500 + ("special offload type"));
40501 + }
40502 + break;
40503 + default:
40504 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
40505 + }
40506 +
40507 + return E_OK;
40508 +}
40509 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40510 +
40511 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40512 +
40513 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
40514 + t_Handle h_FmPort,
40515 + t_FmPcdManip *p_Manip)
40516 +{
40517 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40518 + uint32_t tmpReg32 = 0;
40519 + t_AdOfTypeContLookup *p_Ad;
40520 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40521 + t_Error err;
40522 +
40523 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40524 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40525 +
40526 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40527 + if (p_Manip->h_FmPcd != h_FmPcd)
40528 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40529 + ("handler of PCD previously was initiated by different value"));
40530 +
40531 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40532 +
40533 + if (!p_Manip->p_StatsTbl)
40534 + {
40535 +
40536 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40537 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40538 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40539 + if (err)
40540 + RETURN_ERROR(MAJOR, err, NO_MSG);
40541 +
40542 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
40543 +
40544 + p_Manip->p_StatsTbl =
40545 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40546 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
40547 + 4);
40548 + if (!p_Manip->p_StatsTbl)
40549 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
40550 +
40551 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
40552 +
40553 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
40554 +
40555 + if (p_Manip->cnia)
40556 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
40557 +
40558 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
40559 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40560 + }
40561 + else
40562 + {
40563 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40564 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40565 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40566 + if (err)
40567 + RETURN_ERROR(MAJOR, err, NO_MSG);
40568 + }
40569 +
40570 + return E_OK;
40571 +}
40572 +
40573 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
40574 +{
40575 + t_AdOfTypeContLookup *p_Ad;
40576 + uint32_t tmpReg32 = 0;
40577 + uint8_t prsArrayOffset = 0;
40578 + t_Error err;
40579 +
40580 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40581 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40582 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40583 +
40584 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40585 + if (p_Manip->rmv)
40586 + {
40587 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
40588 + if (err)
40589 + RETURN_ERROR(MAJOR, err, NO_MSG);
40590 +
40591 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
40592 + tmpReg32 |= HMAN_RMV_HDR;
40593 + }
40594 +
40595 + if (p_Manip->insrt)
40596 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
40597 +
40598 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40599 +
40600 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40601 +
40602 + tmpReg32 = 0;
40603 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40604 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40605 +
40606 + return E_OK;
40607 +}
40608 +
40609 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
40610 + bool caamUsed)
40611 +{
40612 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40613 + uint32_t tmpReg32 = 0;
40614 +
40615 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
40616 +
40617 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
40618 +
40619 + tmpReg32 = 0;
40620 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40621 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
40622 +
40623 + tmpReg32 = 0;
40624 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
40625 + tmpReg32 |= (uint32_t)0x16 << 16;
40626 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
40627 +
40628 + if (caamUsed)
40629 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
40630 +
40631 + return E_OK;
40632 +}
40633 +
40634 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
40635 +{
40636 + t_AdOfTypeContLookup *p_Ad;
40637 + uint32_t tmpReg32 = 0;
40638 + t_Error err = E_OK;
40639 +
40640 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40641 +
40642 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40643 +
40644 + tmpReg32 = 0;
40645 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40646 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40647 +
40648 + tmpReg32 = 0;
40649 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40650 +
40651 +
40652 + if (p_Manip->h_Frag)
40653 + {
40654 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
40655 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
40656 + }
40657 +
40658 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40659 +
40660 + return err;
40661 +}
40662 +
40663 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
40664 + t_FmPcdManip *p_Manip,
40665 + t_FmPcd *p_FmPcd,
40666 + uint8_t poolId)
40667 +{
40668 + t_Handle p_Table;
40669 + uint32_t tmpReg32 = 0;
40670 + int i = 0;
40671 + uint8_t log2Num;
40672 + uint8_t numOfSets;
40673 + uint32_t j = 0;
40674 + uint32_t bitFor1Micro;
40675 +
40676 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
40677 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
40678 +
40679 + if (!p_FmPcd->h_Hc)
40680 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
40681 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
40682 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
40683 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
40684 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
40685 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
40686 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
40687 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
40688 + {
40689 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
40690 + (p_ManipParams->maxNumFramesInProcess > 512))
40691 + 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"));
40692 + }
40693 + else
40694 + {
40695 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
40696 + (p_ManipParams->maxNumFramesInProcess > 2048))
40697 + 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"));
40698 + }
40699 +
40700 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
40701 + if (bitFor1Micro == 0)
40702 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
40703 +
40704 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
40705 +
40706 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40707 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
40708 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40709 + if (!p_Manip->h_Frag)
40710 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
40711 +
40712 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
40713 +
40714 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
40715 +
40716 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
40717 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40718 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
40719 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
40720 +
40721 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40722 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
40723 +
40724 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
40725 +
40726 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
40727 +
40728 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
40729 +
40730 + tmpReg32 = 0;
40731 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
40732 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
40733 + if (p_ManipParams->haltOnDuplicationFrag)
40734 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
40735 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
40736 + {
40737 + i = 8;
40738 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
40739 + }
40740 + else
40741 + i = 4;
40742 +
40743 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
40744 + LOG2(numOfSets, log2Num);
40745 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
40746 +
40747 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
40748 +
40749 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
40750 + if (((j / i) % 2)== 0)
40751 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
40752 +
40753 + tmpReg32 = 0x00008000;
40754 + tmpReg32 |= (uint32_t)poolId << 16;
40755 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
40756 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
40757 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
40758 +
40759 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
40760 +
40761 + p_Manip->capwapFragParams.sgBpid = poolId;
40762 +
40763 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
40764 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
40765 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
40766 +
40767 + tmpReg32 = 0;
40768 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
40769 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
40770 +
40771 + return E_OK;
40772 +}
40773 +
40774 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
40775 + t_FmPcdManip *p_Manip,
40776 + t_FmPcd *p_FmPcd,
40777 + uint8_t poolId)
40778 +{
40779 + t_AdOfTypeContLookup *p_Ad;
40780 + uint32_t tmpReg32 = 0;
40781 +
40782 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40783 +
40784 + p_Manip->updateParams |= OFFSET_OF_DATA;
40785 +
40786 + p_Manip->frag = TRUE;
40787 +
40788 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40789 + FM_PCD_CC_AD_ENTRY_SIZE,
40790 + FM_PCD_CC_AD_TABLE_ALIGN);
40791 + if (!p_Manip->h_Frag)
40792 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
40793 +
40794 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
40795 +
40796 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
40797 +
40798 + tmpReg32 = 0;
40799 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
40800 +
40801 + if (p_ManipParams->headerOptionsCompr)
40802 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
40803 + tmpReg32 |= ((uint32_t)poolId << 8);
40804 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40805 +
40806 + tmpReg32 = 0;
40807 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40808 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40809 +
40810 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
40811 + p_Manip->capwapFragParams.sgBpid = poolId;
40812 +
40813 + return E_OK;
40814 +}
40815 +
40816 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
40817 +{
40818 + t_AdOfTypeContLookup *p_Ad;
40819 + uint32_t tmpReg32 = 0;
40820 +
40821 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40822 +
40823 + UNUSED(p_FmPcd);
40824 +
40825 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40826 +
40827 + tmpReg32 = 0;
40828 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
40829 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
40830 + tmpReg32 |= (uint32_t)0x16 << 16;
40831 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40832 +
40833 + tmpReg32 = 0;
40834 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40835 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40836 +
40837 + return E_OK;
40838 +}
40839 +
40840 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40841 +{
40842 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
40843 + uint8_t tmpReg8 = 0xff;
40844 + t_AdOfTypeContLookup *p_Ad;
40845 + bool ipModify = FALSE;
40846 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
40847 + uint16_t tmpReg16 = 0;
40848 + t_Error err = E_OK;
40849 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
40850 + uint8_t *p_Template = NULL;
40851 +
40852 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40853 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40854 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40855 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
40856 +
40857 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40858 + if (p_Manip->insrt)
40859 + {
40860 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
40861 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
40862 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
40863 +
40864 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
40865 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
40866 +
40867 + if (p_InsrtByTemplate->size > 128)
40868 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
40869 +
40870 + if (p_InsrtByTemplate->size)
40871 + {
40872 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40873 + p_InsrtByTemplate->size,
40874 + FM_PCD_CC_AD_TABLE_ALIGN);
40875 + if(!p_Manip->p_Template)
40876 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
40877 +
40878 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
40879 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
40880 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
40881 + }
40882 +
40883 + tmpReg32 = 0;
40884 +
40885 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
40886 +
40887 + if (!p_Template)
40888 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
40889 +
40890 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
40891 +
40892 + if (p_InsrtByTemplate->modifyOuterIp)
40893 + {
40894 + ipModify = TRUE;
40895 +
40896 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
40897 +
40898 + if((tmpReg8 & 0xf0) == 0x40)
40899 + tmpReg8 = 4;
40900 + else if((tmpReg8 & 0xf0) == 0x60)
40901 + tmpReg8 = 6;
40902 + else
40903 + tmpReg8 = 0xff;
40904 +
40905 + if (tmpReg8 != 0xff)
40906 + {
40907 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
40908 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
40909 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
40910 + {
40911 +
40912 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
40913 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
40914 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
40915 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
40916 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
40917 + /*IP header template - IP totalLength -
40918 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
40919 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
40920 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
40921 + }
40922 + if (blockSize)
40923 + {
40924 + if (!POWER_OF_2(blockSize))
40925 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
40926 + }
40927 +
40928 + }
40929 + if (tmpReg8 == 4)
40930 + {
40931 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
40932 + 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"));
40933 +
40934 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
40935 +
40936 + if (blockSize)
40937 + blockSize -= 1;
40938 +
40939 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
40940 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
40941 +
40942 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
40943 + 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
40944 +
40945 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
40946 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
40947 +
40948 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
40949 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
40950 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
40951 +
40952 + /*UDP checksum has to be 0*/
40953 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
40954 + {
40955 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
40956 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
40957 +
40958 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
40959 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
40960 +
40961 + }
40962 +
40963 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
40964 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
40965 +
40966 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
40967 + }
40968 + else if (tmpReg8 == 6)
40969 + {
40970 + /*TODO - add check for maximum value of blockSize;*/
40971 + if (blockSize)
40972 + LOG2(blockSize, log2Num);
40973 + tmpRegNia |= (uint32_t)log2Num << 24;
40974 +
40975 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
40976 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
40977 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
40978 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
40979 + {
40980 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
40981 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
40982 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
40983 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
40984 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
40985 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
40986 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
40987 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
40988 + }
40989 + }
40990 + else
40991 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
40992 + }
40993 +
40994 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
40995 + /*TODO - check it*/
40996 + if (p_InsrtByTemplate->modifyOuterVlan)
40997 + {
40998 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
40999 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
41000 +
41001 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
41002 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
41003 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
41004 +
41005 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
41006 + tmpReg8 &= 0x1f;
41007 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
41008 +
41009 + p_Template[14] = tmpReg8;
41010 + }
41011 +
41012 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
41013 +
41014 + XX_Free(p_Template);
41015 + }
41016 +
41017 + tmpReg32 = 0;
41018 + if (p_Manip->h_Frag)
41019 + {
41020 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41021 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
41022 + }
41023 + else
41024 + tmpReg32 = 0xffff0000;
41025 +
41026 + if (ipModify)
41027 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
41028 + else
41029 + tmpReg32 |= (uint32_t)0x0000ff00;
41030 +
41031 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41032 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
41033 +
41034 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41035 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
41036 +
41037 + return err;
41038 +}
41039 +
41040 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
41041 +{
41042 +
41043 + switch (p_StatsParams->type)
41044 + {
41045 + case (e_FM_PCD_STATS_PER_FLOWID):
41046 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
41047 + p_Manip->muramAllocate = TRUE;
41048 + break;
41049 + default:
41050 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
41051 + }
41052 +
41053 + return E_OK;
41054 +}
41055 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41056 +
41057 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41058 +{
41059 + t_AdOfTypeContLookup *p_Ad;
41060 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41061 + uint32_t tmpReg32;
41062 + t_Error err = E_OK;
41063 +
41064 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
41065 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
41066 + two separate IP Reassembly Parameter tables are required.*/
41067 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
41068 + RETURN_ERROR(MAJOR, err, NO_MSG);
41069 +
41070 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
41071 + tmpReg32 = 0;
41072 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41073 +
41074 + /* Gets the required Action descriptor table pointer */
41075 + switch (hdr)
41076 + {
41077 + case HEADER_TYPE_IPv4:
41078 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
41079 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41080 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41081 + - (p_FmPcd->physicalMuramBase));
41082 + break;
41083 + case HEADER_TYPE_IPv6:
41084 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
41085 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41086 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41087 + - (p_FmPcd->physicalMuramBase));
41088 + break;
41089 + case HEADER_TYPE_CAPWAP:
41090 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
41091 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41092 + p_Manip->reassmParams.capwap.p_ReassTbl)
41093 + - (p_FmPcd->physicalMuramBase));
41094 + break;
41095 + default:
41096 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41097 + }
41098 +
41099 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41100 +
41101 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
41102 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
41103 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
41104 +
41105 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
41106 + {
41107 +#if (DPAA_VERSION == 10)
41108 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
41109 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41110 +#endif /* (DPAA_VERSION == 10) */
41111 +#if (DPAA_VERSION >= 11)
41112 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
41113 + {
41114 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
41115 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
41116 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
41117 + }
41118 +#endif /* (DPAA_VERSION >= 11) */
41119 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
41120 + tmpReg32 = 0;
41121 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
41122 + }
41123 +#if (DPAA_VERSION >= 11)
41124 + else
41125 + if (hdr == HEADER_TYPE_CAPWAP)
41126 + {
41127 + tmpReg32 = 0;
41128 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
41129 + }
41130 +#endif /* (DPAA_VERSION >= 11) */
41131 +
41132 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41133 +
41134 + p_Manip->reassm = TRUE;
41135 +
41136 + return E_OK;
41137 +}
41138 +
41139 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
41140 +{
41141 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41142 +
41143 + /* Allocation if IPv4 Action descriptor */
41144 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
41145 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41146 + FM_PCD_CC_AD_TABLE_ALIGN);
41147 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
41148 + {
41149 + ReleaseManipHandler(p_Manip, p_FmPcd);
41150 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41151 + ("Allocation of IPv4 table descriptor"));
41152 + }
41153 +
41154 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41155 +
41156 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41157 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
41158 +}
41159 +
41160 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
41161 +{
41162 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41163 +
41164 + /* Allocation if IPv6 Action descriptor */
41165 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
41166 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41167 + FM_PCD_CC_AD_TABLE_ALIGN);
41168 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
41169 + {
41170 + ReleaseManipHandler(p_Manip, p_FmPcd);
41171 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41172 + ("Allocation of IPv6 table descriptor"));
41173 + }
41174 +
41175 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41176 +
41177 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41178 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
41179 +}
41180 +
41181 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41182 + t_FmPcdManip *p_Manip)
41183 +{
41184 + uint32_t maxSetNumber = 10000;
41185 + t_FmPcdManipReassemIpParams reassmManipParams =
41186 + p_ManipReassmParams->u.ipReassem;
41187 + t_Error res;
41188 +
41189 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41190 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41191 + E_INVALID_HANDLE);
41192 +
41193 + /* Check validation of user's parameter.*/
41194 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41195 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41196 + RETURN_ERROR(
41197 + MAJOR, E_INVALID_VALUE,
41198 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41199 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41200 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41201 + if (reassmManipParams.maxNumFramesInProcess
41202 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41203 + RETURN_ERROR(
41204 + MAJOR,
41205 + E_INVALID_VALUE,
41206 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41207 +
41208 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
41209 + && (reassmManipParams.minFragSize[1] < 256))
41210 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
41211 +
41212 + /* Saves user's reassembly manipulation parameters */
41213 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
41214 + reassmManipParams.relativeSchemeId[0];
41215 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
41216 + reassmManipParams.relativeSchemeId[1];
41217 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
41218 + reassmManipParams.numOfFramesPerHashEntry[0];
41219 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
41220 + reassmManipParams.numOfFramesPerHashEntry[1];
41221 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
41222 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
41223 + p_Manip->reassmParams.maxNumFramesInProcess =
41224 + reassmManipParams.maxNumFramesInProcess;
41225 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41226 + p_Manip->reassmParams.fqidForTimeOutFrames =
41227 + reassmManipParams.fqidForTimeOutFrames;
41228 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41229 + reassmManipParams.timeoutThresholdForReassmProcess;
41230 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41231 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41232 +#if (DPAA_VERSION == 10)
41233 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
41234 +#endif /* (DPAA_VERSION == 10) */
41235 +#if (DPAA_VERSION >= 11)
41236 + if (reassmManipParams.nonConsistentSpFqid != 0)
41237 + {
41238 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
41239 + reassmManipParams.nonConsistentSpFqid;
41240 + }
41241 +#endif /* (DPAA_VERSION >= 11) */
41242 +
41243 + /* Creates and initializes the IP Reassembly common parameter table */
41244 + CreateReassCommonTable(p_Manip);
41245 +
41246 + /* Creation of IPv4 reassembly manipulation */
41247 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41248 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
41249 + {
41250 + res = SetIpv4ReassmManip(p_Manip);
41251 + if (res != E_OK)
41252 + return res;
41253 + }
41254 +
41255 + /* Creation of IPv6 reassembly manipulation */
41256 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41257 + {
41258 + res = SetIpv6ReassmManip(p_Manip);
41259 + if (res != E_OK)
41260 + return res;
41261 + }
41262 +
41263 + return E_OK;
41264 +}
41265 +
41266 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
41267 + t_FmPcdKgSchemeParams *p_Scheme,
41268 + t_Handle h_CcTree, bool ipv4,
41269 + uint8_t groupId)
41270 +{
41271 + uint32_t j;
41272 + uint8_t res;
41273 +
41274 + /* Configures scheme's network environment parameters */
41275 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
41276 + if (ipv4)
41277 + res = FmPcdNetEnvGetUnitId(
41278 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41279 + HEADER_TYPE_IPv4, FALSE, 0);
41280 + else
41281 + res = FmPcdNetEnvGetUnitId(
41282 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41283 + HEADER_TYPE_IPv6, FALSE, 0);
41284 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41285 + p_Scheme->netEnvParams.unitIds[0] = res;
41286 +
41287 + res = FmPcdNetEnvGetUnitId(
41288 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41289 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41290 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41291 + p_Scheme->netEnvParams.unitIds[1] = res;
41292 +
41293 + /* Configures scheme's next engine parameters*/
41294 + p_Scheme->nextEngine = e_FM_PCD_CC;
41295 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41296 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41297 + p_Scheme->useHash = TRUE;
41298 +
41299 + /* Configures scheme's key*/
41300 + if (ipv4 == TRUE)
41301 + {
41302 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
41303 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41304 + e_FM_PCD_EXTRACT_BY_HDR;
41305 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41306 + e_FM_PCD_EXTRACT_FULL_FIELD;
41307 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41308 + HEADER_TYPE_IPv4;
41309 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
41310 + NET_HEADER_FIELD_IPv4_DST_IP;
41311 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41312 + e_FM_PCD_EXTRACT_BY_HDR;
41313 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41314 + e_FM_PCD_EXTRACT_FULL_FIELD;
41315 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41316 + HEADER_TYPE_IPv4;
41317 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
41318 + NET_HEADER_FIELD_IPv4_SRC_IP;
41319 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41320 + e_FM_PCD_EXTRACT_BY_HDR;
41321 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41322 + e_FM_PCD_EXTRACT_FULL_FIELD;
41323 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41324 + HEADER_TYPE_IPv4;
41325 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
41326 + NET_HEADER_FIELD_IPv4_PROTO;
41327 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
41328 + e_FM_PCD_EXTRACT_BY_HDR;
41329 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
41330 + HEADER_TYPE_IPv4;
41331 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
41332 + e_FM_PCD_EXTRACT_FROM_HDR;
41333 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
41334 + FALSE;
41335 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
41336 + 2;
41337 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
41338 + 4;
41339 + }
41340 + else /* IPv6 */
41341 + {
41342 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
41343 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41344 + e_FM_PCD_EXTRACT_BY_HDR;
41345 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41346 + e_FM_PCD_EXTRACT_FULL_FIELD;
41347 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41348 + HEADER_TYPE_IPv6;
41349 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
41350 + NET_HEADER_FIELD_IPv6_DST_IP;
41351 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41352 + e_FM_PCD_EXTRACT_BY_HDR;
41353 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41354 + e_FM_PCD_EXTRACT_FULL_FIELD;
41355 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41356 + HEADER_TYPE_IPv6;
41357 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
41358 + NET_HEADER_FIELD_IPv6_SRC_IP;
41359 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41360 + e_FM_PCD_EXTRACT_BY_HDR;
41361 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41362 + HEADER_TYPE_USER_DEFINED_SHIM2;
41363 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41364 + e_FM_PCD_EXTRACT_FROM_HDR;
41365 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
41366 + 4;
41367 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
41368 + 4;
41369 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
41370 + TRUE;
41371 + }
41372 +
41373 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
41374 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
41375 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
41376 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
41377 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
41378 + {
41379 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
41380 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
41381 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
41382 + e_FM_PCD_KG_DFLT_GBL_0;
41383 + }
41384 +}
41385 +
41386 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
41387 + t_FmPcdManipReassemIpStats *p_Stats)
41388 +{
41389 + ASSERT_COND(p_Manip);
41390 + ASSERT_COND(p_Stats);
41391 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41392 +
41393 + p_Stats->timeout =
41394 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41395 + p_Stats->rfdPoolBusy =
41396 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41397 + p_Stats->internalBufferBusy =
41398 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41399 + p_Stats->externalBufferBusy =
41400 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41401 + p_Stats->sgFragments =
41402 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41403 + p_Stats->dmaSemaphoreDepletion =
41404 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41405 +#if (DPAA_VERSION >= 11)
41406 + p_Stats->nonConsistentSp =
41407 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41408 +#endif /* (DPAA_VERSION >= 11) */
41409 +
41410 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41411 + {
41412 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
41413 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
41414 + p_Stats->specificHdrStatistics[0].validFragments =
41415 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
41416 + p_Stats->specificHdrStatistics[0].processedFragments =
41417 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
41418 + p_Stats->specificHdrStatistics[0].malformedFragments =
41419 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
41420 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
41421 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
41422 + p_Stats->specificHdrStatistics[0].discardedFragments =
41423 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
41424 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
41425 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
41426 + }
41427 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41428 + {
41429 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
41430 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
41431 + p_Stats->specificHdrStatistics[1].validFragments =
41432 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
41433 + p_Stats->specificHdrStatistics[1].processedFragments =
41434 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
41435 + p_Stats->specificHdrStatistics[1].malformedFragments =
41436 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
41437 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
41438 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
41439 + p_Stats->specificHdrStatistics[1].discardedFragments =
41440 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
41441 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
41442 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
41443 + }
41444 + return E_OK;
41445 +}
41446 +
41447 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
41448 + t_FmPcdManipFragIpStats *p_Stats)
41449 +{
41450 + t_AdOfTypeContLookup *p_Ad;
41451 +
41452 + ASSERT_COND(p_Manip);
41453 + ASSERT_COND(p_Stats);
41454 + ASSERT_COND(p_Manip->h_Ad);
41455 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41456 +
41457 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41458 +
41459 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41460 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
41461 + & 0x00ffffff;
41462 + p_Stats->generatedFragments =
41463 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
41464 +
41465 + return E_OK;
41466 +}
41467 +
41468 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
41469 + t_FmPcdManip *p_Manip)
41470 +{
41471 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41472 + t_FmPcd *p_FmPcd;
41473 +#if (DPAA_VERSION == 10)
41474 + t_Error err = E_OK;
41475 +#endif /* (DPAA_VERSION == 10) */
41476 +
41477 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41478 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41479 + E_INVALID_VALUE);
41480 +
41481 + p_FmPcd = p_Manip->h_FmPcd;
41482 + /* Allocation of fragmentation Action Descriptor */
41483 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41484 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41485 + FM_PCD_CC_AD_TABLE_ALIGN);
41486 + if (!p_Manip->fragParams.p_Frag)
41487 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41488 + ("MURAM alloc for Fragmentation table descriptor"));
41489 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41490 +
41491 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41492 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
41493 +
41494 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41495 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41496 + ccAdBaseReg |= (p_ManipParams->dontFragAction
41497 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
41498 +
41499 +
41500 + /* Set Scatter/Gather BPid */
41501 + if (p_ManipParams->sgBpidEn)
41502 + {
41503 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
41504 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41505 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
41506 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
41507 + }
41508 +
41509 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41510 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
41511 + - p_FmPcd->physicalMuramBase);
41512 +#if (DPAA_VERSION == 10)
41513 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41514 +#else
41515 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41516 +#endif /* (DPAA_VERSION == 10) */
41517 +
41518 + /* Set all Ad registers */
41519 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41520 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41521 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41522 +
41523 + /* Saves user's fragmentation manipulation parameters */
41524 + p_Manip->frag = TRUE;
41525 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41526 +
41527 +#if (DPAA_VERSION == 10)
41528 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
41529 +
41530 + /* scratch buffer pool initialization */
41531 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
41532 + {
41533 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41534 + p_Manip->fragParams.p_Frag = NULL;
41535 + RETURN_ERROR(MAJOR, err, NO_MSG);
41536 + }
41537 +#endif /* (DPAA_VERSION == 10) */
41538 +
41539 + return E_OK;
41540 +}
41541 +
41542 +static t_Error IPManip(t_FmPcdManip *p_Manip)
41543 +{
41544 + t_Error err = E_OK;
41545 + t_FmPcd *p_FmPcd;
41546 + t_AdOfTypeContLookup *p_Ad;
41547 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41548 +
41549 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41550 + p_FmPcd = p_Manip->h_FmPcd;
41551 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41552 +
41553 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41554 +
41555 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
41556 + if (p_Manip->frag == TRUE)
41557 + {
41558 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41559 + - (p_FmPcd->physicalMuramBase));
41560 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41561 + << FM_PCD_MANIP_IP_MTU_SHIFT;
41562 + }
41563 +
41564 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41565 + tmpReg32 |= HMAN_OC_IP_MANIP;
41566 +
41567 +#if (DPAA_VERSION >= 11)
41568 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
41569 +#endif /* (DPAA_VERSION >= 11) */
41570 +
41571 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41572 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41573 + WRITE_UINT32(p_Ad->gmask, 0);
41574 + /* Total frame counter - MUST be initialized to zero.*/
41575 +
41576 + return err;
41577 +}
41578 +
41579 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41580 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41581 + t_Handle h_Ad, bool validate)
41582 +{
41583 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41584 + t_Error err;
41585 +
41586 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41587 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
41588 + E_INVALID_STATE);
41589 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41590 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41591 +
41592 + UNUSED(h_FmPcd);
41593 + UNUSED(h_Ad);
41594 + UNUSED(h_PcdParams);
41595 + UNUSED(validate);
41596 + UNUSED(p_Manip);
41597 +
41598 + fmPortGetSetCcParams.setCcParams.type = 0;
41599 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41600 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41601 + RETURN_ERROR(MAJOR, err, NO_MSG);
41602 +
41603 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41604 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41605 +
41606 + return E_OK;
41607 +}
41608 +
41609 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
41610 + t_FmPcdManip *p_Manip)
41611 +{
41612 + t_AdOfTypeContLookup *p_Ad;
41613 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
41614 + t_Error err = E_OK;
41615 + uint32_t tmpReg32 = 0;
41616 + uint32_t power;
41617 +
41618 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41619 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41620 +
41621 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
41622 +
41623 + SANITY_CHECK_RETURN_ERROR(
41624 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
41625 + E_INVALID_VALUE);
41626 + SANITY_CHECK_RETURN_ERROR(
41627 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
41628 + E_INVALID_VALUE);
41629 + SANITY_CHECK_RETURN_ERROR(
41630 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
41631 + E_INVALID_VALUE);
41632 + SANITY_CHECK_RETURN_ERROR(
41633 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
41634 + E_INVALID_VALUE);
41635 + SANITY_CHECK_RETURN_ERROR(
41636 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
41637 + E_INVALID_VALUE);
41638 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
41639 +
41640 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41641 +
41642 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41643 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
41644 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
41645 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
41646 + tmpReg32 |=
41647 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
41648 + tmpReg32 |=
41649 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
41650 + if (p_IPSecParams->arwSize)
41651 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
41652 + & (FM_MURAM_SIZE-1));
41653 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41654 +
41655 + tmpReg32 = 0;
41656 + if (p_IPSecParams->arwSize) {
41657 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
41658 + LOG2(power, power);
41659 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
41660 + }
41661 +
41662 + if (p_ManipParams->h_NextManip)
41663 + tmpReg32 |=
41664 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
41665 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
41666 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41667 +
41668 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
41669 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
41670 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
41671 + if (p_ManipParams->h_NextManip)
41672 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
41673 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41674 +
41675 + return err;
41676 +}
41677 +
41678 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
41679 +{
41680 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41681 +
41682 + /* Allocation if CAPWAP Action descriptor */
41683 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
41684 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41685 + FM_PCD_CC_AD_TABLE_ALIGN);
41686 + if (!p_Manip->reassmParams.capwap.h_Ad)
41687 + {
41688 + ReleaseManipHandler(p_Manip, p_FmPcd);
41689 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41690 + ("Allocation of CAPWAP table descriptor"));
41691 + }
41692 +
41693 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41694 +
41695 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
41696 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
41697 +}
41698 +
41699 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
41700 + t_FmPcdKgSchemeParams *p_Scheme,
41701 + t_Handle h_CcTree, uint8_t groupId)
41702 +{
41703 + uint8_t res;
41704 +
41705 + /* Configures scheme's network environment parameters */
41706 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
41707 + res = FmPcdNetEnvGetUnitId(
41708 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41709 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41710 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41711 + p_Scheme->netEnvParams.unitIds[0] = res;
41712 +
41713 + /* Configures scheme's next engine parameters*/
41714 + p_Scheme->nextEngine = e_FM_PCD_CC;
41715 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41716 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41717 + p_Scheme->useHash = TRUE;
41718 +
41719 + /* Configures scheme's key*/
41720 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
41721 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41722 + e_FM_PCD_EXTRACT_NON_HDR;
41723 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
41724 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
41725 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
41726 + e_FM_PCD_ACTION_NONE;
41727 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
41728 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
41729 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41730 + e_FM_PCD_EXTRACT_NON_HDR;
41731 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
41732 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
41733 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
41734 + e_FM_PCD_ACTION_NONE;
41735 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
41736 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
41737 +
41738 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
41739 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
41740 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
41741 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
41742 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
41743 +}
41744 +
41745 +#if (DPAA_VERSION >= 11)
41746 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
41747 + t_FmPcdManipReassemCapwapStats *p_Stats)
41748 +{
41749 + ASSERT_COND(p_Manip);
41750 + ASSERT_COND(p_Stats);
41751 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41752 +
41753 + p_Stats->timeout =
41754 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41755 + p_Stats->rfdPoolBusy =
41756 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41757 + p_Stats->internalBufferBusy =
41758 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41759 + p_Stats->externalBufferBusy =
41760 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41761 + p_Stats->sgFragments =
41762 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41763 + p_Stats->dmaSemaphoreDepletion =
41764 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41765 + p_Stats->exceedMaxReassemblyFrameLen =
41766 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41767 +
41768 + p_Stats->successfullyReassembled =
41769 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
41770 + p_Stats->validFragments =
41771 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
41772 + p_Stats->processedFragments =
41773 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
41774 + p_Stats->malformedFragments =
41775 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
41776 + p_Stats->autoLearnBusy =
41777 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
41778 + p_Stats->discardedFragments =
41779 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
41780 + p_Stats->moreThan16Fragments =
41781 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
41782 +
41783 + return E_OK;
41784 +}
41785 +
41786 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
41787 + t_FmPcdManipFragCapwapStats *p_Stats)
41788 +{
41789 + t_AdOfTypeContLookup *p_Ad;
41790 +
41791 + ASSERT_COND(p_Manip);
41792 + ASSERT_COND(p_Stats);
41793 + ASSERT_COND(p_Manip->h_Ad);
41794 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41795 +
41796 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41797 +
41798 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41799 +
41800 + return E_OK;
41801 +}
41802 +
41803 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41804 + t_FmPcdManip *p_Manip)
41805 +{
41806 + uint32_t maxSetNumber = 10000;
41807 + t_FmPcdManipReassemCapwapParams reassmManipParams =
41808 + p_ManipReassmParams->u.capwapReassem;
41809 + t_Error res;
41810 +
41811 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41812 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41813 + E_INVALID_HANDLE);
41814 +
41815 + /* Check validation of user's parameter.*/
41816 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41817 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41818 + RETURN_ERROR(
41819 + MAJOR, E_INVALID_VALUE,
41820 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41821 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41822 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41823 + if (reassmManipParams.maxNumFramesInProcess
41824 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41825 + RETURN_ERROR(
41826 + MAJOR,
41827 + E_INVALID_VALUE,
41828 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41829 +
41830 + /* Saves user's reassembly manipulation parameters */
41831 + p_Manip->reassmParams.capwap.relativeSchemeId =
41832 + reassmManipParams.relativeSchemeId;
41833 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
41834 + reassmManipParams.numOfFramesPerHashEntry;
41835 + p_Manip->reassmParams.capwap.maxRessembledsSize =
41836 + reassmManipParams.maxReassembledFrameLength;
41837 + p_Manip->reassmParams.maxNumFramesInProcess =
41838 + reassmManipParams.maxNumFramesInProcess;
41839 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41840 + p_Manip->reassmParams.fqidForTimeOutFrames =
41841 + reassmManipParams.fqidForTimeOutFrames;
41842 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41843 + reassmManipParams.timeoutThresholdForReassmProcess;
41844 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41845 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41846 +
41847 + /* Creates and initializes the Reassembly common parameter table */
41848 + CreateReassCommonTable(p_Manip);
41849 +
41850 + res = SetCapwapReassmManip(p_Manip);
41851 + if (res != E_OK)
41852 + return res;
41853 +
41854 + return E_OK;
41855 +}
41856 +
41857 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
41858 + t_FmPcdManip *p_Manip)
41859 +{
41860 + t_FmPcd *p_FmPcd;
41861 + t_AdOfTypeContLookup *p_Ad;
41862 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41863 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41864 +
41865 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41866 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41867 + E_INVALID_VALUE);
41868 + p_FmPcd = p_Manip->h_FmPcd;
41869 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41870 +
41871 + /* Allocation of fragmentation Action Descriptor */
41872 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41873 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41874 + FM_PCD_CC_AD_TABLE_ALIGN);
41875 + if (!p_Manip->fragParams.p_Frag)
41876 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41877 + ("MURAM alloc for Fragmentation table descriptor"));
41878 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41879 +
41880 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41881 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
41882 +
41883 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41884 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41885 + ccAdBaseReg |=
41886 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
41887 + 0;
41888 +
41889 + /* Set Scatter/Gather BPid */
41890 + if (p_ManipParams->sgBpidEn)
41891 + {
41892 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
41893 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41894 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
41895 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
41896 + }
41897 +
41898 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41899 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
41900 + - p_FmPcd->physicalMuramBase);
41901 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41902 +
41903 + /* Set all Ad registers */
41904 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41905 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41906 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41907 +
41908 + /* Saves user's fragmentation manipulation parameters */
41909 + p_Manip->frag = TRUE;
41910 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41911 +
41912 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41913 +
41914 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41915 + - (p_FmPcd->physicalMuramBase));
41916 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41917 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
41918 +
41919 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41920 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
41921 +
41922 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
41923 +
41924 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41925 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41926 + WRITE_UINT32(p_Ad->gmask, 0);
41927 + /* Total frame counter - MUST be initialized to zero.*/
41928 +
41929 + return E_OK;
41930 +}
41931 +
41932 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41933 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41934 + t_Handle h_Ad, bool validate)
41935 +{
41936 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41937 + t_Error err;
41938 +
41939 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41940 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
41941 + E_INVALID_STATE);
41942 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41943 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41944 +
41945 + UNUSED(h_FmPcd);
41946 + UNUSED(h_Ad);
41947 + UNUSED(h_PcdParams);
41948 + UNUSED(validate);
41949 + UNUSED(p_Manip);
41950 +
41951 + fmPortGetSetCcParams.setCcParams.type = 0;
41952 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41953 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41954 + RETURN_ERROR(MAJOR, err, NO_MSG);
41955 +
41956 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41957 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41958 +
41959 + return E_OK;
41960 +}
41961 +
41962 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
41963 + t_FmPcdManip *p_Manip)
41964 +{
41965 + t_AdOfTypeContLookup *p_Ad;
41966 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
41967 + t_Error err = E_OK;
41968 + uint32_t tmpReg32 = 0;
41969 +
41970 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41971 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41972 +
41973 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
41974 +
41975 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41976 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41977 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
41978 + /* TODO - add 'qosSrc' */
41979 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41980 +
41981 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
41982 + if (p_ManipParams->h_NextManip)
41983 + {
41984 + WRITE_UINT32(
41985 + p_Ad->matchTblPtr,
41986 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
41987 +
41988 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
41989 + }
41990 +
41991 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41992 +
41993 + return err;
41994 +}
41995 +#endif /* (DPAA_VERSION >= 11) */
41996 +
41997 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
41998 + bool stats)
41999 +{
42000 + t_FmPcdManip *p_Manip;
42001 + t_Error err;
42002 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42003 +
42004 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42005 + if (!p_Manip)
42006 + {
42007 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42008 + return NULL;
42009 + }
42010 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42011 +
42012 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
42013 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
42014 + sizeof(p_Manip->manipParams));
42015 +
42016 + if (!stats)
42017 + err = CheckManipParamsAndSetType(p_Manip,
42018 + (t_FmPcdManipParams *)p_Params);
42019 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42020 + else
42021 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
42022 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42023 + else
42024 + {
42025 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
42026 + XX_Free(p_Manip);
42027 + return NULL;
42028 + }
42029 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42030 + if (err)
42031 + {
42032 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
42033 + XX_Free(p_Manip);
42034 + return NULL;
42035 + }
42036 +
42037 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
42038 + {
42039 + /* In Case of reassembly manipulation the reassembly action descriptor will
42040 + be defines later on */
42041 + if (p_Manip->muramAllocate)
42042 + {
42043 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
42044 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42045 + FM_PCD_CC_AD_TABLE_ALIGN);
42046 + if (!p_Manip->h_Ad)
42047 + {
42048 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
42049 + ReleaseManipHandler(p_Manip, p_FmPcd);
42050 + XX_Free(p_Manip);
42051 + return NULL;
42052 + }
42053 +
42054 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42055 + }
42056 + else
42057 + {
42058 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
42059 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42060 + if (!p_Manip->h_Ad)
42061 + {
42062 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42063 + ReleaseManipHandler(p_Manip, p_FmPcd);
42064 + XX_Free(p_Manip);
42065 + return NULL;
42066 + }
42067 +
42068 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42069 + }
42070 + }
42071 +
42072 + p_Manip->h_FmPcd = h_FmPcd;
42073 +
42074 + return p_Manip;
42075 +}
42076 +
42077 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42078 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
42079 +{
42080 + t_CcNodeInformation *p_CcNodeInformation;
42081 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
42082 + t_List *p_Pos;
42083 + int i = 0;
42084 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
42085 + t_CcNodeInformation ccNodeInfo;
42086 +
42087 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
42088 + {
42089 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
42090 + p_NodePtrOnCurrentMdfManip =
42091 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
42092 +
42093 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
42094 +
42095 + /* Search in the previous node which exact index points on this current modified node for getting AD */
42096 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
42097 + {
42098 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
42099 + == e_FM_PCD_CC)
42100 + {
42101 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
42102 + == (t_Handle)p_CrntMdfManip)
42103 + {
42104 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
42105 + p_AdTablePtOnCrntCurrentMdfNode =
42106 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
42107 + else
42108 + p_AdTablePtOnCrntCurrentMdfNode =
42109 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
42110 +
42111 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
42112 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
42113 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
42114 + }
42115 + }
42116 + }
42117 +
42118 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
42119 + }
42120 +}
42121 +
42122 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
42123 + t_FmPcd *p_FmPcd)
42124 +{
42125 + t_Error err;
42126 +
42127 + /* Copy the HMTD */
42128 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
42129 + /* Replace the HMCT table pointer */
42130 + WRITE_UINT32(
42131 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
42132 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
42133 + /* Call Host Command to replace HMTD by a new HMTD */
42134 + err = FmHcPcdCcDoDynamicChange(
42135 + p_FmPcd->h_Hc,
42136 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
42137 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
42138 + if (err)
42139 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
42140 +}
42141 +
42142 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42143 + t_Handle h_FmPort, t_Handle h_Manip,
42144 + t_Handle h_Ad, bool validate, int level,
42145 + t_Handle h_FmTree)
42146 +{
42147 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42148 + t_Error err = E_OK;
42149 +
42150 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42151 +
42152 + UNUSED(level);
42153 + UNUSED(h_FmTree);
42154 +
42155 + switch (p_Manip->opcode)
42156 + {
42157 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42158 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42159 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
42160 + p_Manip,
42161 + h_Ad,
42162 + validate);
42163 + break;
42164 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42165 + if (!p_Manip->h_Frag)
42166 + break;
42167 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42168 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
42169 + break;
42170 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42171 + if (p_Manip->h_Frag)
42172 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
42173 + break;
42174 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42175 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
42176 + break;
42177 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42178 + case (HMAN_OC_IP_REASSEMBLY):
42179 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42180 + validate);
42181 + break;
42182 + case (HMAN_OC_IP_FRAGMENTATION):
42183 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42184 + h_Ad, validate);
42185 + break;
42186 +#if (DPAA_VERSION >= 11)
42187 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42188 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42189 + h_Ad, validate);
42190 + break;
42191 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42192 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42193 + validate);
42194 + break;
42195 +#endif /* (DPAA_VERSION >= 11) */
42196 + default:
42197 + return E_OK;
42198 + }
42199 +
42200 + return err;
42201 +}
42202 +
42203 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
42204 + bool validate, int level,
42205 + t_Handle h_FmTree)
42206 +{
42207 +
42208 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42209 + t_Error err = E_OK;
42210 +
42211 + UNUSED(level);
42212 +
42213 + switch (p_Manip->opcode)
42214 + {
42215 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42216 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42217 + RETURN_ERROR(
42218 + MAJOR,
42219 + E_INVALID_STATE,
42220 + ("modify node with this type of manipulation is not suppported"));
42221 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42222 +
42223 + if (p_Manip->h_Frag)
42224 + {
42225 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
42226 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
42227 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
42228 + RETURN_ERROR(
42229 + MAJOR,
42230 + E_INVALID_STATE,
42231 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
42232 + }
42233 + break;
42234 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42235 + if (p_Manip->h_Frag)
42236 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
42237 + break;
42238 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42239 + default:
42240 + return E_OK;
42241 + }
42242 +
42243 + return err;
42244 +}
42245 +
42246 +/*****************************************************************************/
42247 +/* Inter-module API routines */
42248 +/*****************************************************************************/
42249 +
42250 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42251 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
42252 + bool validate, int level, t_Handle h_FmTree,
42253 + bool modify)
42254 +{
42255 + t_Error err;
42256 +
42257 + if (!modify)
42258 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
42259 + h_Ad, validate, level, h_FmTree);
42260 + else
42261 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
42262 +
42263 + return err;
42264 +}
42265 +
42266 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
42267 +{
42268 +
42269 + uint32_t intFlags;
42270 +
42271 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
42272 + if (add)
42273 + ((t_FmPcdManip *)h_Manip)->owner++;
42274 + else
42275 + {
42276 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
42277 + ((t_FmPcdManip *)h_Manip)->owner--;
42278 + }
42279 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
42280 +}
42281 +
42282 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
42283 +{
42284 + ASSERT_COND(h_Manip);
42285 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
42286 +}
42287 +
42288 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
42289 +{
42290 + ASSERT_COND(h_Manip);
42291 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
42292 +}
42293 +
42294 +t_Error FmPcdManipCheckParamsForCcNextEngine(
42295 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
42296 + uint32_t *requiredAction)
42297 +{
42298 + t_FmPcdManip *p_Manip;
42299 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42300 + t_Error err = E_OK;
42301 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
42302 + bool pointFromCc = TRUE;
42303 +
42304 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
42305 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
42306 + E_NULL_POINTER);
42307 +
42308 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
42309 + *requiredAction = 0;
42310 +
42311 + while (p_Manip)
42312 + {
42313 + switch (p_Manip->opcode)
42314 + {
42315 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42316 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42317 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42318 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42319 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42320 + p_Manip->cnia = TRUE;
42321 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42322 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42323 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42324 + p_Manip->ownerTmp++;
42325 + break;
42326 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42327 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42328 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42329 + RETURN_ERROR(
42330 + MAJOR,
42331 + E_INVALID_STATE,
42332 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
42333 + p_Manip->ownerTmp++;
42334 + break;
42335 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42336 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
42337 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
42338 + != CC_PC_GENERIC_IC_HASH_INDEXED))
42339 + 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"));
42340 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
42341 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
42342 + if (err)
42343 + RETURN_ERROR(MAJOR, err, NO_MSG);
42344 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42345 + break;
42346 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42347 + case (HMAN_OC_IP_FRAGMENTATION):
42348 + case (HMAN_OC_IP_REASSEMBLY):
42349 +#if (DPAA_VERSION >= 11)
42350 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42351 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42352 +#endif /* (DPAA_VERSION >= 11) */
42353 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42354 + RETURN_ERROR(
42355 + MAJOR,
42356 + E_INVALID_STATE,
42357 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42358 + p_Manip->ownerTmp++;
42359 + break;
42360 + case (HMAN_OC_IPSEC_MANIP):
42361 +#if (DPAA_VERSION >= 11)
42362 + case (HMAN_OC_CAPWAP_MANIP):
42363 +#endif /* (DPAA_VERSION >= 11) */
42364 + p_Manip->ownerTmp++;
42365 + break;
42366 + case (HMAN_OC):
42367 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
42368 + && MANIP_IS_CASCADED(p_Manip))
42369 + RETURN_ERROR(
42370 + MINOR,
42371 + E_INVALID_STATE,
42372 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
42373 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
42374 + RETURN_ERROR(
42375 + MAJOR,
42376 + E_INVALID_STATE,
42377 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
42378 + break;
42379 + default:
42380 + RETURN_ERROR(
42381 + MAJOR, E_INVALID_STATE,
42382 + ("invalid type of header manipulation for this state"));
42383 + }
42384 + p_Manip = p_Manip->h_NextManip;
42385 + pointFromCc = FALSE;
42386 + }
42387 + return E_OK;
42388 +}
42389 +
42390 +
42391 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
42392 + t_Handle h_FmPcdCcNode)
42393 +{
42394 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42395 + t_Error err = E_OK;
42396 +
42397 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42398 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
42399 +
42400 + switch (p_Manip->opcode)
42401 + {
42402 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42403 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42404 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42405 + RETURN_ERROR(
42406 + MAJOR,
42407 + E_INVALID_VALUE,
42408 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
42409 + break;
42410 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42411 + if (p_Manip->h_Frag)
42412 + {
42413 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42414 + RETURN_ERROR(
42415 + MAJOR,
42416 + E_INVALID_VALUE,
42417 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
42418 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
42419 + if (err)
42420 + RETURN_ERROR(MAJOR, err, NO_MSG);
42421 + }
42422 + break;
42423 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42424 + default:
42425 + break;
42426 + }
42427 +
42428 + return err;
42429 +}
42430 +
42431 +void FmPcdManipUpdateAdResultForCc(
42432 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
42433 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
42434 +{
42435 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42436 +
42437 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42438 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42439 +
42440 + ASSERT_COND(p_Manip);
42441 + ASSERT_COND(p_CcNextEngineParams);
42442 + ASSERT_COND(p_Ad);
42443 + ASSERT_COND(p_AdNewPtr);
42444 +
42445 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42446 +
42447 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
42448 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
42449 + switch (p_Manip->opcode)
42450 + {
42451 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42452 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42453 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42454 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42455 + *p_AdNewPtr = p_Manip->h_Ad;
42456 + break;
42457 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42458 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42459 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
42460 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
42461 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
42462 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
42463 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
42464 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
42465 + *p_AdNewPtr = NULL;
42466 + break;
42467 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42468 + case (HMAN_OC_IPSEC_MANIP):
42469 +#if (DPAA_VERSION >= 11)
42470 + case (HMAN_OC_CAPWAP_MANIP):
42471 +#endif /* (DPAA_VERSION >= 11) */
42472 + *p_AdNewPtr = p_Manip->h_Ad;
42473 + break;
42474 + case (HMAN_OC_IP_FRAGMENTATION):
42475 +#if (DPAA_VERSION >= 11)
42476 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42477 +#endif /* (DPAA_VERSION >= 11) */
42478 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
42479 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
42480 + {
42481 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
42482 + sizeof(t_AdOfTypeContLookup));
42483 +#if (DPAA_VERSION >= 11)
42484 + WRITE_UINT32(
42485 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42486 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
42487 +#endif /* (DPAA_VERSION >= 11) */
42488 + *p_AdNewPtr = NULL;
42489 + }
42490 + else
42491 + *p_AdNewPtr = p_Manip->h_Ad;
42492 + break;
42493 + case (HMAN_OC_IP_REASSEMBLY):
42494 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
42495 + {
42496 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
42497 + {
42498 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
42499 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
42500 + FmPcdManipUpdateOwner(h_Manip, FALSE);
42501 + }
42502 + else
42503 + {
42504 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42505 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
42506 + }
42507 + }
42508 + else
42509 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42510 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42511 + sizeof(t_AdOfTypeContLookup));
42512 + *p_AdNewPtr = NULL;
42513 + break;
42514 +#if (DPAA_VERSION >= 11)
42515 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42516 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
42517 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42518 + sizeof(t_AdOfTypeContLookup));
42519 + *p_AdNewPtr = NULL;
42520 + break;
42521 +#endif /* (DPAA_VERSION >= 11) */
42522 + case (HMAN_OC):
42523 + /* Allocate and initialize HMTD */
42524 + *p_AdNewPtr = p_Manip->h_Ad;
42525 + break;
42526 + default:
42527 + break;
42528 + }
42529 +}
42530 +
42531 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
42532 + t_Handle *p_AdNewPtr,
42533 + uint32_t adTableOffset)
42534 +{
42535 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42536 +
42537 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42538 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42539 + ASSERT_COND(p_Manip);
42540 +
42541 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42542 +
42543 + switch (p_Manip->opcode)
42544 + {
42545 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42546 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42547 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42548 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
42549 + WRITE_UINT32(
42550 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
42551 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
42552 + WRITE_UINT32(
42553 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
42554 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
42555 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
42556 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
42557 + WRITE_UINT32(
42558 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42559 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
42560 + *p_AdNewPtr = NULL;
42561 + break;
42562 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42563 + case (HMAN_OC):
42564 + /* Initialize HMTD within the match table*/
42565 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42566 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
42567 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
42568 + /* update NADEN to be "1"*/
42569 + WRITE_UINT16(
42570 + ((t_Hmtd *)p_Ad)->cfg,
42571 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
42572 + /* update next action descriptor */
42573 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
42574 + (uint16_t)(adTableOffset >> 4));
42575 + /* mark that Manip's HMTD is not used */
42576 + *p_AdNewPtr = NULL;
42577 + break;
42578 +
42579 + default:
42580 + break;
42581 + }
42582 +}
42583 +
42584 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42585 + t_Handle h_CcTree, t_Handle h_Manip,
42586 + bool isIpv4, uint8_t groupId)
42587 +{
42588 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42589 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42590 + t_Handle h_Scheme;
42591 +
42592 + ASSERT_COND(p_FmPcd);
42593 + ASSERT_COND(h_NetEnv);
42594 + ASSERT_COND(p_Manip);
42595 +
42596 + /* scheme was already build, no need to check for IPv6 */
42597 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
42598 + return E_OK;
42599 +
42600 + if (isIpv4) {
42601 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
42602 + if (h_Scheme) {
42603 + /* scheme was found */
42604 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
42605 + return E_OK;
42606 + }
42607 + } else {
42608 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
42609 + if (h_Scheme) {
42610 + /* scheme was found */
42611 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
42612 + return E_OK;
42613 + }
42614 + }
42615 +
42616 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42617 + if (!p_SchemeParams)
42618 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42619 + ("Memory allocation failed for scheme"));
42620 +
42621 + /* Configures the IPv4 or IPv6 scheme*/
42622 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42623 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42624 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
42625 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
42626 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
42627 + p_SchemeParams->schemeCounter.update = TRUE;
42628 +#if (DPAA_VERSION >= 11)
42629 + p_SchemeParams->alwaysDirect = TRUE;
42630 + p_SchemeParams->bypassFqidGeneration = TRUE;
42631 +#else
42632 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
42633 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
42634 +#endif /* (DPAA_VERSION >= 11) */
42635 +
42636 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
42637 +
42638 + /* Sets the new scheme */
42639 + if (isIpv4)
42640 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
42641 + p_FmPcd, p_SchemeParams);
42642 + else
42643 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
42644 + p_FmPcd, p_SchemeParams);
42645 +
42646 + XX_Free(p_SchemeParams);
42647 +
42648 + return E_OK;
42649 +}
42650 +
42651 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
42652 +{
42653 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42654 +
42655 + ASSERT_COND(p_Manip);
42656 +
42657 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
42658 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
42659 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
42660 +
42661 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
42662 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
42663 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
42664 +
42665 + return E_OK;
42666 +}
42667 +
42668 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
42669 +{
42670 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42671 +
42672 + ASSERT_COND(p_Manip);
42673 +
42674 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
42675 +}
42676 +
42677 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42678 + t_Handle h_CcTree, t_Handle h_Manip,
42679 + uint8_t groupId)
42680 +{
42681 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42682 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42683 +
42684 + ASSERT_COND(p_FmPcd);
42685 + ASSERT_COND(h_NetEnv);
42686 + ASSERT_COND(p_Manip);
42687 +
42688 + /* scheme was already build, no need to check for IPv6 */
42689 + if (p_Manip->reassmParams.capwap.h_Scheme)
42690 + return E_OK;
42691 +
42692 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42693 + if (!p_SchemeParams)
42694 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42695 + ("Memory allocation failed for scheme"));
42696 +
42697 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42698 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42699 + p_SchemeParams->id.relativeSchemeId =
42700 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
42701 + p_SchemeParams->schemeCounter.update = TRUE;
42702 + p_SchemeParams->bypassFqidGeneration = TRUE;
42703 +
42704 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
42705 +
42706 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
42707 + p_SchemeParams);
42708 +
42709 + XX_Free(p_SchemeParams);
42710 +
42711 + return E_OK;
42712 +}
42713 +
42714 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
42715 +{
42716 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42717 +
42718 + ASSERT_COND(p_Manip);
42719 +
42720 + if (p_Manip->reassmParams.capwap.h_Scheme)
42721 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
42722 +
42723 + return E_OK;
42724 +}
42725 +
42726 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42727 +t_Handle FmPcdManipApplSpecificBuild(void)
42728 +{
42729 + t_FmPcdManip *p_Manip;
42730 +
42731 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42732 + if (!p_Manip)
42733 + {
42734 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42735 + return NULL;
42736 + }
42737 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42738 +
42739 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
42740 + p_Manip->muramAllocate = FALSE;
42741 +
42742 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42743 + if (!p_Manip->h_Ad)
42744 + {
42745 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42746 + XX_Free(p_Manip);
42747 + return NULL;
42748 + }
42749 +
42750 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42751 +
42752 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
42753 + /*Application specific = type of flowId index, move internal frame header from data to IC,
42754 + SEC errors check*/
42755 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
42756 + {
42757 + XX_Free(p_Manip->h_Ad);
42758 + XX_Free(p_Manip);
42759 + return NULL;
42760 + }
42761 + return p_Manip;
42762 +}
42763 +
42764 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
42765 +{
42766 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42767 + ASSERT_COND(h_Manip);
42768 +
42769 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
42770 +}
42771 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42772 +/*********************** End of inter-module routines ************************/
42773 +
42774 +/****************************************/
42775 +/* API Init unit functions */
42776 +/****************************************/
42777 +
42778 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
42779 + t_FmPcdManipParams *p_ManipParams)
42780 +{
42781 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42782 + t_FmPcdManip *p_Manip;
42783 + t_Error err;
42784 +
42785 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
42786 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
42787 +
42788 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
42789 + if (!p_Manip)
42790 + return NULL;
42791 +
42792 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
42793 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
42794 + || (p_Manip->opcode == HMAN_OC)
42795 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
42796 +#if (DPAA_VERSION >= 11)
42797 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
42798 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
42799 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
42800 +#endif /* (DPAA_VERSION >= 11) */
42801 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
42802 + {
42803 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
42804 + XX_Free(p_Manip);
42805 + return NULL;
42806 + }
42807 + p_Manip->h_Spinlock = XX_InitSpinlock();
42808 + if (!p_Manip->h_Spinlock)
42809 + {
42810 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42811 + ReleaseManipHandler(p_Manip, p_FmPcd);
42812 + XX_Free(p_Manip);
42813 + return NULL;
42814 + }INIT_LIST(&p_Manip->nodesLst);
42815 +
42816 + switch (p_Manip->opcode)
42817 + {
42818 + case (HMAN_OC_IP_REASSEMBLY):
42819 + /* IpReassembly */
42820 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
42821 + break;
42822 + case (HMAN_OC_IP_FRAGMENTATION):
42823 + /* IpFragmentation */
42824 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
42825 + if (err)
42826 + break;
42827 + err = IPManip(p_Manip);
42828 + break;
42829 + case (HMAN_OC_IPSEC_MANIP):
42830 + err = IPSecManip(p_ManipParams, p_Manip);
42831 + break;
42832 +#if (DPAA_VERSION >= 11)
42833 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42834 + /* CapwapReassembly */
42835 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
42836 + break;
42837 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42838 + /* CapwapFragmentation */
42839 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
42840 + p_Manip);
42841 + break;
42842 + case (HMAN_OC_CAPWAP_MANIP):
42843 + err = CapwapManip(p_ManipParams, p_Manip);
42844 + break;
42845 +#endif /* (DPAA_VERSION >= 11) */
42846 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42847 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42848 + /* HmanType1 */
42849 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
42850 + break;
42851 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42852 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
42853 + p_Manip,
42854 + p_FmPcd,
42855 + p_ManipParams->fragOrReasmParams.sgBpid);
42856 + if (err)
42857 + {
42858 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42859 + ReleaseManipHandler(p_Manip, p_FmPcd);
42860 + XX_Free(p_Manip);
42861 + return NULL;
42862 + }
42863 + if (p_Manip->insrt)
42864 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
42865 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42866 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
42867 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
42868 + break;
42869 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42870 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
42871 + p_Manip,
42872 + p_FmPcd,
42873 + p_ManipParams->fragOrReasmParams.sgBpid);
42874 + if (err)
42875 + {
42876 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42877 + ReleaseManipHandler(p_Manip, p_FmPcd);
42878 + XX_Free(p_Manip);
42879 + return NULL;
42880 + }
42881 + if (p_Manip->rmv)
42882 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
42883 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42884 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
42885 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
42886 + break;
42887 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42888 + /*Application Specific type 1*/
42889 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
42890 + break;
42891 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42892 + case (HMAN_OC):
42893 + /* New Manip */
42894 + err = CreateManipActionNew(p_Manip, p_ManipParams);
42895 + break;
42896 + default:
42897 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
42898 + ReleaseManipHandler(p_Manip, p_FmPcd);
42899 + XX_Free(p_Manip);
42900 + return NULL;
42901 + }
42902 +
42903 + if (err)
42904 + {
42905 + REPORT_ERROR(MAJOR, err, NO_MSG);
42906 + ReleaseManipHandler(p_Manip, p_FmPcd);
42907 + XX_Free(p_Manip);
42908 + return NULL;
42909 + }
42910 +
42911 + if (p_ManipParams->h_NextManip)
42912 + {
42913 + /* in the check routine we've verified that h_NextManip has no owners
42914 + * and that only supported types are allowed. */
42915 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
42916 + /* save a "prev" pointer in h_NextManip */
42917 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
42918 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
42919 + }
42920 +
42921 + return p_Manip;
42922 +}
42923 +
42924 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
42925 + t_FmPcdManipParams *p_ManipParams)
42926 +{
42927 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
42928 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
42929 + t_Error err;
42930 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
42931 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
42932 + t_CcNodeInformation *p_CcNodeInfo;
42933 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42934 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
42935 +
42936 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
42937 +
42938 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
42939 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
42940 + RETURN_ERROR(
42941 + MINOR,
42942 + E_NOT_SUPPORTED,
42943 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
42944 +
42945 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
42946 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
42947 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
42948 + sizeof(p_Manip->manipParams));
42949 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
42950 +
42951 + /* The replacement of the HdrManip depends on the node type.*/
42952 + /*
42953 + * (1) If this is an independent node, all its owners should be updated.
42954 + *
42955 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
42956 + * it has a "next" and it has a "cascaded" indication), the next
42957 + * node remains unchanged, and the behavior is as in (1).
42958 + *
42959 + * (3) If it is not the head, but a part of a cascaded chain, in can be
42960 + * also replaced as a regular node with just one owner.
42961 + *
42962 + * (4) If it is a part of a chain implemented as a unified table, the
42963 + * whole table is replaced and the owners of the head node must be updated.
42964 + *
42965 + */
42966 + /* lock shadow */
42967 + if (!p_FmPcd->p_CcShadow)
42968 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
42969 +
42970 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
42971 + return ERROR_CODE(E_BUSY);
42972 +
42973 + /* this routine creates a new manip action in the CC Shadow. */
42974 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
42975 + if (err)
42976 + RETURN_ERROR(MINOR, err, NO_MSG);
42977 +
42978 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
42979 + * replace only HMTD and no lcok is required. Otherwise
42980 + * lock the whole PCD
42981 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
42982 + if (!FmPcdLockTryLockAll(p_FmPcd))
42983 + {
42984 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
42985 + return ERROR_CODE(E_BUSY);
42986 + }
42987 +
42988 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
42989 +
42990 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
42991 + e_MANIP_HANDLER_TABLE_OWNER);
42992 + ASSERT_COND(p_FirstManip);
42993 +
42994 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
42995 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42996 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
42997 +
42998 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
42999 + ASSERT_COND(p_Hmtd);
43000 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
43001 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
43002 +
43003 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43004 + {
43005 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43006 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43007 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43008 + }
43009 +
43010 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
43011 + ASSERT_COND(p_WholeHmct);
43012 +
43013 + /* re-build the HMCT n the original location */
43014 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
43015 + if (err)
43016 + {
43017 + RELEASE_LOCK(p_FmPcd->shadowLock);
43018 + RETURN_ERROR(MINOR, err, NO_MSG);
43019 + }
43020 +
43021 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43022 + ASSERT_COND(p_Hmtd);
43023 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
43024 + ((t_FmPcd*)p_Manip->h_FmPcd));
43025 +
43026 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
43027 + * For each p_Hmct (from list+fixed):
43028 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43029 + {
43030 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43031 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43032 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43033 + }
43034 +
43035 +
43036 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
43037 +
43038 + FmPcdLockUnlockAll(p_FmPcd);
43039 +
43040 + /* unlock shadow */
43041 + RELEASE_LOCK(p_FmPcd->shadowLock);
43042 +
43043 + return E_OK;
43044 +}
43045 +
43046 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
43047 +{
43048 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43049 +
43050 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43051 +
43052 + if (p_Manip->owner)
43053 + RETURN_ERROR(
43054 + MAJOR,
43055 + E_INVALID_STATE,
43056 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
43057 +
43058 + if (p_Manip->h_NextManip)
43059 + {
43060 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
43061 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
43062 + }
43063 +
43064 + if (p_Manip->p_Hmct
43065 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
43066 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
43067 + p_Manip->p_Hmct);
43068 +
43069 + if (p_Manip->h_Spinlock)
43070 + {
43071 + XX_FreeSpinlock(p_Manip->h_Spinlock);
43072 + p_Manip->h_Spinlock = NULL;
43073 + }
43074 +
43075 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
43076 +
43077 + XX_Free(h_ManipNode);
43078 +
43079 + return E_OK;
43080 +}
43081 +
43082 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
43083 + t_FmPcdManipStats *p_FmPcdManipStats)
43084 +{
43085 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43086 +
43087 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43088 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
43089 +
43090 + switch (p_Manip->opcode)
43091 + {
43092 + case (HMAN_OC_IP_REASSEMBLY):
43093 + return IpReassemblyStats(p_Manip,
43094 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
43095 + case (HMAN_OC_IP_FRAGMENTATION):
43096 + return IpFragmentationStats(p_Manip,
43097 + &p_FmPcdManipStats->u.frag.u.ipFrag);
43098 +#if (DPAA_VERSION >= 11)
43099 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43100 + return CapwapReassemblyStats(
43101 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
43102 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43103 + return CapwapFragmentationStats(
43104 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
43105 +#endif /* (DPAA_VERSION >= 11) */
43106 + default:
43107 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
43108 + ("no statistics to this type of manip"));
43109 + }
43110 +
43111 + return E_OK;
43112 +}
43113 +
43114 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43115 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
43116 +{
43117 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43118 + t_FmPcdManip *p_Manip;
43119 + t_Error err;
43120 +
43121 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
43122 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
43123 +
43124 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
43125 + if (!p_Manip)
43126 + return NULL;
43127 +
43128 + switch (p_Manip->opcode)
43129 + {
43130 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43131 + /* Indexed statistics */
43132 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
43133 + break;
43134 + default:
43135 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
43136 + ReleaseManipHandler(p_Manip, p_FmPcd);
43137 + XX_Free(p_Manip);
43138 + return NULL;
43139 + }
43140 +
43141 + if (err)
43142 + {
43143 + REPORT_ERROR(MAJOR, err, NO_MSG);
43144 + ReleaseManipHandler(p_Manip, p_FmPcd);
43145 + XX_Free(p_Manip);
43146 + return NULL;
43147 + }
43148 +
43149 + return p_Manip;
43150 +}
43151 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43152 --- /dev/null
43153 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43154 @@ -0,0 +1,555 @@
43155 +/*
43156 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43157 + *
43158 + * Redistribution and use in source and binary forms, with or without
43159 + * modification, are permitted provided that the following conditions are met:
43160 + * * Redistributions of source code must retain the above copyright
43161 + * notice, this list of conditions and the following disclaimer.
43162 + * * Redistributions in binary form must reproduce the above copyright
43163 + * notice, this list of conditions and the following disclaimer in the
43164 + * documentation and/or other materials provided with the distribution.
43165 + * * Neither the name of Freescale Semiconductor nor the
43166 + * names of its contributors may be used to endorse or promote products
43167 + * derived from this software without specific prior written permission.
43168 + *
43169 + *
43170 + * ALTERNATIVELY, this software may be distributed under the terms of the
43171 + * GNU General Public License ("GPL") as published by the Free Software
43172 + * Foundation, either version 2 of that License or (at your option) any
43173 + * later version.
43174 + *
43175 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43176 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43177 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43178 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43179 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43180 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43181 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43182 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43183 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43184 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43185 + */
43186 +
43187 +
43188 +/******************************************************************************
43189 + @File fm_manip.h
43190 +
43191 + @Description FM PCD manip...
43192 +*//***************************************************************************/
43193 +#ifndef __FM_MANIP_H
43194 +#define __FM_MANIP_H
43195 +
43196 +#include "std_ext.h"
43197 +#include "error_ext.h"
43198 +#include "list_ext.h"
43199 +
43200 +#include "fm_cc.h"
43201 +
43202 +
43203 +/***********************************************************************/
43204 +/* Header manipulations defines */
43205 +/***********************************************************************/
43206 +
43207 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
43208 +
43209 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43210 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
43211 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
43212 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
43213 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
43214 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
43215 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
43216 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43217 +#else
43218 +#define HMAN_OC_CAPWAP_MANIP 0x2F
43219 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
43220 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43221 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
43222 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43223 +#define HMAN_OC_IP_MANIP 0x34
43224 +#define HMAN_OC_IP_FRAGMENTATION 0x74
43225 +#define HMAN_OC_IP_REASSEMBLY 0xB4
43226 +#define HMAN_OC_IPSEC_MANIP 0xF4
43227 +#define HMAN_OC 0x35
43228 +
43229 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43230 +#define HMAN_RMV_HDR 0x80000000
43231 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
43232 +
43233 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
43234 +#define UDP_CHECKSUM_FIELD_SIZE 2
43235 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
43236 +
43237 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
43238 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
43239 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
43240 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
43241 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
43242 +
43243 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
43244 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
43245 +
43246 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
43247 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
43248 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
43249 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
43250 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
43251 +
43252 +
43253 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
43254 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
43255 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
43256 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
43257 +
43258 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
43259 +
43260 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
43261 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
43262 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
43263 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43264 +
43265 +#if (DPAA_VERSION >= 11)
43266 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
43267 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
43268 +
43269 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
43270 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
43271 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
43272 +
43273 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
43274 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
43275 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
43276 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
43277 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
43278 +#endif /* (DPAA_VERSION >= 11) */
43279 +
43280 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
43281 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
43282 +
43283 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
43284 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
43285 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
43286 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
43287 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
43288 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
43289 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
43290 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
43291 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
43292 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
43293 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
43294 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
43295 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
43296 +
43297 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
43298 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
43299 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
43300 +
43301 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
43302 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
43303 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
43304 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
43305 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
43306 +
43307 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
43308 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
43309 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
43310 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
43311 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
43312 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
43313 +
43314 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
43315 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
43316 +
43317 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
43318 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
43319 +
43320 +#define e_FM_MANIP_IP_INDX 1
43321 +
43322 +#define HMCD_OPCODE_GENERIC_RMV 0x01
43323 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
43324 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
43325 +#define HMCD_OPCODE_L2_RMV 0x08
43326 +#define HMCD_OPCODE_L2_INSRT 0x09
43327 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
43328 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
43329 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
43330 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
43331 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
43332 +#define HMCD_OPCODE_REPLACE_IP 0x12
43333 +#define HMCD_OPCODE_RMV_TILL 0x15
43334 +#define HMCD_OPCODE_UDP_INSRT 0x16
43335 +#define HMCD_OPCODE_IP_INSRT 0x17
43336 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
43337 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
43338 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
43339 +
43340 +#define HMCD_LAST 0x00800000
43341 +
43342 +#define HMCD_DSCP_VALUES 64
43343 +
43344 +#define HMCD_BASIC_SIZE 4
43345 +#define HMCD_PTR_SIZE 4
43346 +#define HMCD_PARAM_SIZE 4
43347 +#define HMCD_IPV4_ADDR_SIZE 4
43348 +#define HMCD_IPV6_ADDR_SIZE 0x10
43349 +#define HMCD_L4_HDR_SIZE 8
43350 +
43351 +#define HMCD_CAPWAP_INSRT 0x00010000
43352 +#define HMCD_INSRT_UDP_LITE 0x00010000
43353 +#define HMCD_IP_ID_MASK 0x0000FFFF
43354 +#define HMCD_IP_SIZE_MASK 0x0000FF00
43355 +#define HMCD_IP_SIZE_SHIFT 8
43356 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
43357 +#define HMCD_IP_OR_QOS 0x00010000
43358 +#define HMCD_IP_L4_CS_CALC 0x00040000
43359 +#define HMCD_IP_DF_MODE 0x00400000
43360 +
43361 +
43362 +#define HMCD_OC_SHIFT 24
43363 +
43364 +#define HMCD_RMV_OFFSET_SHIFT 0
43365 +#define HMCD_RMV_SIZE_SHIFT 8
43366 +
43367 +#define HMCD_INSRT_OFFSET_SHIFT 0
43368 +#define HMCD_INSRT_SIZE_SHIFT 8
43369 +
43370 +#define HMTD_CFG_TYPE 0x4000
43371 +#define HMTD_CFG_EXT_HMCT 0x0080
43372 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
43373 +#define HMTD_CFG_NEXT_AD_EN 0x0020
43374 +
43375 +#define HMCD_RMV_L2_ETHERNET 0
43376 +#define HMCD_RMV_L2_STACKED_QTAGS 1
43377 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
43378 +#define HMCD_RMV_L2_MPLS 3
43379 +#define HMCD_RMV_L2_PPPOE 4
43380 +
43381 +#define HMCD_INSRT_L2_MPLS 0
43382 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
43383 +#define HMCD_INSRT_L2_PPPOE 2
43384 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
43385 +
43386 +#define HMCD_L2_MODE_SHIFT 16
43387 +
43388 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
43389 +#define HMCD_VLAN_PRI_UPDATE 0
43390 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
43391 +
43392 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
43393 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
43394 +#define HMCD_IPV4_UPDATE_DST 0x00000020
43395 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
43396 +#define HMCD_IPV4_UPDATE_ID 0x00000080
43397 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
43398 +
43399 +#define HMCD_IPV6_UPDATE_HL 0x00000001
43400 +#define HMCD_IPV6_UPDATE_TC 0x00000002
43401 +#define HMCD_IPV6_UPDATE_DST 0x00000040
43402 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
43403 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
43404 +
43405 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
43406 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
43407 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
43408 +
43409 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
43410 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
43411 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
43412 +#define HMCD_IP_REPLACE_ID 0x00400000
43413 +
43414 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
43415 +
43416 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
43417 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
43418 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
43419 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
43420 +
43421 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
43422 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
43423 +
43424 +#define DSCP_TO_VLAN_TABLE_SIZE 32
43425 +
43426 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
43427 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
43428 +
43429 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
43430 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
43431 +
43432 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
43433 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
43434 +
43435 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
43436 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
43437 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
43438 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
43439 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
43440 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
43441 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
43442 +#define MANIP_FREE_HMTD(h_Manip) \
43443 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
43444 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
43445 + else \
43446 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
43447 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
43448 + }
43449 +/* position regarding Manip SW structure */
43450 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
43451 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
43452 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
43453 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
43454 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
43455 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
43456 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
43457 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
43458 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
43459 +
43460 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
43461 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
43462 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
43463 +
43464 +typedef enum e_ManipUnifiedPosition {
43465 + e_MANIP_UNIFIED_NONE = 0,
43466 + e_MANIP_UNIFIED_FIRST,
43467 + e_MANIP_UNIFIED_MID,
43468 + e_MANIP_UNIFIED_LAST
43469 +} e_ManipUnifiedPosition;
43470 +
43471 +typedef enum e_ManipInfo {
43472 + e_MANIP_HMTD,
43473 + e_MANIP_HMCT,
43474 + e_MANIP_HANDLER_TABLE_OWNER
43475 +}e_ManipInfo;
43476 +/***********************************************************************/
43477 +/* Memory map */
43478 +/***********************************************************************/
43479 +#if defined(__MWERKS__) && !defined(__GNUC__)
43480 +#pragma pack(push,1)
43481 +#endif /* defined(__MWERKS__) && ... */
43482 +
43483 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43484 +typedef struct t_CapwapReasmPram {
43485 + volatile uint32_t mode;
43486 + volatile uint32_t autoLearnHashTblPtr;
43487 + volatile uint32_t intStatsTblPtr;
43488 + volatile uint32_t reasmFrmDescPoolTblPtr;
43489 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
43490 + volatile uint32_t timeOutTblPtr;
43491 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
43492 + volatile uint32_t risc23SetIndexes;
43493 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
43494 + volatile uint32_t extendedStatsTblPtr;
43495 + volatile uint32_t expirationDelay;
43496 + volatile uint32_t totalProcessedFragCounter;
43497 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
43498 + volatile uint32_t totalDuplicatedFragCounter;
43499 + volatile uint32_t totalMalformdFragCounter;
43500 + volatile uint32_t totalTimeOutCounter;
43501 + volatile uint32_t totalSetBusyCounter;
43502 + volatile uint32_t totalRfdPoolBusyCounter;
43503 + volatile uint32_t totalDiscardedFragsCounter;
43504 + volatile uint32_t totalMoreThan16FramesCounter;
43505 + volatile uint32_t internalBufferBusy;
43506 + volatile uint32_t externalBufferBusy;
43507 + volatile uint32_t reserved1[4];
43508 +} t_CapwapReasmPram;
43509 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43510 +
43511 +typedef _Packed struct t_ReassTbl {
43512 + volatile uint16_t waysNumAndSetSize;
43513 + volatile uint16_t autoLearnHashKeyMask;
43514 + volatile uint32_t reassCommonPrmTblPtr;
43515 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
43516 + volatile uint32_t autoLearnHashTblPtrLow;
43517 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
43518 + volatile uint32_t autoLearnSetLockTblPtrLow;
43519 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
43520 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
43521 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
43522 + volatile uint32_t totalValidFragmentCounter;
43523 + volatile uint32_t totalProcessedFragCounter;
43524 + volatile uint32_t totalMalformdFragCounter;
43525 + volatile uint32_t totalSetBusyCounter;
43526 + volatile uint32_t totalDiscardedFragsCounter;
43527 + volatile uint32_t totalMoreThan16FramesCounter;
43528 + volatile uint32_t reserved2[2];
43529 +} _PackedType t_ReassTbl;
43530 +
43531 +typedef struct t_ReassCommonTbl {
43532 + volatile uint32_t timeoutModeAndFqid;
43533 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
43534 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
43535 + volatile uint32_t reassFrmDescPoolPtrLow;
43536 + volatile uint32_t timeOutTblPtr;
43537 + volatile uint32_t expirationDelay;
43538 + volatile uint32_t internalBufferManagement;
43539 + volatile uint32_t reserved2;
43540 + volatile uint32_t totalTimeOutCounter;
43541 + volatile uint32_t totalRfdPoolBusyCounter;
43542 + volatile uint32_t totalInternalBufferBusy;
43543 + volatile uint32_t totalExternalBufferBusy;
43544 + volatile uint32_t totalSgFragmentCounter;
43545 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
43546 + volatile uint32_t totalNCSPCounter;
43547 + volatile uint32_t discardMask;
43548 +} t_ReassCommonTbl;
43549 +
43550 +typedef _Packed struct t_Hmtd {
43551 + volatile uint16_t cfg;
43552 + volatile uint8_t eliodnOffset;
43553 + volatile uint8_t extHmcdBasePtrHi;
43554 + volatile uint32_t hmcdBasePtr;
43555 + volatile uint16_t nextAdIdx;
43556 + volatile uint8_t res1;
43557 + volatile uint8_t opCode;
43558 + volatile uint32_t res2;
43559 +} _PackedType t_Hmtd;
43560 +
43561 +#if defined(__MWERKS__) && !defined(__GNUC__)
43562 +#pragma pack(pop)
43563 +#endif /* defined(__MWERKS__) && ... */
43564 +
43565 +
43566 +/***********************************************************************/
43567 +/* Driver's internal structures */
43568 +/***********************************************************************/
43569 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43570 +typedef struct
43571 +{
43572 + t_Handle p_AutoLearnHashTbl;
43573 + t_Handle p_ReassmFrmDescrPoolTbl;
43574 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
43575 + t_Handle p_TimeOutTbl;
43576 + uint16_t maxNumFramesInProcess;
43577 + uint8_t numOfTasks;
43578 + //uint8_t poolId;
43579 + uint8_t prOffset;
43580 + uint16_t dataOffset;
43581 + uint8_t sgBpid;
43582 + uint8_t hwPortId;
43583 + uint32_t fqidForTimeOutFrames;
43584 + uint32_t timeoutRoutineRequestTime;
43585 + uint32_t bitFor1Micro;
43586 +} t_CapwapFragParams;
43587 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43588 +
43589 +typedef struct
43590 +{
43591 + t_AdOfTypeContLookup *p_Frag;
43592 +#if (DPAA_VERSION == 10)
43593 + uint8_t scratchBpid;
43594 +#endif /* (DPAA_VERSION == 10) */
43595 +} t_FragParams;
43596 +
43597 +typedef struct t_ReassmParams
43598 +{
43599 + e_NetHeaderType hdr; /* Header selection */
43600 + t_ReassCommonTbl *p_ReassCommonTbl;
43601 + uintptr_t reassFrmDescrIndxPoolTblAddr;
43602 + uintptr_t reassFrmDescrPoolTblAddr;
43603 + uintptr_t timeOutTblAddr;
43604 + uintptr_t internalBufferPoolManagementIndexAddr;
43605 + uintptr_t internalBufferPoolAddr;
43606 + uint32_t maxNumFramesInProcess;
43607 + uint8_t sgBpid;
43608 + uint8_t dataMemId;
43609 + uint16_t dataLiodnOffset;
43610 + uint32_t fqidForTimeOutFrames;
43611 + e_FmPcdManipReassemTimeOutMode timeOutMode;
43612 + uint32_t timeoutThresholdForReassmProcess;
43613 + union {
43614 + struct {
43615 + t_Handle h_Ipv4Ad;
43616 + t_Handle h_Ipv6Ad;
43617 + bool ipv6Assigned;
43618 + t_ReassTbl *p_Ipv4ReassTbl;
43619 + t_ReassTbl *p_Ipv6ReassTbl;
43620 + uintptr_t ipv4AutoLearnHashTblAddr;
43621 + uintptr_t ipv6AutoLearnHashTblAddr;
43622 + uintptr_t ipv4AutoLearnSetLockTblAddr;
43623 + uintptr_t ipv6AutoLearnSetLockTblAddr;
43624 + uint16_t minFragSize[2];
43625 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
43626 + uint8_t relativeSchemeId[2];
43627 + t_Handle h_Ipv4Scheme;
43628 + t_Handle h_Ipv6Scheme;
43629 + uint32_t nonConsistentSpFqid;
43630 + } ip;
43631 + struct {
43632 + t_Handle h_Ad;
43633 + t_ReassTbl *p_ReassTbl;
43634 + uintptr_t autoLearnHashTblAddr;
43635 + uintptr_t autoLearnSetLockTblAddr;
43636 + uint16_t maxRessembledsSize;
43637 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
43638 + uint8_t relativeSchemeId;
43639 + t_Handle h_Scheme;
43640 + } capwap;
43641 + };
43642 +} t_ReassmParams;
43643 +
43644 +typedef struct{
43645 + e_FmPcdManipType type;
43646 + t_FmPcdManipParams manipParams;
43647 + bool muramAllocate;
43648 + t_Handle h_Ad;
43649 + uint32_t opcode;
43650 + bool rmv;
43651 + bool insrt;
43652 + t_Handle h_NextManip;
43653 + t_Handle h_PrevManip;
43654 + e_FmPcdManipType nextManipType;
43655 + /* HdrManip parameters*/
43656 + uint8_t *p_Hmct;
43657 + uint8_t *p_Data;
43658 + bool dontParseAfterManip;
43659 + bool fieldUpdate;
43660 + bool custom;
43661 + uint16_t tableSize;
43662 + uint8_t dataSize;
43663 + bool cascaded;
43664 + e_ManipUnifiedPosition unifiedPosition;
43665 + /* end HdrManip */
43666 + uint8_t *p_Template;
43667 + uint16_t owner;
43668 + uint32_t updateParams;
43669 + uint32_t shadowUpdateParams;
43670 + bool frag;
43671 + bool reassm;
43672 + uint16_t sizeForFragmentation;
43673 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43674 + t_Handle h_Frag;
43675 + t_CapwapFragParams capwapFragParams;
43676 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43677 + union {
43678 + t_ReassmParams reassmParams;
43679 + t_FragParams fragParams;
43680 + };
43681 + uint8_t icOffset;
43682 + uint16_t ownerTmp;
43683 + bool cnia;
43684 + t_Handle p_StatsTbl;
43685 + t_Handle h_FmPcd;
43686 + t_List nodesLst;
43687 + t_Handle h_Spinlock;
43688 +} t_FmPcdManip;
43689 +
43690 +typedef struct t_FmPcdCcSavedManipParams
43691 +{
43692 + union
43693 + {
43694 + struct
43695 + {
43696 + uint16_t dataOffset;
43697 + //uint8_t poolId;
43698 + }capwapParams;
43699 + struct
43700 + {
43701 + uint16_t dataOffset;
43702 + uint8_t poolId;
43703 + }ipParams;
43704 + };
43705 +
43706 +} t_FmPcdCcSavedManipParams;
43707 +
43708 +
43709 +#endif /* __FM_MANIP_H */
43710 --- /dev/null
43711 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
43712 @@ -0,0 +1,2095 @@
43713 +/*
43714 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43715 + *
43716 + * Redistribution and use in source and binary forms, with or without
43717 + * modification, are permitted provided that the following conditions are met:
43718 + * * Redistributions of source code must retain the above copyright
43719 + * notice, this list of conditions and the following disclaimer.
43720 + * * Redistributions in binary form must reproduce the above copyright
43721 + * notice, this list of conditions and the following disclaimer in the
43722 + * documentation and/or other materials provided with the distribution.
43723 + * * Neither the name of Freescale Semiconductor nor the
43724 + * names of its contributors may be used to endorse or promote products
43725 + * derived from this software without specific prior written permission.
43726 + *
43727 + *
43728 + * ALTERNATIVELY, this software may be distributed under the terms of the
43729 + * GNU General Public License ("GPL") as published by the Free Software
43730 + * Foundation, either version 2 of that License or (at your option) any
43731 + * later version.
43732 + *
43733 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43734 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43735 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43736 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43737 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43738 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43739 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43740 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43741 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43742 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43743 + */
43744 +
43745 +
43746 +/******************************************************************************
43747 + @File fm_pcd.c
43748 +
43749 + @Description FM PCD ...
43750 +*//***************************************************************************/
43751 +#include "std_ext.h"
43752 +#include "error_ext.h"
43753 +#include "string_ext.h"
43754 +#include "xx_ext.h"
43755 +#include "sprint_ext.h"
43756 +#include "debug_ext.h"
43757 +#include "net_ext.h"
43758 +#include "fm_ext.h"
43759 +#include "fm_pcd_ext.h"
43760 +
43761 +#include "fm_common.h"
43762 +#include "fm_pcd.h"
43763 +#include "fm_pcd_ipc.h"
43764 +#include "fm_hc.h"
43765 +#include "fm_muram_ext.h"
43766 +
43767 +
43768 +/****************************************/
43769 +/* static functions */
43770 +/****************************************/
43771 +
43772 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
43773 +{
43774 + if (!p_FmPcd->h_Fm)
43775 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
43776 +
43777 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
43778 + {
43779 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
43780 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43781 +
43782 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
43783 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
43784 +
43785 + if (!p_FmPcd->f_Exception)
43786 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
43787 +
43788 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
43789 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
43790 +
43791 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
43792 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
43793 + }
43794 +
43795 + return E_OK;
43796 +}
43797 +
43798 +static volatile bool blockingFlag = FALSE;
43799 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
43800 + uint8_t *p_Msg,
43801 + uint8_t *p_Reply,
43802 + uint32_t replyLength,
43803 + t_Error status)
43804 +{
43805 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
43806 + blockingFlag = FALSE;
43807 +}
43808 +
43809 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
43810 + uint8_t *p_Msg,
43811 + uint32_t msgLength,
43812 + uint8_t *p_Reply,
43813 + uint32_t *p_ReplyLength)
43814 +{
43815 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
43816 + t_Error err = E_OK;
43817 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
43818 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
43819 +
43820 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43821 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
43822 +
43823 +#ifdef DISABLE_SANITY_CHECKS
43824 + UNUSED(msgLength);
43825 +#endif /* DISABLE_SANITY_CHECKS */
43826 +
43827 + ASSERT_COND(p_Msg);
43828 +
43829 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
43830 + *p_ReplyLength = 0;
43831 +
43832 + switch (p_IpcMsg->msgId)
43833 + {
43834 + case (FM_PCD_MASTER_IS_ALIVE):
43835 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
43836 + p_IpcReply->error = E_OK;
43837 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
43838 + break;
43839 + case (FM_PCD_MASTER_IS_ENABLED):
43840 + /* count partitions registrations */
43841 + if (p_FmPcd->enabled)
43842 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
43843 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
43844 + p_IpcReply->error = E_OK;
43845 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
43846 + break;
43847 + case (FM_PCD_GUEST_DISABLE):
43848 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
43849 + {
43850 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
43851 + p_IpcReply->error = E_OK;
43852 + }
43853 + else
43854 + {
43855 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
43856 + p_IpcReply->error = E_INVALID_STATE;
43857 + }
43858 + *p_ReplyLength = sizeof(uint32_t);
43859 + break;
43860 + case (FM_PCD_GET_COUNTER):
43861 + {
43862 + e_FmPcdCounters inCounter;
43863 + uint32_t outCounter;
43864 +
43865 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
43866 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
43867 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
43868 + p_IpcReply->error = E_OK;
43869 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
43870 + break;
43871 + }
43872 + case (FM_PCD_ALLOC_KG_SCHEMES):
43873 + {
43874 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
43875 +
43876 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
43877 + err = FmPcdKgAllocSchemes(h_FmPcd,
43878 + ipcSchemesParams.numOfSchemes,
43879 + ipcSchemesParams.guestId,
43880 + p_IpcReply->replyBody);
43881 + p_IpcReply->error = err;
43882 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
43883 + break;
43884 + }
43885 + case (FM_PCD_FREE_KG_SCHEMES):
43886 + {
43887 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
43888 +
43889 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
43890 + err = FmPcdKgFreeSchemes(h_FmPcd,
43891 + ipcSchemesParams.numOfSchemes,
43892 + ipcSchemesParams.guestId,
43893 + ipcSchemesParams.schemesIds);
43894 + p_IpcReply->error = err;
43895 + *p_ReplyLength = sizeof(uint32_t);
43896 + break;
43897 + }
43898 + case (FM_PCD_ALLOC_KG_CLSPLAN):
43899 + {
43900 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
43901 +
43902 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
43903 + err = KgAllocClsPlanEntries(h_FmPcd,
43904 + ipcKgClsPlanParams.numOfClsPlanEntries,
43905 + ipcKgClsPlanParams.guestId,
43906 + p_IpcReply->replyBody);
43907 + p_IpcReply->error = err;
43908 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
43909 + break;
43910 + }
43911 + case (FM_PCD_FREE_KG_CLSPLAN):
43912 + {
43913 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
43914 +
43915 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
43916 + KgFreeClsPlanEntries(h_FmPcd,
43917 + ipcKgClsPlanParams.numOfClsPlanEntries,
43918 + ipcKgClsPlanParams.guestId,
43919 + ipcKgClsPlanParams.clsPlanBase);
43920 + *p_ReplyLength = sizeof(uint32_t);
43921 + break;
43922 + }
43923 + case (FM_PCD_ALLOC_PROFILES):
43924 + {
43925 + t_FmIpcResourceAllocParams ipcAllocParams;
43926 + uint16_t base;
43927 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
43928 + base = PlcrAllocProfilesForPartition(h_FmPcd,
43929 + ipcAllocParams.base,
43930 + ipcAllocParams.num,
43931 + ipcAllocParams.guestId);
43932 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
43933 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
43934 + break;
43935 + }
43936 + case (FM_PCD_FREE_PROFILES):
43937 + {
43938 + t_FmIpcResourceAllocParams ipcAllocParams;
43939 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
43940 + PlcrFreeProfilesForPartition(h_FmPcd,
43941 + ipcAllocParams.base,
43942 + ipcAllocParams.num,
43943 + ipcAllocParams.guestId);
43944 + break;
43945 + }
43946 + case (FM_PCD_SET_PORT_PROFILES):
43947 + {
43948 + t_FmIpcResourceAllocParams ipcAllocParams;
43949 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
43950 + PlcrSetPortProfiles(h_FmPcd,
43951 + ipcAllocParams.guestId,
43952 + ipcAllocParams.num,
43953 + ipcAllocParams.base);
43954 + break;
43955 + }
43956 + case (FM_PCD_CLEAR_PORT_PROFILES):
43957 + {
43958 + t_FmIpcResourceAllocParams ipcAllocParams;
43959 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
43960 + PlcrClearPortProfiles(h_FmPcd,
43961 + ipcAllocParams.guestId);
43962 + break;
43963 + }
43964 + case (FM_PCD_GET_SW_PRS_OFFSET):
43965 + {
43966 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
43967 + uint32_t swPrsOffset;
43968 +
43969 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
43970 + swPrsOffset =
43971 + FmPcdGetSwPrsOffset(h_FmPcd,
43972 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
43973 + ipcSwPrsLable.indexPerHdr);
43974 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
43975 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
43976 + break;
43977 + }
43978 + case (FM_PCD_PRS_INC_PORT_STATS):
43979 + {
43980 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
43981 +
43982 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
43983 + PrsIncludePortInStatistics(h_FmPcd,
43984 + ipcPrsIncludePort.hardwarePortId,
43985 + ipcPrsIncludePort.include);
43986 + break;
43987 + }
43988 + default:
43989 + *p_ReplyLength = 0;
43990 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
43991 + }
43992 + return E_OK;
43993 +}
43994 +
43995 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
43996 +{
43997 + ASSERT_COND(h_NetEnv);
43998 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
43999 +}
44000 +
44001 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
44002 +{
44003 + ASSERT_COND(h_NetEnv);
44004 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
44005 +}
44006 +
44007 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44008 +{
44009 + uint32_t intFlags;
44010 +
44011 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44012 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
44013 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44014 +}
44015 +
44016 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
44017 +{
44018 + t_FmPcdLock *p_Lock = NULL;
44019 + uint32_t intFlags;
44020 +
44021 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44022 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
44023 + {
44024 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
44025 + LIST_DelAndInit(&p_Lock->node);
44026 + }
44027 + if (p_FmPcd->h_Spinlock)
44028 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44029 +
44030 + return p_Lock;
44031 +}
44032 +
44033 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44034 +{
44035 + uint32_t intFlags;
44036 +
44037 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44038 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
44039 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44040 +}
44041 +
44042 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
44043 +{
44044 + t_FmPcdLock *p_Lock;
44045 + int i;
44046 +
44047 + for (i=0; i<10; i++)
44048 + {
44049 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
44050 + if (!p_Lock)
44051 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
44052 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
44053 + INIT_LIST(&p_Lock->node);
44054 + p_Lock->h_Spinlock = XX_InitSpinlock();
44055 + if (!p_Lock->h_Spinlock)
44056 + {
44057 + XX_Free(p_Lock);
44058 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
44059 + }
44060 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
44061 + }
44062 +
44063 + return E_OK;
44064 +}
44065 +
44066 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
44067 +{
44068 + t_FmPcdLock *p_Lock;
44069 +
44070 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44071 + while (p_Lock)
44072 + {
44073 + XX_FreeSpinlock(p_Lock->h_Spinlock);
44074 + XX_Free(p_Lock);
44075 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44076 + }
44077 +}
44078 +
44079 +
44080 +
44081 +/*****************************************************************************/
44082 +/* Inter-module API routines */
44083 +/*****************************************************************************/
44084 +
44085 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
44086 +{
44087 + ASSERT_COND(p_FmPcd);
44088 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
44089 +}
44090 +
44091 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
44092 +{
44093 + uint8_t netEnvId = p_GrpParams->netEnvId;
44094 + int i, k, j;
44095 +
44096 + ASSERT_COND(p_FmPcd);
44097 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
44098 + {
44099 + p_GrpParams->grpExists = TRUE;
44100 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
44101 + return E_OK;
44102 + }
44103 +
44104 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44105 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44106 + {
44107 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44108 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44109 + {
44110 + /* if an option exists, add it to the opts list */
44111 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44112 + {
44113 + /* check if this option already exists, add if it doesn't */
44114 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
44115 + {
44116 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44117 + break;
44118 + }
44119 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
44120 + if (j == p_GrpParams->numOfOptions)
44121 + {
44122 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
44123 + p_GrpParams->numOfOptions++;
44124 + }
44125 + }
44126 + }
44127 + }
44128 +
44129 + if (p_GrpParams->numOfOptions == 0)
44130 + {
44131 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
44132 + {
44133 + p_GrpParams->grpExists = TRUE;
44134 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
44135 + }
44136 + }
44137 +
44138 + return E_OK;
44139 +
44140 +}
44141 +
44142 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
44143 +{
44144 + uint8_t j,k;
44145 +
44146 + *p_Vector = 0;
44147 +
44148 + ASSERT_COND(p_FmPcd);
44149 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44150 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
44151 + {
44152 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44153 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44154 + {
44155 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
44156 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
44157 + }
44158 + }
44159 +
44160 + if (!*p_Vector)
44161 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
44162 + else
44163 + return E_OK;
44164 +}
44165 +
44166 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
44167 +{
44168 + int i;
44169 +
44170 + ASSERT_COND(p_FmPcd);
44171 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
44172 +
44173 + p_Params->vector = 0;
44174 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
44175 + {
44176 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
44177 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
44178 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
44179 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
44180 + }
44181 +
44182 + return E_OK;
44183 +}
44184 +
44185 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
44186 +{
44187 + int i=0, k;
44188 +
44189 + ASSERT_COND(p_FmPcd);
44190 + /* check whether a given unit may be used by non-clsPlan users. */
44191 + /* first, recognize the unit by its vector */
44192 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
44193 + {
44194 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
44195 + {
44196 + for (k=0;
44197 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44198 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
44199 + k++)
44200 + /* check that no option exists */
44201 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44202 + return FALSE;
44203 + break;
44204 + }
44205 + i++;
44206 + }
44207 + /* assert that a unit was found to mach the vector */
44208 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
44209 +
44210 + return TRUE;
44211 +}
44212 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44213 +{
44214 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44215 + int i, k;
44216 +
44217 + ASSERT_COND(p_FmPcd);
44218 +
44219 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44220 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44221 + {
44222 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44223 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44224 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
44225 + return TRUE;
44226 + }
44227 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44228 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
44229 + {
44230 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44231 + return TRUE;
44232 + }
44233 +
44234 + return FALSE;
44235 +}
44236 +
44237 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
44238 +{
44239 + uint8_t i, k;
44240 +
44241 + ASSERT_COND(p_FmPcd);
44242 +
44243 + if (interchangeable)
44244 + {
44245 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44246 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44247 + {
44248 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44249 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
44250 + {
44251 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
44252 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
44253 +
44254 + return i;
44255 + }
44256 + }
44257 + }
44258 + else
44259 + {
44260 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44261 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44262 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
44263 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
44264 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
44265 + return i;
44266 +
44267 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44268 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44269 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
44270 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
44271 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44272 + }
44273 +
44274 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
44275 +}
44276 +
44277 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
44278 +{
44279 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44280 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
44281 + uint8_t result;
44282 + t_Error err = E_OK;
44283 +
44284 + ASSERT_COND(p_FmPcd);
44285 + ASSERT_COND(h_ReasmCommonPramTbl);
44286 +
44287 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
44288 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
44289 +
44290 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
44291 + RETURN_ERROR(MAJOR, err, NO_MSG);
44292 +
44293 + switch (result)
44294 + {
44295 + case (0):
44296 + return E_OK;
44297 + case (1):
44298 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44299 + case (2):
44300 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44301 + case (3):
44302 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
44303 + default:
44304 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
44305 + }
44306 +
44307 + return E_OK;
44308 +}
44309 +
44310 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44311 +{
44312 + int i;
44313 +
44314 + ASSERT_COND(p_FmPcd);
44315 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
44316 +
44317 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
44318 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44319 + {
44320 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44321 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44322 + }
44323 +
44324 + return HEADER_TYPE_NONE;
44325 +}
44326 +
44327 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
44328 +{
44329 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44330 + uint16_t swPortIndex = 0;
44331 +
44332 + ASSERT_COND(h_FmPcd);
44333 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
44334 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
44335 +}
44336 +
44337 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
44338 +{
44339 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44340 +
44341 + ASSERT_COND(h_FmPcd);
44342 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
44343 +}
44344 +
44345 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
44346 +{
44347 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44348 +
44349 + ASSERT_COND(h_FmPcd);
44350 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
44351 +}
44352 +
44353 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
44354 +{
44355 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
44356 +}
44357 +
44358 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44359 +{
44360 + uint32_t intFlags;
44361 +
44362 + ASSERT_COND(h_FmPcd);
44363 +
44364 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44365 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
44366 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44367 +}
44368 +
44369 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44370 +{
44371 + uint32_t intFlags;
44372 +
44373 + ASSERT_COND(h_FmPcd);
44374 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
44375 +
44376 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44377 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
44378 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44379 +}
44380 +
44381 +uint32_t FmPcdLock(t_Handle h_FmPcd)
44382 +{
44383 + ASSERT_COND(h_FmPcd);
44384 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
44385 +}
44386 +
44387 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
44388 +{
44389 + ASSERT_COND(h_FmPcd);
44390 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
44391 +}
44392 +
44393 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
44394 +{
44395 + t_FmPcdLock *p_Lock;
44396 + ASSERT_COND(h_FmPcd);
44397 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44398 + if (!p_Lock)
44399 + {
44400 + FillFreeLocksLst(h_FmPcd);
44401 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44402 + }
44403 +
44404 + if (p_Lock)
44405 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
44406 + return p_Lock;
44407 +}
44408 +
44409 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
44410 +{
44411 + uint32_t intFlags;
44412 + ASSERT_COND(h_FmPcd);
44413 + intFlags = FmPcdLock(h_FmPcd);
44414 + LIST_DelAndInit(&p_Lock->node);
44415 + FmPcdUnlock(h_FmPcd, intFlags);
44416 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
44417 +}
44418 +
44419 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
44420 +{
44421 + uint32_t intFlags;
44422 + t_List *p_Pos, *p_SavedPos=NULL;
44423 +
44424 + ASSERT_COND(h_FmPcd);
44425 + intFlags = FmPcdLock(h_FmPcd);
44426 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44427 + {
44428 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44429 + if (!FmPcdLockTryLock(p_Lock))
44430 + {
44431 + p_SavedPos = p_Pos;
44432 + break;
44433 + }
44434 + }
44435 + if (p_SavedPos)
44436 + {
44437 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44438 + {
44439 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44440 + if (p_Pos == p_SavedPos)
44441 + break;
44442 + FmPcdLockUnlock(p_Lock);
44443 + }
44444 + }
44445 + FmPcdUnlock(h_FmPcd, intFlags);
44446 +
44447 + CORE_MemoryBarrier();
44448 +
44449 + if (p_SavedPos)
44450 + return FALSE;
44451 +
44452 + return TRUE;
44453 +}
44454 +
44455 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
44456 +{
44457 + uint32_t intFlags;
44458 + t_List *p_Pos;
44459 +
44460 + ASSERT_COND(h_FmPcd);
44461 + intFlags = FmPcdLock(h_FmPcd);
44462 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44463 + {
44464 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44465 + p_Lock->flag = FALSE;
44466 + }
44467 + FmPcdUnlock(h_FmPcd, intFlags);
44468 +
44469 + CORE_MemoryBarrier();
44470 +}
44471 +
44472 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
44473 +{
44474 + ASSERT_COND(h_FmPcd);
44475 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
44476 +
44477 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
44478 +}
44479 +
44480 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
44481 +{
44482 + ASSERT_COND(h_FmPcd);
44483 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
44484 +}
44485 +
44486 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
44487 +{
44488 + ASSERT_COND(h_FmPcd);
44489 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
44490 +}
44491 +/*********************** End of inter-module routines ************************/
44492 +
44493 +
44494 +/****************************************/
44495 +/* API Init unit functions */
44496 +/****************************************/
44497 +
44498 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
44499 +{
44500 + t_FmPcd *p_FmPcd = NULL;
44501 + t_FmPhysAddr physicalMuramBase;
44502 + uint8_t i;
44503 +
44504 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
44505 +
44506 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
44507 + if (!p_FmPcd)
44508 + {
44509 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
44510 + return NULL;
44511 + }
44512 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
44513 +
44514 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
44515 + if (!p_FmPcd->p_FmPcdDriverParam)
44516 + {
44517 + XX_Free(p_FmPcd);
44518 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
44519 + return NULL;
44520 + }
44521 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
44522 +
44523 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
44524 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
44525 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
44526 + if (p_FmPcd->h_FmMuram)
44527 + {
44528 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
44529 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
44530 + }
44531 +
44532 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
44533 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
44534 +
44535 + if (p_FmPcdParams->useHostCommand)
44536 + {
44537 + t_FmHcParams hcParams;
44538 +
44539 + memset(&hcParams, 0, sizeof(hcParams));
44540 + hcParams.h_Fm = p_FmPcd->h_Fm;
44541 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
44542 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
44543 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
44544 + if (!p_FmPcd->h_Hc)
44545 + {
44546 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
44547 + FM_PCD_Free(p_FmPcd);
44548 + return NULL;
44549 + }
44550 + }
44551 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44552 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
44553 +
44554 + if (p_FmPcdParams->kgSupport)
44555 + {
44556 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
44557 + if (!p_FmPcd->p_FmPcdKg)
44558 + {
44559 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
44560 + FM_PCD_Free(p_FmPcd);
44561 + return NULL;
44562 + }
44563 + }
44564 +
44565 + if (p_FmPcdParams->plcrSupport)
44566 + {
44567 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
44568 + if (!p_FmPcd->p_FmPcdPlcr)
44569 + {
44570 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
44571 + FM_PCD_Free(p_FmPcd);
44572 + return NULL;
44573 + }
44574 + }
44575 +
44576 + if (p_FmPcdParams->prsSupport)
44577 + {
44578 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
44579 + if (!p_FmPcd->p_FmPcdPrs)
44580 + {
44581 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
44582 + FM_PCD_Free(p_FmPcd);
44583 + return NULL;
44584 + }
44585 + }
44586 +
44587 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
44588 + if (!p_FmPcd->h_Spinlock)
44589 + {
44590 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
44591 + FM_PCD_Free(p_FmPcd);
44592 + return NULL;
44593 + }
44594 + INIT_LIST(&p_FmPcd->freeLocksLst);
44595 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
44596 +
44597 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
44598 +
44599 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
44600 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
44601 + p_FmPcd->h_App = p_FmPcdParams->h_App;
44602 +
44603 + p_FmPcd->p_CcShadow = NULL;
44604 + p_FmPcd->ccShadowSize = 0;
44605 + p_FmPcd->ccShadowAlign = 0;
44606 +
44607 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
44608 + if (!p_FmPcd->h_ShadowSpinlock)
44609 + {
44610 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
44611 + FM_PCD_Free(p_FmPcd);
44612 + return NULL;
44613 + }
44614 +
44615 + return p_FmPcd;
44616 +}
44617 +
44618 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
44619 +{
44620 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44621 + t_Error err = E_OK;
44622 + t_FmPcdIpcMsg msg;
44623 +
44624 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44625 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
44626 +
44627 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
44628 +
44629 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44630 + {
44631 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44632 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
44633 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44634 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44635 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
44636 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44637 +
44638 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
44639 + if (p_FmPcd->h_IpcSession)
44640 + {
44641 + t_FmPcdIpcReply reply;
44642 + uint32_t replyLength;
44643 + uint8_t isMasterAlive = 0;
44644 +
44645 + memset(&msg, 0, sizeof(msg));
44646 + memset(&reply, 0, sizeof(reply));
44647 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
44648 + msg.msgBody[0] = p_FmPcd->guestId;
44649 + blockingFlag = TRUE;
44650 +
44651 + do
44652 + {
44653 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
44654 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44655 + (uint8_t*)&msg,
44656 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
44657 + (uint8_t*)&reply,
44658 + &replyLength,
44659 + IpcMsgCompletionCB,
44660 + h_FmPcd)) != E_OK)
44661 + REPORT_ERROR(MAJOR, err, NO_MSG);
44662 + while (blockingFlag) ;
44663 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
44664 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44665 + isMasterAlive = *(uint8_t*)(reply.replyBody);
44666 + } while (!isMasterAlive);
44667 + }
44668 + }
44669 +
44670 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
44671 +
44672 + if (p_FmPcd->p_FmPcdKg)
44673 + {
44674 + err = KgInit(p_FmPcd);
44675 + if (err)
44676 + RETURN_ERROR(MAJOR, err, NO_MSG);
44677 + }
44678 +
44679 + if (p_FmPcd->p_FmPcdPlcr)
44680 + {
44681 + err = PlcrInit(p_FmPcd);
44682 + if (err)
44683 + RETURN_ERROR(MAJOR, err, NO_MSG);
44684 + }
44685 +
44686 + if (p_FmPcd->p_FmPcdPrs)
44687 + {
44688 + err = PrsInit(p_FmPcd);
44689 + if (err)
44690 + RETURN_ERROR(MAJOR, err, NO_MSG);
44691 + }
44692 +
44693 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44694 + {
44695 + /* register to inter-core messaging mechanism */
44696 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44697 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
44698 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44699 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
44700 + if (err)
44701 + RETURN_ERROR(MAJOR, err, NO_MSG);
44702 + }
44703 +
44704 + /* IPv6 Frame-Id used for fragmentation */
44705 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
44706 + if (!p_FmPcd->ipv6FrameIdAddr)
44707 + {
44708 + FM_PCD_Free(p_FmPcd);
44709 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
44710 + }
44711 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
44712 +
44713 + /* CAPWAP Frame-Id used for fragmentation */
44714 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
44715 + if (!p_FmPcd->capwapFrameIdAddr)
44716 + {
44717 + FM_PCD_Free(p_FmPcd);
44718 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
44719 + }
44720 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
44721 +
44722 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44723 + p_FmPcd->p_FmPcdDriverParam = NULL;
44724 +
44725 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
44726 +
44727 + return E_OK;
44728 +}
44729 +
44730 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
44731 +{
44732 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
44733 + t_Error err = E_OK;
44734 +
44735 + if (p_FmPcd->ipv6FrameIdAddr)
44736 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
44737 +
44738 + if (p_FmPcd->capwapFrameIdAddr)
44739 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
44740 +
44741 + if (p_FmPcd->enabled)
44742 + FM_PCD_Disable(p_FmPcd);
44743 +
44744 + if (p_FmPcd->p_FmPcdDriverParam)
44745 + {
44746 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
44747 + p_FmPcd->p_FmPcdDriverParam = NULL;
44748 + }
44749 +
44750 + if (p_FmPcd->p_FmPcdKg)
44751 + {
44752 + if ((err = KgFree(p_FmPcd)) != E_OK)
44753 + RETURN_ERROR(MINOR, err, NO_MSG);
44754 + XX_Free(p_FmPcd->p_FmPcdKg);
44755 + p_FmPcd->p_FmPcdKg = NULL;
44756 + }
44757 +
44758 + if (p_FmPcd->p_FmPcdPlcr)
44759 + {
44760 + PlcrFree(p_FmPcd);
44761 + XX_Free(p_FmPcd->p_FmPcdPlcr);
44762 + p_FmPcd->p_FmPcdPlcr = NULL;
44763 + }
44764 +
44765 + if (p_FmPcd->p_FmPcdPrs)
44766 + {
44767 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44768 + PrsFree(p_FmPcd);
44769 + XX_Free(p_FmPcd->p_FmPcdPrs);
44770 + p_FmPcd->p_FmPcdPrs = NULL;
44771 + }
44772 +
44773 + if (p_FmPcd->h_Hc)
44774 + {
44775 + FmHcFree(p_FmPcd->h_Hc);
44776 + p_FmPcd->h_Hc = NULL;
44777 + }
44778 +
44779 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
44780 +
44781 + FmUnregisterPcd(p_FmPcd->h_Fm);
44782 +
44783 + ReleaseFreeLocksLst(p_FmPcd);
44784 +
44785 + if (p_FmPcd->h_Spinlock)
44786 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
44787 +
44788 + if (p_FmPcd->h_ShadowSpinlock)
44789 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
44790 +
44791 + XX_Free(p_FmPcd);
44792 +
44793 + return E_OK;
44794 +}
44795 +
44796 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
44797 +{
44798 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44799 + uint32_t bitMask = 0;
44800 +
44801 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44802 +
44803 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44804 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
44805 +
44806 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
44807 + if (bitMask)
44808 + {
44809 + if (enable)
44810 + p_FmPcd->exceptions |= bitMask;
44811 + else
44812 + p_FmPcd->exceptions &= ~bitMask;
44813 + }
44814 + else
44815 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
44816 +
44817 + return E_OK;
44818 +}
44819 +
44820 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
44821 +{
44822 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44823 +
44824 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44825 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
44826 +
44827 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
44828 +}
44829 +
44830 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
44831 +{
44832 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44833 + t_Error err = E_OK;
44834 +
44835 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
44836 +
44837 + if (p_FmPcd->enabled)
44838 + return E_OK;
44839 +
44840 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
44841 + p_FmPcd->h_IpcSession)
44842 + {
44843 + uint8_t enabled;
44844 + t_FmPcdIpcMsg msg;
44845 + t_FmPcdIpcReply reply;
44846 + uint32_t replyLength;
44847 +
44848 + memset(&reply, 0, sizeof(reply));
44849 + memset(&msg, 0, sizeof(msg));
44850 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
44851 + replyLength = sizeof(uint32_t) + sizeof(enabled);
44852 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44853 + (uint8_t*)&msg,
44854 + sizeof(msg.msgId),
44855 + (uint8_t*)&reply,
44856 + &replyLength,
44857 + NULL,
44858 + NULL)) != E_OK)
44859 + RETURN_ERROR(MAJOR, err, NO_MSG);
44860 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
44861 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44862 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
44863 + if (!p_FmPcd->enabled)
44864 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
44865 +
44866 + return E_OK;
44867 + }
44868 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44869 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
44870 + ("running in guest-mode without IPC!"));
44871 +
44872 + if (p_FmPcd->p_FmPcdKg)
44873 + KgEnable(p_FmPcd);
44874 +
44875 + if (p_FmPcd->p_FmPcdPlcr)
44876 + PlcrEnable(p_FmPcd);
44877 +
44878 + if (p_FmPcd->p_FmPcdPrs)
44879 + PrsEnable(p_FmPcd);
44880 +
44881 + p_FmPcd->enabled = TRUE;
44882 +
44883 + return E_OK;
44884 +}
44885 +
44886 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
44887 +{
44888 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44889 + t_Error err = E_OK;
44890 +
44891 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
44892 +
44893 + if (!p_FmPcd->enabled)
44894 + return E_OK;
44895 +
44896 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
44897 + p_FmPcd->h_IpcSession)
44898 + {
44899 + t_FmPcdIpcMsg msg;
44900 + t_FmPcdIpcReply reply;
44901 + uint32_t replyLength;
44902 +
44903 + memset(&reply, 0, sizeof(reply));
44904 + memset(&msg, 0, sizeof(msg));
44905 + msg.msgId = FM_PCD_GUEST_DISABLE;
44906 + replyLength = sizeof(uint32_t);
44907 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
44908 + (uint8_t*)&msg,
44909 + sizeof(msg.msgId),
44910 + (uint8_t*)&reply,
44911 + &replyLength,
44912 + NULL,
44913 + NULL)) != E_OK)
44914 + RETURN_ERROR(MAJOR, err, NO_MSG);
44915 + if (replyLength != sizeof(uint32_t))
44916 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
44917 + if (reply.error == E_OK)
44918 + p_FmPcd->enabled = FALSE;
44919 +
44920 + return (t_Error)(reply.error);
44921 + }
44922 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44923 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
44924 + ("running in guest-mode without IPC!"));
44925 +
44926 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
44927 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
44928 + ("Trying to disable a master partition PCD while"
44929 + "guest partitions are still enabled!"));
44930 +
44931 + if (p_FmPcd->p_FmPcdKg)
44932 + KgDisable(p_FmPcd);
44933 +
44934 + if (p_FmPcd->p_FmPcdPlcr)
44935 + PlcrDisable(p_FmPcd);
44936 +
44937 + if (p_FmPcd->p_FmPcdPrs)
44938 + PrsDisable(p_FmPcd);
44939 +
44940 + p_FmPcd->enabled = FALSE;
44941 +
44942 + return E_OK;
44943 +}
44944 +
44945 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
44946 +{
44947 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44948 + uint32_t intFlags, specialUnits = 0;
44949 + uint8_t bitId = 0;
44950 + uint8_t i, j, k;
44951 + uint8_t netEnvCurrId;
44952 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
44953 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
44954 + uint8_t hdrNum;
44955 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
44956 +
44957 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
44958 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
44959 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
44960 +
44961 + intFlags = FmPcdLock(p_FmPcd);
44962 +
44963 + /* find a new netEnv */
44964 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
44965 + if (!p_FmPcd->netEnvs[i].used)
44966 + break;
44967 +
44968 + if (i== FM_MAX_NUM_OF_PORTS)
44969 + {
44970 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
44971 + FmPcdUnlock(p_FmPcd, intFlags);
44972 + return NULL;
44973 + }
44974 +
44975 + p_FmPcd->netEnvs[i].used = TRUE;
44976 + FmPcdUnlock(p_FmPcd, intFlags);
44977 +
44978 + /* As anyone doesn't have handle of this netEnv yet, no need
44979 + to protect it with spinlocks */
44980 +
44981 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
44982 + if (!p_ModifiedNetEnvParams)
44983 + {
44984 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
44985 + return NULL;
44986 + }
44987 +
44988 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
44989 + p_NetEnvParams = p_ModifiedNetEnvParams;
44990 +
44991 + netEnvCurrId = (uint8_t)i;
44992 +
44993 + /* clear from previous use */
44994 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
44995 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
44996 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
44997 +
44998 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
44999 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
45000 +
45001 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45002 +
45003 + /* check that header with opt is not interchanged with the same header */
45004 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45005 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45006 + {
45007 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45008 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45009 + {
45010 + /* if an option exists, check that other headers are not the same header
45011 + without option */
45012 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
45013 + {
45014 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45015 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
45016 + {
45017 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
45018 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
45019 + {
45020 + REPORT_ERROR(MINOR, E_FULL,
45021 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
45022 + XX_Free(p_ModifiedNetEnvParams);
45023 + return NULL;
45024 + }
45025 + }
45026 + }
45027 + }
45028 + }
45029 +
45030 + /* Specific headers checking */
45031 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45032 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45033 + {
45034 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45035 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45036 + {
45037 + /* Some headers pairs may not be defined on different units as the parser
45038 + doesn't distinguish */
45039 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
45040 + /* check that header with opt is not interchanged with the same header */
45041 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
45042 + {
45043 + if (ipsecEspExists && (ipsecEspUnit != i))
45044 + {
45045 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45046 + XX_Free(p_ModifiedNetEnvParams);
45047 + return NULL;
45048 + }
45049 + else
45050 + {
45051 + ipsecAhUnit = i;
45052 + ipsecAhExists = TRUE;
45053 + }
45054 + }
45055 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
45056 + {
45057 + if (ipsecAhExists && (ipsecAhUnit != i))
45058 + {
45059 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45060 + XX_Free(p_ModifiedNetEnvParams);
45061 + return NULL;
45062 + }
45063 + else
45064 + {
45065 + ipsecEspUnit = i;
45066 + ipsecEspExists = TRUE;
45067 + }
45068 + }
45069 + /* ENCAP_ESP */
45070 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
45071 + {
45072 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
45073 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
45074 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45075 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45076 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45077 + }
45078 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
45079 + /* UDP_LITE */
45080 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
45081 + {
45082 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
45083 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
45084 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
45085 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45086 + }
45087 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
45088 +
45089 + /* IP FRAG */
45090 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
45091 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
45092 + {
45093 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
45094 + * IPv4 exists. If so we don't need to set an extra unit
45095 + * We consider as "having IPv4" any IPv4 without interchangable headers
45096 + * but including any options. */
45097 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
45098 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
45099 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45100 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45101 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45102 +
45103 + /* check if IPv4 header exists by itself */
45104 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45105 + {
45106 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
45107 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45108 + }
45109 + }
45110 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
45111 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
45112 + {
45113 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
45114 + * IPv4 exists. If so we don't need to set an extra unit
45115 + * We consider as "having IPv6" any IPv6 without interchangable headers
45116 + * but including any options. */
45117 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
45118 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
45119 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45120 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45121 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45122 +
45123 + /* check if IPv6 header exists by itself */
45124 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45125 + {
45126 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
45127 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45128 + }
45129 + }
45130 +#if (DPAA_VERSION >= 11)
45131 + /* CAPWAP FRAG */
45132 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
45133 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
45134 + {
45135 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
45136 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
45137 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45138 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45139 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45140 + }
45141 +#endif /* (DPAA_VERSION >= 11) */
45142 + }
45143 + }
45144 +
45145 + /* if private header (shim), check that no other headers specified */
45146 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45147 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45148 + {
45149 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45150 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
45151 + {
45152 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
45153 + XX_Free(p_ModifiedNetEnvParams);
45154 + return NULL;
45155 + }
45156 + }
45157 +
45158 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
45159 + {
45160 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45161 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
45162 + {
45163 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
45164 + if (shim1Selected)
45165 + {
45166 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
45167 + XX_Free(p_ModifiedNetEnvParams);
45168 + return NULL;
45169 + }
45170 + shim1Selected = TRUE;
45171 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
45172 + break;
45173 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
45174 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
45175 + break;
45176 + default:
45177 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
45178 + }
45179 + else
45180 + {
45181 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
45182 +
45183 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45184 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45185 + }
45186 + }
45187 +
45188 + /* define a set of hardware parser LCV's according to the defined netenv */
45189 +
45190 + /* set an array of LCV's for each header in the netEnv */
45191 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45192 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45193 + {
45194 + /* private headers have no LCV in the hard parser */
45195 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45196 + {
45197 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45198 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45199 + {
45200 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
45201 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
45202 + {
45203 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
45204 + XX_Free(p_ModifiedNetEnvParams);
45205 + return NULL;
45206 + }
45207 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45208 + }
45209 + }
45210 + }
45211 + XX_Free(p_ModifiedNetEnvParams);
45212 +
45213 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
45214 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
45215 + {
45216 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
45217 + return NULL;
45218 + }
45219 + return &p_FmPcd->netEnvs[netEnvCurrId];
45220 +}
45221 +
45222 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
45223 +{
45224 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
45225 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
45226 + uint32_t intFlags;
45227 + uint8_t netEnvId = p_NetEnv->netEnvId;
45228 +
45229 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
45230 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45231 +
45232 + /* check that no port is bound to this netEnv */
45233 + if (p_FmPcd->netEnvs[netEnvId].owners)
45234 + {
45235 + RETURN_ERROR(MINOR, E_INVALID_STATE,
45236 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
45237 + }
45238 +
45239 + intFlags = FmPcdLock(p_FmPcd);
45240 +
45241 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
45242 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45243 +
45244 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45245 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45246 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
45247 +
45248 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
45249 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
45250 +
45251 + FmPcdUnlock(p_FmPcd, intFlags);
45252 + return E_OK;
45253 +}
45254 +
45255 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
45256 +{
45257 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45258 +
45259 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
45260 +
45261 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
45262 +}
45263 +
45264 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
45265 +{
45266 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45267 + t_FmCtrlCodeRevisionInfo revInfo;
45268 + t_Error err;
45269 +
45270 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45271 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45272 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
45273 +
45274 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
45275 + {
45276 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
45277 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
45278 + }
45279 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
45280 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
45281 +
45282 + if (!p_FmPcd->h_Hc)
45283 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
45284 +
45285 + p_FmPcd->advancedOffloadSupport = TRUE;
45286 +
45287 + return E_OK;
45288 +}
45289 +
45290 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
45291 +{
45292 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45293 + uint32_t outCounter = 0;
45294 + t_Error err;
45295 +
45296 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
45297 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
45298 +
45299 + switch (counter)
45300 + {
45301 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45302 + if (!p_FmPcd->p_FmPcdKg)
45303 + {
45304 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
45305 + return 0;
45306 + }
45307 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45308 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
45309 + !p_FmPcd->h_IpcSession)
45310 + {
45311 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45312 + ("running in guest-mode without neither IPC nor mapped register!"));
45313 + return 0;
45314 + }
45315 + break;
45316 +
45317 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45318 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45319 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45320 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45321 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45322 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45323 + if (!p_FmPcd->p_FmPcdPlcr)
45324 + {
45325 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
45326 + return 0;
45327 + }
45328 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45329 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45330 + !p_FmPcd->h_IpcSession)
45331 + {
45332 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45333 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
45334 + return 0;
45335 + }
45336 +
45337 + /* check that counters are enabled */
45338 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45339 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45340 + {
45341 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45342 + return 0;
45343 + }
45344 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
45345 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
45346 + break;
45347 +
45348 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45349 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45350 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45351 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45352 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45353 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45354 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45355 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45356 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45357 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45358 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45359 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45360 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45361 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45362 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45363 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45364 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45365 + if (!p_FmPcd->p_FmPcdPrs)
45366 + {
45367 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
45368 + return 0;
45369 + }
45370 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45371 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
45372 + !p_FmPcd->h_IpcSession)
45373 + {
45374 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45375 + ("running in guest-mode without neither IPC nor mapped register!"));
45376 + return 0;
45377 + }
45378 + break;
45379 + default:
45380 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
45381 + return 0;
45382 + }
45383 +
45384 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45385 + p_FmPcd->h_IpcSession)
45386 + {
45387 + t_FmPcdIpcMsg msg;
45388 + t_FmPcdIpcReply reply;
45389 + uint32_t replyLength;
45390 +
45391 + memset(&msg, 0, sizeof(msg));
45392 + memset(&reply, 0, sizeof(reply));
45393 + msg.msgId = FM_PCD_GET_COUNTER;
45394 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
45395 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
45396 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45397 + (uint8_t*)&msg,
45398 + sizeof(msg.msgId) +sizeof(uint32_t),
45399 + (uint8_t*)&reply,
45400 + &replyLength,
45401 + NULL,
45402 + NULL)) != E_OK)
45403 + RETURN_ERROR(MAJOR, err, NO_MSG);
45404 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
45405 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45406 +
45407 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
45408 + return outCounter;
45409 + }
45410 +
45411 + switch (counter)
45412 + {
45413 + /* Parser statistics */
45414 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45415 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
45416 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45417 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
45418 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45419 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
45420 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45421 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
45422 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45423 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
45424 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45425 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
45426 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45427 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
45428 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45429 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
45430 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45431 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
45432 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45433 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
45434 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45435 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
45436 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45437 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
45438 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45439 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
45440 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45441 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
45442 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45443 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
45444 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45445 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
45446 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45447 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
45448 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45449 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
45450 +
45451 + /* Policer statistics */
45452 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45453 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
45454 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45455 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
45456 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45457 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
45458 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45459 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
45460 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45461 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
45462 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45463 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
45464 + }
45465 + return 0;
45466 +}
45467 +
45468 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45469 +{
45470 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45471 + uint32_t bitMask = 0, tmpReg;
45472 +
45473 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45474 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45475 +
45476 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45477 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
45478 +
45479 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45480 +
45481 + if (bitMask)
45482 + {
45483 + if (enable)
45484 + p_FmPcd->exceptions |= bitMask;
45485 + else
45486 + p_FmPcd->exceptions &= ~bitMask;
45487 +
45488 + switch (exception)
45489 + {
45490 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45491 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45492 + if (!p_FmPcd->p_FmPcdKg)
45493 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45494 + break;
45495 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45496 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45497 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45498 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45499 + if (!p_FmPcd->p_FmPcdPlcr)
45500 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45501 + break;
45502 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45503 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45504 + if (!p_FmPcd->p_FmPcdPrs)
45505 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
45506 + break;
45507 + }
45508 +
45509 + switch (exception)
45510 + {
45511 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45512 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45513 + if (enable)
45514 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
45515 + else
45516 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
45517 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45518 + break;
45519 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45520 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45521 + if (enable)
45522 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
45523 + else
45524 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
45525 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45526 + break;
45527 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45528 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
45529 + if (enable)
45530 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
45531 + else
45532 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
45533 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
45534 + break;
45535 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45536 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
45537 + if (enable)
45538 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
45539 + else
45540 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
45541 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
45542 + break;
45543 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45544 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45545 + if (enable)
45546 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
45547 + else
45548 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
45549 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45550 + break;
45551 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45552 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45553 + if (enable)
45554 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
45555 + else
45556 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
45557 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45558 + break;
45559 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45560 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45561 + if (enable)
45562 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45563 + else
45564 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45565 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45566 + break;
45567 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45568 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45569 + if (enable)
45570 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45571 + else
45572 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45573 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45574 + break;
45575 + }
45576 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
45577 + Driver may disable them automatically, depending on driver's status */
45578 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45579 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45580 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45581 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45582 + FmEnableRamsEcc(p_FmPcd->h_Fm);
45583 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45584 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45585 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45586 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45587 + FmDisableRamsEcc(p_FmPcd->h_Fm);
45588 + }
45589 +
45590 + return E_OK;
45591 +}
45592 +
45593 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
45594 +{
45595 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45596 +
45597 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45598 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45599 +
45600 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45601 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
45602 +
45603 + switch (exception)
45604 + {
45605 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45606 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45607 + if (!p_FmPcd->p_FmPcdKg)
45608 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45609 + break;
45610 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45611 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45612 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45613 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45614 + if (!p_FmPcd->p_FmPcdPlcr)
45615 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45616 + break;
45617 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45618 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45619 + if (!p_FmPcd->p_FmPcdPrs)
45620 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
45621 + break;
45622 + default:
45623 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
45624 + }
45625 + switch (exception)
45626 + {
45627 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
45628 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
45629 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45630 + break;
45631 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
45632 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
45633 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45634 + break;
45635 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
45636 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
45637 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45638 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
45639 + break;
45640 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
45641 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
45642 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45643 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
45644 + break;
45645 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
45646 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
45647 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45648 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
45649 + break;
45650 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
45651 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
45652 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45653 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
45654 + break;
45655 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
45656 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
45657 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45658 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
45659 + break;
45660 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
45661 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
45662 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45663 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
45664 + break;
45665 + }
45666 +
45667 + return E_OK;
45668 +}
45669 +
45670 +
45671 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
45672 +{
45673 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45674 +
45675 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45676 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45677 +
45678 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45679 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
45680 +
45681 + switch (counter)
45682 + {
45683 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45684 + if (!p_FmPcd->p_FmPcdKg)
45685 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
45686 + break;
45687 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45688 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45689 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45690 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45691 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45692 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45693 + if (!p_FmPcd->p_FmPcdPlcr)
45694 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
45695 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45696 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45697 + break;
45698 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45699 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45700 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45701 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45702 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45703 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45704 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45705 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45706 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45707 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45708 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45709 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45710 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45711 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45712 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45713 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45714 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45715 + if (!p_FmPcd->p_FmPcdPrs)
45716 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45717 + break;
45718 + default:
45719 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
45720 + }
45721 + switch (counter)
45722 + {
45723 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45724 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
45725 + break;
45726 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45727 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
45728 + break;
45729 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45730 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
45731 + break;
45732 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45733 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
45734 + break;
45735 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45736 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
45737 + break;
45738 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45739 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
45740 + break;
45741 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45742 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
45743 + break;
45744 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45745 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
45746 + break;
45747 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45748 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
45749 + break;
45750 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45751 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
45752 + break;
45753 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45754 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
45755 + break;
45756 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45757 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
45758 + break;
45759 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45760 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
45761 + break;
45762 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45763 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
45764 + break;
45765 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45766 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
45767 + break;
45768 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45769 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
45770 + break;
45771 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45772 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
45773 + break;
45774 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45775 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
45776 + break;
45777 +
45778 + /*Policer counters*/
45779 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45780 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
45781 + break;
45782 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45783 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
45784 + break;
45785 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45786 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
45787 + break;
45788 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45789 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
45790 + break;
45791 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45792 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
45793 + break;
45794 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45795 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
45796 + break;
45797 + }
45798 +
45799 + return E_OK;
45800 +}
45801 +
45802 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
45803 +{
45804 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45805 + return FmHcGetPort(p_FmPcd->h_Hc);
45806 +}
45807 +
45808 --- /dev/null
45809 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
45810 @@ -0,0 +1,543 @@
45811 +/*
45812 + * Copyright 2008-2012 Freescale Semiconductor Inc.
45813 + *
45814 + * Redistribution and use in source and binary forms, with or without
45815 + * modification, are permitted provided that the following conditions are met:
45816 + * * Redistributions of source code must retain the above copyright
45817 + * notice, this list of conditions and the following disclaimer.
45818 + * * Redistributions in binary form must reproduce the above copyright
45819 + * notice, this list of conditions and the following disclaimer in the
45820 + * documentation and/or other materials provided with the distribution.
45821 + * * Neither the name of Freescale Semiconductor nor the
45822 + * names of its contributors may be used to endorse or promote products
45823 + * derived from this software without specific prior written permission.
45824 + *
45825 + *
45826 + * ALTERNATIVELY, this software may be distributed under the terms of the
45827 + * GNU General Public License ("GPL") as published by the Free Software
45828 + * Foundation, either version 2 of that License or (at your option) any
45829 + * later version.
45830 + *
45831 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
45832 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45833 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45834 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
45835 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45836 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45837 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45838 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45839 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45840 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45841 + */
45842 +
45843 +
45844 +/******************************************************************************
45845 + @File fm_pcd.h
45846 +
45847 + @Description FM PCD ...
45848 +*//***************************************************************************/
45849 +#ifndef __FM_PCD_H
45850 +#define __FM_PCD_H
45851 +
45852 +#include "std_ext.h"
45853 +#include "error_ext.h"
45854 +#include "list_ext.h"
45855 +#include "fm_pcd_ext.h"
45856 +#include "fm_common.h"
45857 +#include "fsl_fman_prs.h"
45858 +#include "fsl_fman_kg.h"
45859 +
45860 +#define __ERR_MODULE__ MODULE_FM_PCD
45861 +
45862 +
45863 +/****************************/
45864 +/* Defaults */
45865 +/****************************/
45866 +#define DEFAULT_plcrAutoRefresh FALSE
45867 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
45868 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
45869 +#define DEFAULT_fmPcdPlcrExceptions 0
45870 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
45871 +
45872 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
45873 +#define DEFAULT_numOfUsedProfilesPerWindow 16
45874 +#define DEFAULT_numOfSharedPlcrProfiles 4
45875 +
45876 +/****************************/
45877 +/* Network defines */
45878 +/****************************/
45879 +#define UDP_HEADER_SIZE 8
45880 +
45881 +#define ESP_SPI_OFFSET 0
45882 +#define ESP_SPI_SIZE 4
45883 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
45884 +#define ESP_SEQ_NUM_SIZE 4
45885 +
45886 +/****************************/
45887 +/* General defines */
45888 +/****************************/
45889 +#define ILLEGAL_CLS_PLAN 0xff
45890 +#define ILLEGAL_NETENV 0xff
45891 +
45892 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
45893 +
45894 +/****************************/
45895 +/* Error defines */
45896 +/****************************/
45897 +
45898 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
45899 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
45900 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
45901 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
45902 +
45903 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
45904 +switch (exception){ \
45905 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
45906 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
45907 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
45908 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
45909 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
45910 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
45911 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
45912 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
45913 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
45914 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
45915 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
45916 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
45917 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
45918 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
45919 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
45920 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
45921 + default: bitMask = 0;break;}
45922 +
45923 +/***********************************************************************/
45924 +/* Policer defines */
45925 +/***********************************************************************/
45926 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
45927 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
45928 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
45929 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
45930 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
45931 +
45932 +/***********************************************************************/
45933 +/* Memory map */
45934 +/***********************************************************************/
45935 +#if defined(__MWERKS__) && !defined(__GNUC__)
45936 +#pragma pack(push,1)
45937 +#endif /* defined(__MWERKS__) && ... */
45938 +
45939 +
45940 +typedef struct {
45941 +/* General Configuration and Status Registers */
45942 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
45943 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
45944 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
45945 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
45946 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
45947 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
45948 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
45949 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
45950 +/* Global Statistic Counters */
45951 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
45952 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
45953 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
45954 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
45955 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
45956 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
45957 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
45958 +/* Profile RAM Access Registers */
45959 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
45960 + t_FmPcdPlcrProfileRegs profileRegs;
45961 +/* Error Capture Registers */
45962 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
45963 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
45964 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
45965 +/* Debug Registers */
45966 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
45967 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
45968 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
45969 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
45970 + (for port-ID 1-11, only for supported Port-ID registers) */
45971 +} t_FmPcdPlcrRegs;
45972 +
45973 +#if defined(__MWERKS__) && !defined(__GNUC__)
45974 +#pragma pack(pop)
45975 +#endif /* defined(__MWERKS__) && ... */
45976 +
45977 +
45978 +/***********************************************************************/
45979 +/* Driver's internal structures */
45980 +/***********************************************************************/
45981 +
45982 +typedef struct {
45983 + bool known;
45984 + uint8_t id;
45985 +} t_FmPcdKgSchemesExtractsEntry;
45986 +
45987 +typedef struct {
45988 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
45989 +} t_FmPcdKgSchemesExtracts;
45990 +
45991 +typedef struct {
45992 + t_Handle h_Manip;
45993 + bool keepRes;
45994 + e_FmPcdEngine nextEngine;
45995 + uint8_t parseCode;
45996 +} t_FmPcdInfoForManip;
45997 +
45998 +/**************************************************************************//**
45999 + @Description A structure of parameters to communicate
46000 + between the port and PCD regarding the KG scheme.
46001 +*//***************************************************************************/
46002 +typedef struct {
46003 + uint8_t netEnvId; /* in */
46004 + uint8_t numOfDistinctionUnits; /* in */
46005 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
46006 + uint32_t vector; /* out */
46007 +} t_NetEnvParams;
46008 +
46009 +typedef struct {
46010 + bool allocated;
46011 + uint8_t ownerId; /* guestId for KG in multi-partition only.
46012 + portId for PLCR in any environment */
46013 +} t_FmPcdAllocMng;
46014 +
46015 +typedef struct {
46016 + volatile bool lock;
46017 + bool used;
46018 + uint8_t owners;
46019 + uint8_t netEnvId;
46020 + uint8_t guestId;
46021 + uint8_t baseEntry;
46022 + uint16_t sizeOfGrp;
46023 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
46024 +} t_FmPcdKgClsPlanGrp;
46025 +
46026 +typedef struct {
46027 + t_Handle h_FmPcd;
46028 + uint8_t schemeId;
46029 + t_FmPcdLock *p_Lock;
46030 + bool valid;
46031 + uint8_t netEnvId;
46032 + uint8_t owners;
46033 + uint32_t matchVector;
46034 + uint32_t ccUnits;
46035 + bool nextRelativePlcrProfile;
46036 + uint16_t relativeProfileId;
46037 + uint16_t numOfProfiles;
46038 + t_FmPcdKgKeyOrder orderedArray;
46039 + e_FmPcdEngine nextEngine;
46040 + e_FmPcdDoneAction doneAction;
46041 + bool requiredActionFlag;
46042 + uint32_t requiredAction;
46043 + bool extractedOrs;
46044 + uint8_t bitOffsetInPlcrProfile;
46045 + bool directPlcr;
46046 +#if (DPAA_VERSION >= 11)
46047 + bool vspe;
46048 +#endif
46049 +} t_FmPcdKgScheme;
46050 +
46051 +typedef union {
46052 + struct fman_kg_scheme_regs schemeRegs;
46053 + struct fman_kg_pe_regs portRegs;
46054 + struct fman_kg_cp_regs clsPlanRegs;
46055 +} u_FmPcdKgIndirectAccessRegs;
46056 +
46057 +typedef struct {
46058 + struct fman_kg_regs *p_FmPcdKgRegs;
46059 + uint32_t schemeExceptionsBitMask;
46060 + uint8_t numOfSchemes;
46061 + t_Handle h_HwSpinlock;
46062 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46063 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
46064 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
46065 + uint8_t emptyClsPlanGrpId;
46066 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
46067 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
46068 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
46069 +} t_FmPcdKg;
46070 +
46071 +typedef struct {
46072 + uint16_t profilesBase;
46073 + uint16_t numOfProfiles;
46074 + t_Handle h_FmPort;
46075 +} t_FmPcdPlcrMapParam;
46076 +
46077 +typedef struct {
46078 + uint16_t absoluteProfileId;
46079 + t_Handle h_FmPcd;
46080 + bool valid;
46081 + t_FmPcdLock *p_Lock;
46082 + t_FmPcdAllocMng profilesMng;
46083 + bool requiredActionFlag;
46084 + uint32_t requiredAction;
46085 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
46086 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
46087 +
46088 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
46089 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
46090 +
46091 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
46092 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
46093 +} t_FmPcdPlcrProfile;
46094 +
46095 +typedef struct {
46096 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
46097 + uint16_t partPlcrProfilesBase;
46098 + uint16_t partNumOfPlcrProfiles;
46099 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
46100 + uint16_t numOfSharedProfiles;
46101 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
46102 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
46103 + t_Handle h_HwSpinlock;
46104 + t_Handle h_SwSpinlock;
46105 +} t_FmPcdPlcr;
46106 +
46107 +typedef struct {
46108 + uint32_t *p_SwPrsCode;
46109 + uint32_t *p_CurrSwPrs;
46110 + uint8_t currLabel;
46111 + struct fman_prs_regs *p_FmPcdPrsRegs;
46112 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
46113 + uint32_t fmPcdPrsPortIdStatistics;
46114 +} t_FmPcdPrs;
46115 +
46116 +typedef struct {
46117 + struct {
46118 + e_NetHeaderType hdr;
46119 + protocolOpt_t opt; /* only one option !! */
46120 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
46121 +} t_FmPcdIntDistinctionUnit;
46122 +
46123 +typedef struct {
46124 + e_NetHeaderType hdr;
46125 + protocolOpt_t opt; /* only one option !! */
46126 + e_NetHeaderType aliasHdr;
46127 +} t_FmPcdNetEnvAliases;
46128 +
46129 +typedef struct {
46130 + uint8_t netEnvId;
46131 + t_Handle h_FmPcd;
46132 + t_Handle h_Spinlock;
46133 + bool used;
46134 + uint8_t owners;
46135 + uint8_t clsPlanGrpId;
46136 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46137 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46138 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
46139 + uint32_t macsecVector;
46140 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
46141 +} t_FmPcdNetEnv;
46142 +
46143 +typedef struct {
46144 + struct fman_prs_cfg dfltCfg;
46145 + bool plcrAutoRefresh;
46146 + uint16_t prsMaxParseCycleLimit;
46147 +} t_FmPcdDriverParam;
46148 +
46149 +typedef struct {
46150 + t_Handle h_Fm;
46151 + t_Handle h_FmMuram;
46152 + t_FmRevisionInfo fmRevInfo;
46153 +
46154 + uint64_t physicalMuramBase;
46155 +
46156 + t_Handle h_Spinlock;
46157 + t_List freeLocksLst;
46158 + t_List acquiredLocksLst;
46159 +
46160 + t_Handle h_IpcSession; /* relevant for guest only */
46161 + bool enabled;
46162 + uint8_t guestId; /**< Guest Partition Id */
46163 + uint8_t numOfEnabledGuestPartitionsPcds;
46164 + char fmPcdModuleName[MODULE_NAME_SIZE];
46165 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
46166 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
46167 + t_FmPcdKg *p_FmPcdKg;
46168 + t_FmPcdPlcr *p_FmPcdPlcr;
46169 + t_FmPcdPrs *p_FmPcdPrs;
46170 +
46171 + void *p_CcShadow; /**< CC MURAM shadow */
46172 + uint32_t ccShadowSize;
46173 + uint32_t ccShadowAlign;
46174 + volatile bool shadowLock;
46175 + t_Handle h_ShadowSpinlock;
46176 +
46177 + t_Handle h_Hc;
46178 +
46179 + uint32_t exceptions;
46180 + t_FmPcdExceptionCallback *f_Exception;
46181 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
46182 + t_Handle h_App;
46183 + uintptr_t ipv6FrameIdAddr;
46184 + uintptr_t capwapFrameIdAddr;
46185 + bool advancedOffloadSupport;
46186 +
46187 + t_FmPcdDriverParam *p_FmPcdDriverParam;
46188 +} t_FmPcd;
46189 +
46190 +#if (DPAA_VERSION >= 11)
46191 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
46192 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
46193 +#define FRM_REPLIC_UPDATE_INFO 0x02
46194 +#endif /* (DPAA_VERSION >= 11) */
46195 +/***********************************************************************/
46196 +/* PCD internal routines */
46197 +/***********************************************************************/
46198 +
46199 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
46200 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
46201 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
46202 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
46203 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
46204 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46205 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46206 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
46207 +
46208 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
46209 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
46210 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
46211 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
46212 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
46213 +
46214 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46215 +t_Error KgInit(t_FmPcd *p_FmPcd);
46216 +t_Error KgFree(t_FmPcd *p_FmPcd);
46217 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
46218 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
46219 +void KgEnable(t_FmPcd *p_FmPcd);
46220 +void KgDisable(t_FmPcd *p_FmPcd);
46221 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
46222 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
46223 +
46224 +/* only for MULTI partittion */
46225 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46226 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46227 +/* only for SINGLE partittion */
46228 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
46229 +
46230 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
46231 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
46232 +
46233 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46234 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
46235 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
46236 +void PlcrEnable(t_FmPcd *p_FmPcd);
46237 +void PlcrDisable(t_FmPcd *p_FmPcd);
46238 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46239 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46240 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
46241 + uint8_t hardwarePortId,
46242 + uint16_t numOfProfiles,
46243 + uint16_t base);
46244 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
46245 +
46246 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
46247 +t_Error PrsInit(t_FmPcd *p_FmPcd);
46248 +void PrsEnable(t_FmPcd *p_FmPcd);
46249 +void PrsDisable(t_FmPcd *p_FmPcd);
46250 +void PrsFree(t_FmPcd *p_FmPcd );
46251 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
46252 +
46253 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
46254 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
46255 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
46256 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
46257 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
46258 +
46259 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46260 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
46261 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
46262 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
46263 + t_Handle p_Ad,
46264 + t_Handle *p_AdNewPtr);
46265 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
46266 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46267 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
46268 +#ifdef FM_CAPWAP_SUPPORT
46269 +t_Handle FmPcdManipApplSpecificBuild(void);
46270 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
46271 +#endif /* FM_CAPWAP_SUPPORT */
46272 +#if (DPAA_VERSION >= 11)
46273 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
46274 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
46275 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
46276 +
46277 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
46278 + t_Handle h_ReplicGroup,
46279 + t_List *p_AdTables,
46280 + uint32_t *p_NumOfAdTables);
46281 +#endif /* (DPAA_VERSION >= 11) */
46282 +
46283 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
46284 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46285 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46286 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
46287 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
46288 +
46289 +typedef struct
46290 +{
46291 + t_Handle h_StatsAd;
46292 + t_Handle h_StatsCounters;
46293 +#if (DPAA_VERSION >= 11)
46294 + t_Handle h_StatsFLRs;
46295 +#endif /* (DPAA_VERSION >= 11) */
46296 +} t_FmPcdCcStatsParams;
46297 +
46298 +void NextStepAd(t_Handle h_Ad,
46299 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
46300 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
46301 + t_FmPcd *p_FmPcd);
46302 +void ReleaseLst(t_List *p_List);
46303 +
46304 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
46305 +{
46306 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46307 + ASSERT_COND(p_FmPcd);
46308 + return p_FmPcd->h_FmMuram;
46309 +}
46310 +
46311 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
46312 +{
46313 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46314 + ASSERT_COND(p_FmPcd);
46315 + return p_FmPcd->physicalMuramBase;
46316 +}
46317 +
46318 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
46319 +{
46320 + ASSERT_COND(p_Lock);
46321 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46322 +}
46323 +
46324 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
46325 +{
46326 + ASSERT_COND(p_Lock);
46327 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
46328 +}
46329 +
46330 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
46331 +{
46332 + uint32_t intFlags;
46333 +
46334 + ASSERT_COND(p_Lock);
46335 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46336 + if (p_Lock->flag)
46337 + {
46338 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46339 + return FALSE;
46340 + }
46341 + p_Lock->flag = TRUE;
46342 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46343 + return TRUE;
46344 +}
46345 +
46346 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
46347 +{
46348 + ASSERT_COND(p_Lock);
46349 + p_Lock->flag = FALSE;
46350 +}
46351 +
46352 +
46353 +#endif /* __FM_PCD_H */
46354 --- /dev/null
46355 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46356 @@ -0,0 +1,280 @@
46357 +/*
46358 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46359 + *
46360 + * Redistribution and use in source and binary forms, with or without
46361 + * modification, are permitted provided that the following conditions are met:
46362 + * * Redistributions of source code must retain the above copyright
46363 + * notice, this list of conditions and the following disclaimer.
46364 + * * Redistributions in binary form must reproduce the above copyright
46365 + * notice, this list of conditions and the following disclaimer in the
46366 + * documentation and/or other materials provided with the distribution.
46367 + * * Neither the name of Freescale Semiconductor nor the
46368 + * names of its contributors may be used to endorse or promote products
46369 + * derived from this software without specific prior written permission.
46370 + *
46371 + *
46372 + * ALTERNATIVELY, this software may be distributed under the terms of the
46373 + * GNU General Public License ("GPL") as published by the Free Software
46374 + * Foundation, either version 2 of that License or (at your option) any
46375 + * later version.
46376 + *
46377 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46378 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46379 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46380 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46381 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46382 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46383 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46384 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46385 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46386 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46387 + */
46388 +
46389 +
46390 +/**************************************************************************//**
46391 + @File fm_pcd_ipc.h
46392 +
46393 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
46394 +*//***************************************************************************/
46395 +#ifndef __FM_PCD_IPC_H
46396 +#define __FM_PCD_IPC_H
46397 +
46398 +#include "std_ext.h"
46399 +
46400 +
46401 +/**************************************************************************//**
46402 + @Group FM_grp Frame Manager API
46403 +
46404 + @Description FM API functions, definitions and enums
46405 +
46406 + @{
46407 +*//***************************************************************************/
46408 +
46409 +
46410 +#if defined(__MWERKS__) && !defined(__GNUC__)
46411 +#pragma pack(push,1)
46412 +#endif /* defined(__MWERKS__) && ... */
46413 +
46414 +/**************************************************************************//**
46415 + @Description Structure for getting a sw parser address according to a label
46416 + Fields commented 'IN' are passed by the port module to be used
46417 + by the FM module.
46418 + Fields commented 'OUT' will be filled by FM before returning to port.
46419 +*//***************************************************************************/
46420 +typedef _Packed struct t_FmPcdIpcSwPrsLable
46421 +{
46422 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
46423 + the sw parser code. */
46424 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
46425 + attachments for the same header, use this
46426 +
46427 + index to distinguish between them. */
46428 +} _PackedType t_FmPcdIpcSwPrsLable;
46429 +
46430 +/**************************************************************************//**
46431 + @Description Structure for port-PCD communication.
46432 + Fields commented 'IN' are passed by the port module to be used
46433 + by the FM module.
46434 + Fields commented 'OUT' will be filled by FM before returning to port.
46435 + Some fields are optional (depending on configuration) and
46436 + will be analized by the port and FM modules accordingly.
46437 +*//***************************************************************************/
46438 +
46439 +typedef struct t_FmPcdIpcKgSchemesParams
46440 +{
46441 + uint8_t guestId;
46442 + uint8_t numOfSchemes;
46443 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46444 +} _PackedType t_FmPcdIpcKgSchemesParams;
46445 +
46446 +typedef struct t_FmPcdIpcKgClsPlanParams
46447 +{
46448 + uint8_t guestId;
46449 + uint16_t numOfClsPlanEntries;
46450 + uint8_t clsPlanBase;
46451 +} _PackedType t_FmPcdIpcKgClsPlanParams;
46452 +
46453 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
46454 +{
46455 + uint8_t hardwarePortId;
46456 + bool include;
46457 +} _PackedType t_FmPcdIpcPrsIncludePort;
46458 +
46459 +
46460 +#define FM_PCD_MAX_REPLY_SIZE 16
46461 +#define FM_PCD_MAX_MSG_SIZE 36
46462 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
46463 +
46464 +typedef _Packed struct {
46465 + uint32_t msgId;
46466 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
46467 +} _PackedType t_FmPcdIpcMsg;
46468 +
46469 +typedef _Packed struct t_FmPcdIpcReply {
46470 + uint32_t error;
46471 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
46472 +} _PackedType t_FmPcdIpcReply;
46473 +
46474 +typedef _Packed struct t_FmIpcResourceAllocParams {
46475 + uint8_t guestId;
46476 + uint16_t base;
46477 + uint16_t num;
46478 +}_PackedType t_FmIpcResourceAllocParams;
46479 +
46480 +#if defined(__MWERKS__) && !defined(__GNUC__)
46481 +#pragma pack(pop)
46482 +#endif /* defined(__MWERKS__) && ... */
46483 +
46484 +
46485 +
46486 +/**************************************************************************//**
46487 + @Function FM_PCD_ALLOC_KG_SCHEMES
46488 +
46489 + @Description Used by FM PCD front-end in order to allocate KG resources
46490 +
46491 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
46492 +*//***************************************************************************/
46493 +#define FM_PCD_ALLOC_KG_SCHEMES 3
46494 +
46495 +/**************************************************************************//**
46496 + @Function FM_PCD_FREE_KG_SCHEMES
46497 +
46498 + @Description Used by FM PCD front-end in order to Free KG resources
46499 +
46500 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
46501 +*//***************************************************************************/
46502 +#define FM_PCD_FREE_KG_SCHEMES 4
46503 +
46504 +/**************************************************************************//**
46505 + @Function FM_PCD_ALLOC_PROFILES
46506 +
46507 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46508 +
46509 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46510 +*//***************************************************************************/
46511 +#define FM_PCD_ALLOC_PROFILES 5
46512 +
46513 +/**************************************************************************//**
46514 + @Function FM_PCD_FREE_PROFILES
46515 +
46516 + @Description Used by FM PCD front-end in order to Free Policer profiles
46517 +
46518 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46519 +*//***************************************************************************/
46520 +#define FM_PCD_FREE_PROFILES 6
46521 +
46522 +/**************************************************************************//**
46523 + @Function FM_PCD_SET_PORT_PROFILES
46524 +
46525 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46526 + for specific port
46527 +
46528 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46529 +*//***************************************************************************/
46530 +#define FM_PCD_SET_PORT_PROFILES 7
46531 +
46532 +/**************************************************************************//**
46533 + @Function FM_PCD_CLEAR_PORT_PROFILES
46534 +
46535 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46536 + for specific port
46537 +
46538 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46539 +*//***************************************************************************/
46540 +#define FM_PCD_CLEAR_PORT_PROFILES 8
46541 +
46542 +/**************************************************************************//**
46543 + @Function FM_PCD_GET_PHYS_MURAM_BASE
46544 +
46545 + @Description Used by FM PCD front-end in order to get MURAM base address
46546 +
46547 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
46548 +*//***************************************************************************/
46549 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
46550 +
46551 +/**************************************************************************//**
46552 + @Function FM_PCD_GET_SW_PRS_OFFSET
46553 +
46554 + @Description Used by FM front-end to get the SW parser offset of the start of
46555 + code relevant to a given label.
46556 +
46557 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
46558 +*//***************************************************************************/
46559 +#define FM_PCD_GET_SW_PRS_OFFSET 10
46560 +
46561 +/**************************************************************************//**
46562 + @Function FM_PCD_MASTER_IS_ENABLED
46563 +
46564 + @Description Used by FM front-end in order to verify
46565 + PCD enablement.
46566 +
46567 + @Param[in] bool Pointer
46568 +*//***************************************************************************/
46569 +#define FM_PCD_MASTER_IS_ENABLED 15
46570 +
46571 +/**************************************************************************//**
46572 + @Function FM_PCD_GUEST_DISABLE
46573 +
46574 + @Description Used by FM front-end to inform back-end when
46575 + front-end PCD is disabled
46576 +
46577 + @Param[in] None
46578 +*//***************************************************************************/
46579 +#define FM_PCD_GUEST_DISABLE 16
46580 +
46581 +/**************************************************************************//**
46582 + @Function FM_PCD_FREE_KG_CLSPLAN
46583 +
46584 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
46585 +
46586 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46587 +*//***************************************************************************/
46588 +#define FM_PCD_FREE_KG_CLSPLAN 22
46589 +
46590 +/**************************************************************************//**
46591 + @Function FM_PCD_ALLOC_KG_CLSPLAN
46592 +
46593 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
46594 +
46595 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46596 +*//***************************************************************************/
46597 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
46598 +
46599 +/**************************************************************************//**
46600 + @Function FM_PCD_MASTER_IS_ALIVE
46601 +
46602 + @Description Used by FM front-end to check that back-end exists
46603 +
46604 + @Param[in] None
46605 +*//***************************************************************************/
46606 +#define FM_PCD_MASTER_IS_ALIVE 24
46607 +
46608 +/**************************************************************************//**
46609 + @Function FM_PCD_GET_COUNTER
46610 +
46611 + @Description Used by FM front-end to read PCD counters
46612 +
46613 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
46614 +*//***************************************************************************/
46615 +#define FM_PCD_GET_COUNTER 25
46616 +
46617 +/**************************************************************************//**
46618 + @Function FM_PCD_PRS_INC_PORT_STATS
46619 +
46620 + @Description Used by FM front-end to set/clear statistics for port
46621 +
46622 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
46623 +*//***************************************************************************/
46624 +#define FM_PCD_PRS_INC_PORT_STATS 26
46625 +
46626 +#if (DPAA_VERSION >= 11)
46627 +/* TODO - doc */
46628 +#define FM_PCD_ALLOC_SP 27
46629 +#endif /* (DPAA_VERSION >= 11) */
46630 +
46631 +
46632 +/** @} */ /* end of FM_PCD_IPC_grp group */
46633 +/** @} */ /* end of FM_grp group */
46634 +
46635 +
46636 +#endif /* __FM_PCD_IPC_H */
46637 --- /dev/null
46638 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46639 @@ -0,0 +1,1847 @@
46640 +/*
46641 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46642 + *
46643 + * Redistribution and use in source and binary forms, with or without
46644 + * modification, are permitted provided that the following conditions are met:
46645 + * * Redistributions of source code must retain the above copyright
46646 + * notice, this list of conditions and the following disclaimer.
46647 + * * Redistributions in binary form must reproduce the above copyright
46648 + * notice, this list of conditions and the following disclaimer in the
46649 + * documentation and/or other materials provided with the distribution.
46650 + * * Neither the name of Freescale Semiconductor nor the
46651 + * names of its contributors may be used to endorse or promote products
46652 + * derived from this software without specific prior written permission.
46653 + *
46654 + *
46655 + * ALTERNATIVELY, this software may be distributed under the terms of the
46656 + * GNU General Public License ("GPL") as published by the Free Software
46657 + * Foundation, either version 2 of that License or (at your option) any
46658 + * later version.
46659 + *
46660 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46661 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46662 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46663 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46664 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46665 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46666 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46667 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46668 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46669 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46670 + */
46671 +
46672 +
46673 +/******************************************************************************
46674 + @File fm_plcr.c
46675 +
46676 + @Description FM PCD POLICER...
46677 +*//***************************************************************************/
46678 +#include <linux/math64.h>
46679 +#include "std_ext.h"
46680 +#include "error_ext.h"
46681 +#include "string_ext.h"
46682 +#include "debug_ext.h"
46683 +#include "net_ext.h"
46684 +#include "fm_ext.h"
46685 +
46686 +#include "fm_common.h"
46687 +#include "fm_pcd.h"
46688 +#include "fm_hc.h"
46689 +#include "fm_pcd_ipc.h"
46690 +#include "fm_plcr.h"
46691 +
46692 +
46693 +/****************************************/
46694 +/* static functions */
46695 +/****************************************/
46696 +
46697 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
46698 +{
46699 + ASSERT_COND(h_Profile);
46700 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46701 +}
46702 +
46703 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
46704 +{
46705 + ASSERT_COND(h_Profile);
46706 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
46707 +}
46708 +
46709 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
46710 +{
46711 + ASSERT_COND(h_Profile);
46712 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46713 +}
46714 +
46715 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
46716 +{
46717 + ASSERT_COND(h_Profile);
46718 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
46719 +}
46720 +
46721 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
46722 +{
46723 + ASSERT_COND(h_FmPcdPlcr);
46724 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
46725 +}
46726 +
46727 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46728 +{
46729 + ASSERT_COND(h_FmPcdPlcr);
46730 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
46731 +}
46732 +
46733 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
46734 +{
46735 + ASSERT_COND(h_FmPcdPlcr);
46736 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
46737 +}
46738 +
46739 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
46740 +{
46741 + ASSERT_COND(h_FmPcdPlcr);
46742 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
46743 +}
46744 +
46745 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
46746 +{
46747 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46748 + uint16_t i;
46749 +
46750 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
46751 +
46752 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
46753 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
46754 + return TRUE;
46755 + return FALSE;
46756 +}
46757 +
46758 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
46759 +{
46760 + uint32_t nia;
46761 + uint16_t absoluteProfileId;
46762 + uint8_t relativeSchemeId, physicalSchemeId;
46763 +
46764 + nia = FM_PCD_PLCR_NIA_VALID;
46765 +
46766 + switch (nextEngine)
46767 + {
46768 + case e_FM_PCD_DONE :
46769 + switch (p_NextEngineParams->action)
46770 + {
46771 + case e_FM_PCD_DROP_FRAME :
46772 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
46773 + break;
46774 + case e_FM_PCD_ENQ_FRAME:
46775 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
46776 + break;
46777 + default:
46778 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46779 + }
46780 + break;
46781 + case e_FM_PCD_KG:
46782 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
46783 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
46784 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
46785 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
46786 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
46787 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
46788 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
46789 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
46790 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
46791 + break;
46792 + case e_FM_PCD_PLCR:
46793 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
46794 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
46795 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
46796 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
46797 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
46798 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
46799 + break;
46800 + default:
46801 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
46802 + }
46803 +
46804 + *nextAction = nia;
46805 +
46806 + return E_OK;
46807 +}
46808 +
46809 +static uint32_t CalcFPP(uint32_t fpp)
46810 +{
46811 + if (fpp > 15)
46812 + return 15 - (0x1f - fpp);
46813 + else
46814 + return 16 + fpp;
46815 +}
46816 +
46817 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
46818 + uint32_t rate,
46819 + uint64_t tsuInTenthNano,
46820 + uint32_t fppShift,
46821 + uint64_t *p_Integer,
46822 + uint64_t *p_Fraction)
46823 +{
46824 + uint64_t tmp, div;
46825 +
46826 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
46827 + {
46828 + /* now we calculate the initial integer for the bigger rate */
46829 + /* from Kbps to Bytes/TSU */
46830 + tmp = (uint64_t)rate;
46831 + tmp *= 1000; /* kb --> b */
46832 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
46833 +
46834 + div = 1000000000; /* nano */
46835 + div *= 10; /* 10 nano */
46836 + div *= 8; /* bit to byte */
46837 + }
46838 + else
46839 + {
46840 + /* now we calculate the initial integer for the bigger rate */
46841 + /* from Kbps to Bytes/TSU */
46842 + tmp = (uint64_t)rate;
46843 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
46844 +
46845 + div = 1000000000; /* nano */
46846 + div *= 10; /* 10 nano */
46847 + }
46848 + *p_Integer = div64_u64(tmp<<fppShift, div);
46849 +
46850 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
46851 + * For precision, we will multiply by 2^16. we do not divid back, since we write
46852 + * this value as fraction - see spec.
46853 + */
46854 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
46855 +}
46856 +
46857 +/* .......... */
46858 +
46859 +static void CalcRates(uint32_t bitFor1Micro,
46860 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
46861 + uint32_t *cir,
46862 + uint32_t *cbs,
46863 + uint32_t *pir_eir,
46864 + uint32_t *pbs_ebs,
46865 + uint32_t *fpp)
46866 +{
46867 + uint64_t integer, fraction;
46868 + uint32_t temp, tsuInTenthNanos;
46869 + uint8_t fppShift=0;
46870 +
46871 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
46872 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
46873 +
46874 + /* we choose the faster rate to calibrate fpp */
46875 + /* The meaning of this step:
46876 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
46877 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
46878 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
46879 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
46880 + * high rate, as many bits as possible for fraction at low rate.
46881 + */
46882 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
46883 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
46884 + else
46885 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
46886 +
46887 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
46888 + * the LSB bits are for the fraction */
46889 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
46890 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
46891 + * take max FP = 31.
46892 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
46893 + * limited by the 10G physical port.
46894 + */
46895 + if (temp != 0)
46896 + {
46897 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
46898 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
46899 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
46900 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
46901 + * to use these bits for the fraction. in this way we will have for fraction - the number
46902 + * of "0" bits and the rest - for integer.
46903 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
46904 + * one bit to the left - preserving the relationship and achieving more bits
46905 + * for integer in the TS.
46906 + */
46907 +
46908 + /* count zeroes left of the higher used bit (in order to shift the value such that
46909 + * unused bits may be used for fraction).
46910 + */
46911 + while ((temp & 0x80000000) == 0)
46912 + {
46913 + temp = temp << 1;
46914 + fppShift++;
46915 + }
46916 + if (fppShift > 15)
46917 + {
46918 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
46919 + return;
46920 + }
46921 + }
46922 + else
46923 + {
46924 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
46925 + if (!temp)
46926 + /* integer and fraction are 0, we set FP to its max val */
46927 + fppShift = 31;
46928 + else
46929 + {
46930 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
46931 + * + all left zeroes of the fraction. */
46932 + fppShift=16;
46933 + /* count zeroes left of the higher used bit (in order to shift the value such that
46934 + * unused bits may be used for fraction).
46935 + */
46936 + while ((temp & 0x8000) == 0)
46937 + {
46938 + temp = temp << 1;
46939 + fppShift++;
46940 + }
46941 + }
46942 + }
46943 +
46944 + /*
46945 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
46946 + * fraction and the rest for integer */
46947 + /* now we re-calculate cir and pir_eir with the calculated FP */
46948 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
46949 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
46950 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
46951 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
46952 +
46953 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
46954 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
46955 +
46956 + /* convert FP as it should be written to reg.
46957 + * 0-15 --> 16-31
46958 + * 16-31 --> 0-15
46959 + */
46960 + *fpp = CalcFPP(fppShift);
46961 +}
46962 +
46963 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
46964 +{
46965 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
46966 +
46967 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
46968 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
46969 +
46970 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
46971 +}
46972 +
46973 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
46974 + t_FmPcdPlcrProfileParams *p_ProfileParams,
46975 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
46976 +{
46977 + t_Error err = E_OK;
46978 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
46979 +
46980 + ASSERT_COND(p_FmPcd);
46981 +
46982 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
46983 + if (bitFor1Micro == 0)
46984 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
46985 +
46986 +/* Set G, Y, R Nia */
46987 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
46988 + if (err)
46989 + RETURN_ERROR(MAJOR, err, NO_MSG);
46990 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
46991 + if (err)
46992 + RETURN_ERROR(MAJOR, err, NO_MSG);
46993 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
46994 + if (err)
46995 + RETURN_ERROR(MAJOR, err, NO_MSG);
46996 +
46997 +/* Mode fmpl_pemode */
46998 + pemode = FM_PCD_PLCR_PEMODE_PI;
46999 +
47000 + switch (p_ProfileParams->algSelection)
47001 + {
47002 + case e_FM_PCD_PLCR_PASS_THROUGH:
47003 + p_PlcrRegs->fmpl_pecir = 0;
47004 + p_PlcrRegs->fmpl_pecbs = 0;
47005 + p_PlcrRegs->fmpl_pepepir_eir = 0;
47006 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
47007 + p_PlcrRegs->fmpl_pelts = 0;
47008 + p_PlcrRegs->fmpl_pects = 0;
47009 + p_PlcrRegs->fmpl_pepts_ets = 0;
47010 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
47011 + switch (p_ProfileParams->colorMode)
47012 + {
47013 + case e_FM_PCD_PLCR_COLOR_BLIND:
47014 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47015 + switch (p_ProfileParams->color.dfltColor)
47016 + {
47017 + case e_FM_PCD_PLCR_GREEN:
47018 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
47019 + break;
47020 + case e_FM_PCD_PLCR_YELLOW:
47021 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
47022 + break;
47023 + case e_FM_PCD_PLCR_RED:
47024 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
47025 + break;
47026 + case e_FM_PCD_PLCR_OVERRIDE:
47027 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
47028 + break;
47029 + default:
47030 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47031 + }
47032 +
47033 + break;
47034 + case e_FM_PCD_PLCR_COLOR_AWARE:
47035 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47036 + break;
47037 + default:
47038 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47039 + }
47040 + break;
47041 +
47042 + case e_FM_PCD_PLCR_RFC_2698:
47043 + /* Select algorithm MODE[ALG] = "01" */
47044 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
47045 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
47046 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
47047 + goto cont_rfc;
47048 + case e_FM_PCD_PLCR_RFC_4115:
47049 + /* Select algorithm MODE[ALG] = "10" */
47050 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
47051 +cont_rfc:
47052 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
47053 + switch (p_ProfileParams->colorMode)
47054 + {
47055 + case e_FM_PCD_PLCR_COLOR_BLIND:
47056 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47057 + break;
47058 + case e_FM_PCD_PLCR_COLOR_AWARE:
47059 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47060 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
47061 + switch (p_ProfileParams->color.override)
47062 + {
47063 + case e_FM_PCD_PLCR_GREEN:
47064 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
47065 + break;
47066 + case e_FM_PCD_PLCR_YELLOW:
47067 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
47068 + break;
47069 + case e_FM_PCD_PLCR_RED:
47070 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
47071 + break;
47072 + case e_FM_PCD_PLCR_OVERRIDE:
47073 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
47074 + break;
47075 + default:
47076 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47077 + }
47078 + break;
47079 + default:
47080 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47081 + }
47082 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
47083 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
47084 + {
47085 + case e_FM_PCD_PLCR_BYTE_MODE :
47086 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
47087 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
47088 + {
47089 + case e_FM_PCD_PLCR_L2_FRM_LEN:
47090 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
47091 + break;
47092 + case e_FM_PCD_PLCR_L3_FRM_LEN:
47093 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
47094 + break;
47095 + case e_FM_PCD_PLCR_L4_FRM_LEN:
47096 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
47097 + break;
47098 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
47099 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
47100 + break;
47101 + default:
47102 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47103 + }
47104 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
47105 + {
47106 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
47107 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
47108 + break;
47109 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
47110 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
47111 + break;
47112 + default:
47113 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47114 + }
47115 + break;
47116 + case e_FM_PCD_PLCR_PACKET_MODE :
47117 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
47118 + break;
47119 + default:
47120 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47121 + }
47122 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
47123 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
47124 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
47125 +
47126 + /* Configure Traffic Parameters*/
47127 + {
47128 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
47129 +
47130 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
47131 +
47132 + /* Set Committed Information Rate (CIR) */
47133 + p_PlcrRegs->fmpl_pecir = cir;
47134 + /* Set Committed Burst Size (CBS). */
47135 + p_PlcrRegs->fmpl_pecbs = cbs;
47136 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
47137 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
47138 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
47139 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
47140 +
47141 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
47142 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
47143 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
47144 + /* Committed Rate Token Bucket Size (CTS) */
47145 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
47146 +
47147 + /* Set the FPP based on calculation */
47148 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
47149 + }
47150 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
47151 + default:
47152 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47153 + }
47154 +
47155 + p_PlcrRegs->fmpl_pemode = pemode;
47156 +
47157 + p_PlcrRegs->fmpl_pegnia = gnia;
47158 + p_PlcrRegs->fmpl_peynia = ynia;
47159 + p_PlcrRegs->fmpl_pernia = rnia;
47160 +
47161 + /* Zero Counters */
47162 + p_PlcrRegs->fmpl_pegpc = 0;
47163 + p_PlcrRegs->fmpl_peypc = 0;
47164 + p_PlcrRegs->fmpl_perpc = 0;
47165 + p_PlcrRegs->fmpl_perypc = 0;
47166 + p_PlcrRegs->fmpl_perrpc = 0;
47167 +
47168 + return E_OK;
47169 +}
47170 +
47171 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47172 +{
47173 + uint32_t profilesFound;
47174 + uint16_t i, k=0;
47175 + uint32_t intFlags;
47176 +
47177 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47178 +
47179 + if (!numOfProfiles)
47180 + return E_OK;
47181 +
47182 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47183 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47184 +
47185 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47186 + /* Find numOfProfiles free profiles (may be spread) */
47187 + profilesFound = 0;
47188 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47189 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47190 + {
47191 + profilesFound++;
47192 + profilesIds[k] = i;
47193 + k++;
47194 + if (profilesFound == numOfProfiles)
47195 + break;
47196 + }
47197 +
47198 + if (profilesFound != numOfProfiles)
47199 + {
47200 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47201 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
47202 + }
47203 +
47204 + for (i = 0;i<k;i++)
47205 + {
47206 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
47207 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
47208 + }
47209 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47210 +
47211 + return E_OK;
47212 +}
47213 +
47214 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47215 +{
47216 + uint16_t i;
47217 +
47218 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
47219 +
47220 + ASSERT_COND(numOfProfiles);
47221 +
47222 + for (i=0; i < numOfProfiles; i++)
47223 + {
47224 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
47225 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
47226 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
47227 + }
47228 +}
47229 +
47230 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
47231 +{
47232 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47233 +
47234 + /* this routine is protected by calling routine */
47235 +
47236 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47237 +
47238 + if (set)
47239 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
47240 + else
47241 + {
47242 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
47243 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
47244 + }
47245 +}
47246 +
47247 +/*********************************************/
47248 +/*............Policer Exception..............*/
47249 +/*********************************************/
47250 +static void EventsCB(t_Handle h_FmPcd)
47251 +{
47252 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47253 + uint32_t event, mask, force;
47254 +
47255 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47256 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
47257 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47258 +
47259 + event &= mask;
47260 +
47261 + /* clear the forced events */
47262 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
47263 + if (force & event)
47264 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
47265 +
47266 +
47267 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
47268 +
47269 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
47270 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
47271 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
47272 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
47273 +}
47274 +
47275 +/* ..... */
47276 +
47277 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
47278 +{
47279 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47280 + uint32_t event, force, captureReg, mask;
47281 +
47282 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47283 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
47284 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47285 +
47286 + event &= mask;
47287 +
47288 + /* clear the forced events */
47289 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
47290 + if (force & event)
47291 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
47292 +
47293 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
47294 +
47295 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
47296 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
47297 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
47298 + {
47299 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
47300 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
47301 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
47302 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
47303 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
47304 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
47305 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
47306 + }
47307 +}
47308 +
47309 +
47310 +/*****************************************************************************/
47311 +/* Inter-module API routines */
47312 +/*****************************************************************************/
47313 +
47314 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
47315 +{
47316 + t_FmPcdPlcr *p_FmPcdPlcr;
47317 + uint16_t i=0;
47318 +
47319 + UNUSED(p_FmPcd);
47320 + UNUSED(p_FmPcdParams);
47321 +
47322 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
47323 + if (!p_FmPcdPlcr)
47324 + {
47325 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
47326 + return NULL;
47327 + }
47328 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
47329 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
47330 + {
47331 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
47332 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
47333 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
47334 + }
47335 +
47336 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
47337 +
47338 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
47339 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
47340 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
47341 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
47342 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
47343 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
47344 +
47345 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47346 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47347 +
47348 + return p_FmPcdPlcr;
47349 +}
47350 +
47351 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
47352 +{
47353 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
47354 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47355 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47356 + t_Error err = E_OK;
47357 + uint32_t tmpReg32 = 0;
47358 + uint16_t base;
47359 +
47360 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
47361 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
47362 +
47363 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
47364 + if (!p_FmPcdPlcr->h_HwSpinlock)
47365 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
47366 +
47367 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
47368 + if (!p_FmPcdPlcr->h_SwSpinlock)
47369 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
47370 +
47371 + base = PlcrAllocProfilesForPartition(p_FmPcd,
47372 + p_FmPcdPlcr->partPlcrProfilesBase,
47373 + p_FmPcdPlcr->partNumOfPlcrProfiles,
47374 + p_FmPcd->guestId);
47375 + if (base == (uint16_t)ILLEGAL_BASE)
47376 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
47377 +
47378 + if (p_FmPcdPlcr->numOfSharedProfiles)
47379 + {
47380 + err = AllocSharedProfiles(p_FmPcd,
47381 + p_FmPcdPlcr->numOfSharedProfiles,
47382 + p_FmPcdPlcr->sharedProfilesIds);
47383 + if (err)
47384 + RETURN_ERROR(MAJOR, err,NO_MSG);
47385 + }
47386 +
47387 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47388 + return E_OK;
47389 +
47390 + /**********************FMPL_GCR******************/
47391 + tmpReg32 = 0;
47392 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
47393 + if (p_Param->plcrAutoRefresh)
47394 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
47395 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47396 +
47397 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
47398 + /**********************FMPL_GCR******************/
47399 +
47400 + /**********************FMPL_EEVR******************/
47401 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
47402 + /**********************FMPL_EEVR******************/
47403 + /**********************FMPL_EIER******************/
47404 + tmpReg32 = 0;
47405 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
47406 + {
47407 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47408 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
47409 + }
47410 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47411 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47412 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
47413 + /**********************FMPL_EIER******************/
47414 +
47415 + /**********************FMPL_EVR******************/
47416 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
47417 + /**********************FMPL_EVR******************/
47418 + /**********************FMPL_IER******************/
47419 + tmpReg32 = 0;
47420 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
47421 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47422 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
47423 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47424 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
47425 + /**********************FMPL_IER******************/
47426 +
47427 + /* register even if no interrupts enabled, to allow future enablement */
47428 + FmRegisterIntr(p_FmPcd->h_Fm,
47429 + e_FM_MOD_PLCR,
47430 + 0,
47431 + e_FM_INTR_TYPE_ERR,
47432 + ErrorExceptionsCB,
47433 + p_FmPcd);
47434 + FmRegisterIntr(p_FmPcd->h_Fm,
47435 + e_FM_MOD_PLCR,
47436 + 0,
47437 + e_FM_INTR_TYPE_NORMAL,
47438 + EventsCB,
47439 + p_FmPcd);
47440 +
47441 + /* driver initializes one DFLT profile at the last entry*/
47442 + /**********************FMPL_DPMR******************/
47443 + tmpReg32 = 0;
47444 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
47445 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
47446 +
47447 + return E_OK;
47448 +}
47449 +
47450 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
47451 +{
47452 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
47453 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
47454 +
47455 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
47456 + FreeSharedProfiles(p_FmPcd,
47457 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
47458 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
47459 +
47460 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
47461 + PlcrFreeProfilesForPartition(p_FmPcd,
47462 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
47463 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
47464 + p_FmPcd->guestId);
47465 +
47466 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
47467 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
47468 +
47469 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
47470 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
47471 +
47472 + return E_OK;
47473 +}
47474 +
47475 +void PlcrEnable(t_FmPcd *p_FmPcd)
47476 +{
47477 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47478 +
47479 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
47480 +}
47481 +
47482 +void PlcrDisable(t_FmPcd *p_FmPcd)
47483 +{
47484 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47485 +
47486 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
47487 +}
47488 +
47489 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47490 +{
47491 + uint32_t intFlags;
47492 + uint16_t profilesFound = 0;
47493 + int i = 0;
47494 +
47495 + ASSERT_COND(p_FmPcd);
47496 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47497 +
47498 + if (!numOfProfiles)
47499 + return 0;
47500 +
47501 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
47502 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
47503 + return (uint16_t)ILLEGAL_BASE;
47504 +
47505 + if (p_FmPcd->h_IpcSession)
47506 + {
47507 + t_FmIpcResourceAllocParams ipcAllocParams;
47508 + t_FmPcdIpcMsg msg;
47509 + t_FmPcdIpcReply reply;
47510 + t_Error err;
47511 + uint32_t replyLength;
47512 +
47513 + memset(&msg, 0, sizeof(msg));
47514 + memset(&reply, 0, sizeof(reply));
47515 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47516 + ipcAllocParams.guestId = p_FmPcd->guestId;
47517 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47518 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47519 + msg.msgId = FM_PCD_ALLOC_PROFILES;
47520 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47521 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
47522 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47523 + (uint8_t*)&msg,
47524 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47525 + (uint8_t*)&reply,
47526 + &replyLength,
47527 + NULL,
47528 + NULL);
47529 + if ((err != E_OK) ||
47530 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
47531 + {
47532 + REPORT_ERROR(MAJOR, err, NO_MSG);
47533 + return (uint16_t)ILLEGAL_BASE;
47534 + }
47535 + else
47536 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
47537 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
47538 + {
47539 + REPORT_ERROR(MAJOR, err, NO_MSG);
47540 + return (uint16_t)ILLEGAL_BASE;
47541 + }
47542 + }
47543 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47544 + {
47545 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47546 + return (uint16_t)ILLEGAL_BASE;
47547 + }
47548 +
47549 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
47550 + for (i=base; i<(base+numOfProfiles); i++)
47551 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
47552 + profilesFound++;
47553 + else
47554 + break;
47555 +
47556 + if (profilesFound == numOfProfiles)
47557 + for (i=base; i<(base+numOfProfiles); i++)
47558 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
47559 + else
47560 + {
47561 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47562 + return (uint16_t)ILLEGAL_BASE;
47563 + }
47564 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47565 +
47566 + return base;
47567 +}
47568 +
47569 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47570 +{
47571 + int i = 0;
47572 +
47573 + ASSERT_COND(p_FmPcd);
47574 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47575 +
47576 + if (p_FmPcd->h_IpcSession)
47577 + {
47578 + t_FmIpcResourceAllocParams ipcAllocParams;
47579 + t_FmPcdIpcMsg msg;
47580 + t_Error err;
47581 +
47582 + memset(&msg, 0, sizeof(msg));
47583 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47584 + ipcAllocParams.guestId = p_FmPcd->guestId;
47585 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47586 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47587 + msg.msgId = FM_PCD_FREE_PROFILES;
47588 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47589 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47590 + (uint8_t*)&msg,
47591 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47592 + NULL,
47593 + NULL,
47594 + NULL,
47595 + NULL);
47596 + if (err != E_OK)
47597 + REPORT_ERROR(MAJOR, err, NO_MSG);
47598 + return;
47599 + }
47600 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47601 + {
47602 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47603 + return;
47604 + }
47605 +
47606 + for (i=base; i<(base+numOfProfiles); i++)
47607 + {
47608 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
47609 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47610 + else
47611 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
47612 + }
47613 +}
47614 +
47615 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47616 + uint8_t hardwarePortId,
47617 + uint16_t numOfProfiles,
47618 + uint16_t base)
47619 +{
47620 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47621 + uint32_t log2Num, tmpReg32;
47622 +
47623 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47624 + !p_Regs &&
47625 + p_FmPcd->h_IpcSession)
47626 + {
47627 + t_FmIpcResourceAllocParams ipcAllocParams;
47628 + t_FmPcdIpcMsg msg;
47629 + t_Error err;
47630 +
47631 + memset(&msg, 0, sizeof(msg));
47632 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47633 + ipcAllocParams.guestId = hardwarePortId;
47634 + ipcAllocParams.num = numOfProfiles;
47635 + ipcAllocParams.base = base;
47636 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
47637 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47638 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47639 + (uint8_t*)&msg,
47640 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47641 + NULL,
47642 + NULL,
47643 + NULL,
47644 + NULL);
47645 + if (err != E_OK)
47646 + RETURN_ERROR(MAJOR, err, NO_MSG);
47647 + return E_OK;
47648 + }
47649 + else if (!p_Regs)
47650 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47651 + ("Either IPC or 'baseAddress' is required!"));
47652 +
47653 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47654 +
47655 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
47656 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
47657 + ("The requesting port has already an allocated profiles window."));
47658 +
47659 + /**********************FMPL_PMRx******************/
47660 + LOG2((uint64_t)numOfProfiles, log2Num);
47661 + tmpReg32 = base;
47662 + tmpReg32 |= log2Num << 16;
47663 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
47664 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
47665 +
47666 + return E_OK;
47667 +}
47668 +
47669 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
47670 +{
47671 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47672 +
47673 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47674 + !p_Regs &&
47675 + p_FmPcd->h_IpcSession)
47676 + {
47677 + t_FmIpcResourceAllocParams ipcAllocParams;
47678 + t_FmPcdIpcMsg msg;
47679 + t_Error err;
47680 +
47681 + memset(&msg, 0, sizeof(msg));
47682 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47683 + ipcAllocParams.guestId = hardwarePortId;
47684 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
47685 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47686 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47687 + (uint8_t*)&msg,
47688 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47689 + NULL,
47690 + NULL,
47691 + NULL,
47692 + NULL);
47693 + if (err != E_OK)
47694 + RETURN_ERROR(MAJOR, err, NO_MSG);
47695 + return E_OK;
47696 + }
47697 + else if (!p_Regs)
47698 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
47699 + ("Either IPC or 'baseAddress' is required!"));
47700 +
47701 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47702 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
47703 +
47704 + return E_OK;
47705 +}
47706 +
47707 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
47708 +{
47709 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47710 + t_Error err = E_OK;
47711 + uint32_t profilesFound;
47712 + uint32_t intFlags;
47713 + uint16_t i, first, swPortIndex = 0;
47714 +
47715 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47716 +
47717 + if (!numOfProfiles)
47718 + return E_OK;
47719 +
47720 + ASSERT_COND(hardwarePortId);
47721 +
47722 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47723 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47724 +
47725 + if (!POWER_OF_2(numOfProfiles))
47726 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
47727 +
47728 + first = 0;
47729 + profilesFound = 0;
47730 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47731 +
47732 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
47733 + {
47734 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47735 + {
47736 + profilesFound++;
47737 + i++;
47738 + if (profilesFound == numOfProfiles)
47739 + break;
47740 + }
47741 + else
47742 + {
47743 + profilesFound = 0;
47744 + /* advance i to the next aligned address */
47745 + i = first = (uint16_t)(first + numOfProfiles);
47746 + }
47747 + }
47748 +
47749 + if (profilesFound == numOfProfiles)
47750 + {
47751 + for (i=first; i<first + numOfProfiles; i++)
47752 + {
47753 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
47754 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
47755 + }
47756 + }
47757 + else
47758 + {
47759 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47760 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
47761 + }
47762 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47763 +
47764 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
47765 + if (err)
47766 + {
47767 + RETURN_ERROR(MAJOR, err, NO_MSG);
47768 + }
47769 +
47770 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47771 +
47772 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
47773 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
47774 +
47775 + return E_OK;
47776 +}
47777 +
47778 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
47779 +{
47780 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47781 + t_Error err = E_OK;
47782 + uint32_t intFlags;
47783 + uint16_t i, swPortIndex = 0;
47784 +
47785 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
47786 +
47787 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47788 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
47789 +
47790 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
47791 +
47792 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
47793 + if (err)
47794 + RETURN_ERROR(MAJOR, err,NO_MSG);
47795 +
47796 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47797 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
47798 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
47799 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
47800 + i++)
47801 + {
47802 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
47803 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
47804 +
47805 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
47806 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
47807 + }
47808 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47809 +
47810 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
47811 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
47812 +
47813 + return E_OK;
47814 +}
47815 +
47816 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
47817 +{
47818 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47819 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47820 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
47821 + uint32_t tmpReg32, intFlags;
47822 + t_Error err;
47823 +
47824 + /* Calling function locked all PCD modules, so no need to lock here */
47825 +
47826 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
47827 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
47828 +
47829 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
47830 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
47831 +
47832 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
47833 +
47834 + if (p_FmPcd->h_Hc)
47835 + {
47836 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
47837 +
47838 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
47839 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
47840 +
47841 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47842 + return err;
47843 + }
47844 +
47845 + /* lock the HW because once we read the registers we don't want them to be changed
47846 + * by another access. (We can copy to a tmp location and release the lock!) */
47847 +
47848 + intFlags = PlcrHwLock(p_FmPcdPlcr);
47849 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
47850 +
47851 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
47852 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
47853 + {
47854 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
47855 + {
47856 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
47857 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
47858 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
47859 + {
47860 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47861 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47862 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
47863 + }
47864 +
47865 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
47866 + {
47867 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
47868 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
47869 + {
47870 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47871 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47872 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
47873 + }
47874 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
47875 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
47876 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
47877 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
47878 + WritePar(p_FmPcd, tmpReg32);
47879 + }
47880 +
47881 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
47882 + {
47883 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
47884 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
47885 + {
47886 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47887 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47888 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
47889 + }
47890 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
47891 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
47892 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
47893 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
47894 + WritePar(p_FmPcd, tmpReg32);
47895 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47896 + }
47897 +
47898 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
47899 + {
47900 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
47901 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
47902 + {
47903 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47904 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47905 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
47906 + }
47907 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
47908 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
47909 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
47910 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
47911 + WritePar(p_FmPcd, tmpReg32);
47912 +
47913 + }
47914 + }
47915 + }
47916 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
47917 +
47918 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
47919 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
47920 +
47921 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
47922 +
47923 + return E_OK;
47924 +}
47925 +
47926 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47927 +{
47928 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47929 +
47930 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47931 +
47932 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
47933 +}
47934 +
47935 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47936 +{
47937 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47938 +
47939 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47940 +
47941 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
47942 +}
47943 +
47944 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47945 +{
47946 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47947 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47948 +
47949 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
47950 +
47951 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
47952 +}
47953 +
47954 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47955 +{
47956 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47957 + uint32_t intFlags;
47958 +
47959 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47960 +
47961 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
47962 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
47963 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
47964 +}
47965 +
47966 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47967 +{
47968 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47969 + uint32_t intFlags;
47970 +
47971 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47972 +
47973 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
47974 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
47975 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
47976 +}
47977 +
47978 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
47979 +{
47980 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
47981 +}
47982 +
47983 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
47984 + e_FmPcdProfileTypeSelection profileType,
47985 + t_Handle h_FmPort,
47986 + uint16_t relativeProfile,
47987 + uint16_t *p_AbsoluteId)
47988 +{
47989 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47990 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47991 + uint8_t i;
47992 +
47993 + switch (profileType)
47994 + {
47995 + case e_FM_PCD_PLCR_PORT_PRIVATE:
47996 + /* get port PCD id from port handle */
47997 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
47998 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
47999 + break;
48000 + if (i == FM_MAX_NUM_OF_PORTS)
48001 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
48002 +
48003 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48004 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
48005 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48006 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48007 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
48008 + break;
48009 + case e_FM_PCD_PLCR_SHARED:
48010 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
48011 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48012 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
48013 + break;
48014 + default:
48015 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
48016 + }
48017 +
48018 + return E_OK;
48019 +}
48020 +
48021 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
48022 +{
48023 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48024 + uint16_t swPortIndex = 0;
48025 +
48026 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48027 +
48028 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48029 +}
48030 +
48031 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48032 +{
48033 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48034 + uint16_t swPortIndex = 0;
48035 +
48036 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48037 +
48038 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
48039 +
48040 +}
48041 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
48042 +{
48043 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48044 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
48045 +}
48046 +
48047 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
48048 +{
48049 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48050 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48051 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48052 +}
48053 +
48054 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
48055 +{
48056 +
48057 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
48058 + return TRUE;
48059 + else
48060 + return FALSE;
48061 +}
48062 +
48063 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
48064 +{
48065 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48066 + FM_PCD_PLCR_PAR_R |
48067 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48068 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48069 +}
48070 +
48071 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
48072 +{
48073 + switch (counter)
48074 + {
48075 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
48076 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
48077 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
48078 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
48079 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
48080 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
48081 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
48082 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
48083 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
48084 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
48085 + default:
48086 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48087 + return 0;
48088 + }
48089 +}
48090 +
48091 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
48092 +{
48093 +
48094 + uint32_t tmpReg32 = 0;
48095 +
48096 + if (green)
48097 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48098 + if (yellow)
48099 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48100 + if (red)
48101 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48102 +
48103 + return tmpReg32;
48104 +}
48105 +
48106 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
48107 +{
48108 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48109 +
48110 + /* this routine is protected by calling routine */
48111 +
48112 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48113 +
48114 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
48115 +}
48116 +
48117 +/*********************** End of inter-module routines ************************/
48118 +
48119 +
48120 +/**************************************************/
48121 +/*............Policer API.........................*/
48122 +/**************************************************/
48123 +
48124 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
48125 +{
48126 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48127 +
48128 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48129 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48130 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48131 +
48132 + if (!FmIsMaster(p_FmPcd->h_Fm))
48133 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
48134 +
48135 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
48136 +
48137 + return E_OK;
48138 +}
48139 +
48140 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
48141 +{
48142 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48143 +
48144 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48145 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48146 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48147 +
48148 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
48149 +
48150 + return E_OK;
48151 +}
48152 +
48153 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
48154 +{
48155 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48156 + uint32_t tmpReg32;
48157 +
48158 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48159 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48160 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48161 +
48162 + if (!FmIsMaster(p_FmPcd->h_Fm))
48163 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
48164 +
48165 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
48166 + if (enable)
48167 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
48168 + else
48169 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
48170 +
48171 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
48172 + return E_OK;
48173 +}
48174 +
48175 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
48176 + t_FmPcdPlcrProfileParams *p_ProfileParams)
48177 +{
48178 + t_FmPcd *p_FmPcd;
48179 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48180 + t_FmPcdPlcrProfileRegs plcrProfileReg;
48181 + uint32_t intFlags;
48182 + uint16_t absoluteProfileId;
48183 + t_Error err = E_OK;
48184 + uint32_t tmpReg32;
48185 + t_FmPcdPlcrProfile *p_Profile;
48186 +
48187 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
48188 +
48189 + if (p_ProfileParams->modify)
48190 + {
48191 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
48192 + p_FmPcd = p_Profile->h_FmPcd;
48193 + absoluteProfileId = p_Profile->absoluteProfileId;
48194 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48195 + {
48196 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48197 + return NULL;
48198 + }
48199 +
48200 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48201 +
48202 + /* Try lock profile using flag */
48203 + if (!PlcrProfileFlagTryLock(p_Profile))
48204 + {
48205 + DBG(TRACE, ("Profile Try Lock - BUSY"));
48206 + /* Signal to caller BUSY condition */
48207 + p_ProfileParams->id.h_Profile = NULL;
48208 + return NULL;
48209 + }
48210 + }
48211 + else
48212 + {
48213 + p_FmPcd = (t_FmPcd*)h_FmPcd;
48214 +
48215 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48216 +
48217 + /* SMP: needs to be protected only if another core now changes the windows */
48218 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
48219 + p_ProfileParams->id.newParams.profileType,
48220 + p_ProfileParams->id.newParams.h_FmPort,
48221 + p_ProfileParams->id.newParams.relativeProfileId,
48222 + &absoluteProfileId);
48223 + if (err)
48224 + {
48225 + REPORT_ERROR(MAJOR, err, NO_MSG);
48226 + return NULL;
48227 + }
48228 +
48229 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48230 + {
48231 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48232 + return NULL;
48233 + }
48234 +
48235 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48236 + {
48237 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
48238 + return NULL;
48239 + }
48240 +
48241 + /* initialize profile struct */
48242 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
48243 +
48244 + p_Profile->h_FmPcd = p_FmPcd;
48245 + p_Profile->absoluteProfileId = absoluteProfileId;
48246 +
48247 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
48248 + if (!p_Profile->p_Lock)
48249 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
48250 + }
48251 +
48252 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
48253 +
48254 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
48255 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
48256 +
48257 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
48258 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
48259 +
48260 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
48261 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
48262 +
48263 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
48264 +
48265 + /* build the policer profile registers */
48266 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
48267 + if (err)
48268 + {
48269 + REPORT_ERROR(MAJOR, err, NO_MSG);
48270 + if (p_ProfileParams->modify)
48271 + /* unlock */
48272 + PlcrProfileFlagUnlock(p_Profile);
48273 + if (!p_ProfileParams->modify &&
48274 + p_Profile->p_Lock)
48275 + /* release allocated Profile lock */
48276 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48277 + return NULL;
48278 + }
48279 +
48280 + if (p_FmPcd->h_Hc)
48281 + {
48282 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
48283 + if (p_ProfileParams->modify)
48284 + PlcrProfileFlagUnlock(p_Profile);
48285 + if (err)
48286 + {
48287 + /* release the allocated scheme lock */
48288 + if (!p_ProfileParams->modify &&
48289 + p_Profile->p_Lock)
48290 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48291 +
48292 + return NULL;
48293 + }
48294 + if (!p_ProfileParams->modify)
48295 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48296 + return (t_Handle)p_Profile;
48297 + }
48298 +
48299 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48300 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
48301 +
48302 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48303 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
48304 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
48305 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
48306 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
48307 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
48308 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
48309 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
48310 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
48311 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
48312 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
48313 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
48314 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
48315 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
48316 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
48317 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
48318 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
48319 +
48320 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
48321 + WritePar(p_FmPcd, tmpReg32);
48322 +
48323 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48324 +
48325 + if (!p_ProfileParams->modify)
48326 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48327 + else
48328 + PlcrProfileFlagUnlock(p_Profile);
48329 +
48330 + return (t_Handle)p_Profile;
48331 +}
48332 +
48333 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
48334 +{
48335 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48336 + t_FmPcd *p_FmPcd;
48337 + uint16_t profileIndx;
48338 + uint32_t tmpReg32, intFlags;
48339 + t_Error err;
48340 +
48341 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48342 + p_FmPcd = p_Profile->h_FmPcd;
48343 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48344 +
48345 + profileIndx = p_Profile->absoluteProfileId;
48346 +
48347 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
48348 +
48349 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
48350 +
48351 + if (p_FmPcd->h_Hc)
48352 + {
48353 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
48354 + if (p_Profile->p_Lock)
48355 + /* release allocated Profile lock */
48356 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48357 +
48358 + return err;
48359 + }
48360 +
48361 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48362 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
48363 +
48364 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
48365 + WritePar(p_FmPcd, tmpReg32);
48366 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48367 +
48368 +
48369 + if (p_Profile->p_Lock)
48370 + /* release allocated Profile lock */
48371 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48372 +
48373 + /* we do not memset profile as all its fields are being re-initialized at "set",
48374 + * plus its allocation information is still valid. */
48375 + return E_OK;
48376 +}
48377 +
48378 +/***************************************************/
48379 +/*............Policer Profile Counter..............*/
48380 +/***************************************************/
48381 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
48382 +{
48383 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48384 + t_FmPcd *p_FmPcd;
48385 + uint16_t profileIndx;
48386 + uint32_t intFlags, counterVal = 0;
48387 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48388 +
48389 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48390 + p_FmPcd = p_Profile->h_FmPcd;
48391 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48392 +
48393 + if (p_FmPcd->h_Hc)
48394 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
48395 +
48396 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48397 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
48398 +
48399 + profileIndx = p_Profile->absoluteProfileId;
48400 +
48401 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48402 + {
48403 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48404 + return 0;
48405 + }
48406 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48407 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48408 +
48409 + switch (counter)
48410 + {
48411 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48412 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
48413 + break;
48414 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48415 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
48416 + break;
48417 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48418 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
48419 + break;
48420 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48421 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
48422 + break;
48423 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48424 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
48425 + break;
48426 + default:
48427 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48428 + break;
48429 + }
48430 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48431 +
48432 + return counterVal;
48433 +}
48434 +
48435 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
48436 +{
48437 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48438 + t_FmPcd *p_FmPcd;
48439 + uint16_t profileIndx;
48440 + uint32_t tmpReg32, intFlags;
48441 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48442 +
48443 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48444 +
48445 + p_FmPcd = p_Profile->h_FmPcd;
48446 + profileIndx = p_Profile->absoluteProfileId;
48447 +
48448 + if (p_FmPcd->h_Hc)
48449 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
48450 +
48451 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48452 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
48453 +
48454 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48455 + switch (counter)
48456 + {
48457 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48458 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
48459 + break;
48460 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48461 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
48462 + break;
48463 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48464 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
48465 + break;
48466 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48467 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
48468 + break;
48469 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48470 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
48471 + break;
48472 + default:
48473 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48474 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48475 + }
48476 +
48477 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
48478 + * Profile Number, PWSEL=0xFFFF (select all words).
48479 + */
48480 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48481 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
48482 + WritePar(p_FmPcd, tmpReg32);
48483 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48484 +
48485 + return E_OK;
48486 +}
48487 --- /dev/null
48488 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48489 @@ -0,0 +1,165 @@
48490 +/*
48491 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48492 + *
48493 + * Redistribution and use in source and binary forms, with or without
48494 + * modification, are permitted provided that the following conditions are met:
48495 + * * Redistributions of source code must retain the above copyright
48496 + * notice, this list of conditions and the following disclaimer.
48497 + * * Redistributions in binary form must reproduce the above copyright
48498 + * notice, this list of conditions and the following disclaimer in the
48499 + * documentation and/or other materials provided with the distribution.
48500 + * * Neither the name of Freescale Semiconductor nor the
48501 + * names of its contributors may be used to endorse or promote products
48502 + * derived from this software without specific prior written permission.
48503 + *
48504 + *
48505 + * ALTERNATIVELY, this software may be distributed under the terms of the
48506 + * GNU General Public License ("GPL") as published by the Free Software
48507 + * Foundation, either version 2 of that License or (at your option) any
48508 + * later version.
48509 + *
48510 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48511 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48512 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48513 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48514 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48515 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48516 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48517 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48518 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48519 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48520 + */
48521 +
48522 +
48523 +/******************************************************************************
48524 + @File fm_plcr.h
48525 +
48526 + @Description FM Policer private header
48527 +*//***************************************************************************/
48528 +#ifndef __FM_PLCR_H
48529 +#define __FM_PLCR_H
48530 +
48531 +#include "std_ext.h"
48532 +
48533 +
48534 +/***********************************************************************/
48535 +/* Policer defines */
48536 +/***********************************************************************/
48537 +
48538 +#define FM_PCD_PLCR_PAR_GO 0x80000000
48539 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
48540 +#define FM_PCD_PLCR_PAR_R 0x40000000
48541 +
48542 +/* shifts */
48543 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
48544 +
48545 +/* masks */
48546 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
48547 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
48548 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
48549 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
48550 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
48551 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
48552 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
48553 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
48554 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
48555 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
48556 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
48557 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
48558 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
48559 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
48560 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
48561 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
48562 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
48563 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
48564 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
48565 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
48566 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
48567 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
48568 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
48569 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
48570 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
48571 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
48572 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
48573 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
48574 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
48575 +
48576 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
48577 +
48578 +#define FM_PCD_PLCR_GCR_EN 0x80000000
48579 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
48580 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
48581 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
48582 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
48583 +
48584 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
48585 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
48586 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
48587 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
48588 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
48589 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
48590 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
48591 +
48592 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
48593 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
48594 +
48595 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
48596 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
48597 +/* PWSEL Selctive select options */
48598 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
48599 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
48600 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
48601 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
48602 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
48603 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
48604 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
48605 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
48606 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
48607 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
48608 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
48609 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
48610 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
48611 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
48612 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
48613 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
48614 +
48615 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
48616 + 1-> 2^N specific locations. */
48617 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
48618 + 2-> 2^(N-1) base locations. */
48619 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
48620 + 4-> 2^(N-2) base locations. */
48621 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
48622 + 8->2^(N-3) base locations. */
48623 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
48624 + 16-> 2^(N-4) base locations. */
48625 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
48626 + 32-> 2^(N-5) base locations. */
48627 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
48628 + 64-> 2^(N-6) base locations. */
48629 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
48630 + 128-> 2^(N-7) base locations. */
48631 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
48632 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
48633 +
48634 +#define FM_PCD_PLCR_PMR_V 0x80000000
48635 +#define PLCR_ERR_ECC_CAP 0x80000000
48636 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
48637 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
48638 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
48639 +
48640 +#define PLCR_ERR_UNINIT_CAP 0x80000000
48641 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
48642 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
48643 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
48644 +
48645 +/* shifts */
48646 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
48647 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
48648 +
48649 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
48650 +
48651 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
48652 +
48653 +
48654 +#endif /* __FM_PLCR_H */
48655 --- /dev/null
48656 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
48657 @@ -0,0 +1,423 @@
48658 +/*
48659 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48660 + *
48661 + * Redistribution and use in source and binary forms, with or without
48662 + * modification, are permitted provided that the following conditions are met:
48663 + * * Redistributions of source code must retain the above copyright
48664 + * notice, this list of conditions and the following disclaimer.
48665 + * * Redistributions in binary form must reproduce the above copyright
48666 + * notice, this list of conditions and the following disclaimer in the
48667 + * documentation and/or other materials provided with the distribution.
48668 + * * Neither the name of Freescale Semiconductor nor the
48669 + * names of its contributors may be used to endorse or promote products
48670 + * derived from this software without specific prior written permission.
48671 + *
48672 + *
48673 + * ALTERNATIVELY, this software may be distributed under the terms of the
48674 + * GNU General Public License ("GPL") as published by the Free Software
48675 + * Foundation, either version 2 of that License or (at your option) any
48676 + * later version.
48677 + *
48678 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48679 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48680 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48681 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48682 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48683 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48684 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48685 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48686 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48687 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48688 + */
48689 +
48690 +
48691 +/******************************************************************************
48692 + @File fm_pcd.c
48693 +
48694 + @Description FM PCD ...
48695 +*//***************************************************************************/
48696 +#include <linux/math64.h>
48697 +#include "std_ext.h"
48698 +#include "error_ext.h"
48699 +#include "string_ext.h"
48700 +#include "debug_ext.h"
48701 +#include "net_ext.h"
48702 +
48703 +#include "fm_common.h"
48704 +#include "fm_pcd.h"
48705 +#include "fm_pcd_ipc.h"
48706 +#include "fm_prs.h"
48707 +#include "fsl_fman_prs.h"
48708 +
48709 +
48710 +static void PcdPrsErrorException(t_Handle h_FmPcd)
48711 +{
48712 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48713 + uint32_t event, ev_mask;
48714 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48715 +
48716 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48717 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
48718 +
48719 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
48720 +
48721 + fman_prs_ack_err_event(PrsRegs, event);
48722 +
48723 + DBG(TRACE, ("parser error - 0x%08x\n",event));
48724 +
48725 + if(event & FM_PCD_PRS_DOUBLE_ECC)
48726 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
48727 +}
48728 +
48729 +static void PcdPrsException(t_Handle h_FmPcd)
48730 +{
48731 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48732 + uint32_t event, ev_mask;
48733 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48734 +
48735 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48736 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
48737 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
48738 +
48739 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
48740 +
48741 + DBG(TRACE, ("parser event - 0x%08x\n",event));
48742 +
48743 + fman_prs_ack_expt_event(PrsRegs, event);
48744 +
48745 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
48746 +}
48747 +
48748 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
48749 +{
48750 + t_FmPcdPrs *p_FmPcdPrs;
48751 + uintptr_t baseAddr;
48752 +
48753 + UNUSED(p_FmPcd);
48754 + UNUSED(p_FmPcdParams);
48755 +
48756 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
48757 + if (!p_FmPcdPrs)
48758 + {
48759 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
48760 + return NULL;
48761 + }
48762 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
48763 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
48764 +
48765 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
48766 + {
48767 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
48768 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
48769 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
48770 + }
48771 +
48772 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
48773 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
48774 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
48775 +
48776 + return p_FmPcdPrs;
48777 +}
48778 +
48779 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
48780 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
48781 +#else
48782 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
48783 +#endif /* FM_CAPWAP_SUPPORT */
48784 +
48785 +t_Error PrsInit(t_FmPcd *p_FmPcd)
48786 +{
48787 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
48788 + uint32_t *p_TmpCode;
48789 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
48790 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
48791 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48792 + uint32_t i;
48793 +
48794 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
48795 +
48796 + /* nothing to do in guest-partition */
48797 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
48798 + return E_OK;
48799 +
48800 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
48801 + if (!p_TmpCode)
48802 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
48803 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
48804 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
48805 +
48806 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
48807 +
48808 + /* register even if no interrupts enabled, to allow future enablement */
48809 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
48810 +
48811 + /* register even if no interrupts enabled, to allow future enablement */
48812 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
48813 +
48814 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
48815 + FmEnableRamsEcc(p_FmPcd->h_Fm);
48816 +
48817 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
48818 + FmEnableRamsEcc(p_FmPcd->h_Fm);
48819 +
48820 + /* load sw parser Ip-Frag patch */
48821 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
48822 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
48823 +
48824 + XX_FreeSmart(p_TmpCode);
48825 +
48826 + return E_OK;
48827 +}
48828 +
48829 +void PrsFree(t_FmPcd *p_FmPcd)
48830 +{
48831 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48832 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
48833 + /* register even if no interrupts enabled, to allow future enablement */
48834 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
48835 +}
48836 +
48837 +void PrsEnable(t_FmPcd *p_FmPcd)
48838 +{
48839 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48840 +
48841 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48842 + fman_prs_enable(PrsRegs);
48843 +}
48844 +
48845 +void PrsDisable(t_FmPcd *p_FmPcd)
48846 +{
48847 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48848 +
48849 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48850 + fman_prs_disable(PrsRegs);
48851 +}
48852 +
48853 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
48854 +{
48855 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48856 +
48857 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
48858 + return fman_prs_is_enabled(PrsRegs);
48859 +}
48860 +
48861 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
48862 +{
48863 + struct fman_prs_regs *PrsRegs;
48864 + uint32_t bitMask = 0;
48865 + uint8_t prsPortId;
48866 +
48867 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
48868 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48869 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
48870 +
48871 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48872 +
48873 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
48874 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
48875 +
48876 + if (include)
48877 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
48878 + else
48879 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
48880 +
48881 + fman_prs_set_stst_port_msk(PrsRegs,
48882 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
48883 +
48884 + return E_OK;
48885 +}
48886 +
48887 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
48888 +{
48889 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48890 + t_Error err;
48891 +
48892 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
48893 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48894 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
48895 +
48896 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
48897 + p_FmPcd->h_IpcSession)
48898 + {
48899 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
48900 + t_FmPcdIpcMsg msg;
48901 +
48902 + prsIncludePortParams.hardwarePortId = hardwarePortId;
48903 + prsIncludePortParams.include = include;
48904 + memset(&msg, 0, sizeof(msg));
48905 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
48906 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
48907 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
48908 + (uint8_t*)&msg,
48909 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
48910 + NULL,
48911 + NULL,
48912 + NULL,
48913 + NULL);
48914 + if (err != E_OK)
48915 + RETURN_ERROR(MAJOR, err, NO_MSG);
48916 + return E_OK;
48917 + }
48918 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
48919 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
48920 + ("running in guest-mode without IPC!"));
48921 +
48922 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
48923 +}
48924 +
48925 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
48926 +{
48927 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48928 + t_FmPcdPrsLabelParams *p_Label;
48929 + int i;
48930 +
48931 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
48932 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
48933 +
48934 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
48935 + p_FmPcd->h_IpcSession)
48936 + {
48937 + t_Error err = E_OK;
48938 + t_FmPcdIpcSwPrsLable labelParams;
48939 + t_FmPcdIpcMsg msg;
48940 + uint32_t prsOffset = 0;
48941 + t_FmPcdIpcReply reply;
48942 + uint32_t replyLength;
48943 +
48944 + memset(&reply, 0, sizeof(reply));
48945 + memset(&msg, 0, sizeof(msg));
48946 + labelParams.enumHdr = (uint32_t)hdr;
48947 + labelParams.indexPerHdr = indexPerHdr;
48948 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
48949 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
48950 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
48951 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
48952 + (uint8_t*)&msg,
48953 + sizeof(msg.msgId) +sizeof(labelParams),
48954 + (uint8_t*)&reply,
48955 + &replyLength,
48956 + NULL,
48957 + NULL);
48958 + if (err != E_OK)
48959 + RETURN_ERROR(MAJOR, err, NO_MSG);
48960 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
48961 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
48962 +
48963 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
48964 + return prsOffset;
48965 + }
48966 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
48967 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
48968 + ("running in guest-mode without IPC!"));
48969 +
48970 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
48971 +
48972 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
48973 + {
48974 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
48975 +
48976 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
48977 + return p_Label->instructionOffset;
48978 + }
48979 +
48980 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
48981 + return (uint32_t)ILLEGAL_BASE;
48982 +}
48983 +
48984 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
48985 +{
48986 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48987 + struct fman_prs_regs *PrsRegs;
48988 +
48989 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
48990 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
48991 +
48992 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
48993 +
48994 +
48995 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
48996 + {
48997 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
48998 + return;
48999 + }
49000 +
49001 + fman_prs_set_stst(PrsRegs, enable);
49002 +}
49003 +
49004 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
49005 +{
49006 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49007 + uint32_t *p_LoadTarget;
49008 + uint32_t *p_TmpCode;
49009 + int i;
49010 +
49011 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49012 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
49013 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
49014 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
49015 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
49016 +
49017 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49018 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
49019 +
49020 + if (!p_SwPrs->override)
49021 + {
49022 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
49023 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
49024 + }
49025 + else
49026 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
49027 +
49028 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
49029 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
49030 +
49031 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
49032 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
49033 +
49034 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
49035 + if (!p_TmpCode)
49036 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49037 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
49038 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
49039 +
49040 + /* save sw parser labels */
49041 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
49042 + p_SwPrs->labelsTable,
49043 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
49044 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
49045 +
49046 + /* load sw parser code */
49047 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
49048 +
49049 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
49050 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49051 +
49052 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
49053 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
49054 +
49055 + /* copy data parameters */
49056 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
49057 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
49058 +
49059 + /* Clear last 4 bytes */
49060 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
49061 +
49062 + XX_FreeSmart(p_TmpCode);
49063 +
49064 + return E_OK;
49065 +}
49066 +
49067 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
49068 +{
49069 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49070 +
49071 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49072 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49073 +
49074 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49075 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
49076 +
49077 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
49078 +
49079 + return E_OK;
49080 +}
49081 --- /dev/null
49082 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49083 @@ -0,0 +1,316 @@
49084 +/*
49085 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49086 + *
49087 + * Redistribution and use in source and binary forms, with or without
49088 + * modification, are permitted provided that the following conditions are met:
49089 + * * Redistributions of source code must retain the above copyright
49090 + * notice, this list of conditions and the following disclaimer.
49091 + * * Redistributions in binary form must reproduce the above copyright
49092 + * notice, this list of conditions and the following disclaimer in the
49093 + * documentation and/or other materials provided with the distribution.
49094 + * * Neither the name of Freescale Semiconductor nor the
49095 + * names of its contributors may be used to endorse or promote products
49096 + * derived from this software without specific prior written permission.
49097 + *
49098 + *
49099 + * ALTERNATIVELY, this software may be distributed under the terms of the
49100 + * GNU General Public License ("GPL") as published by the Free Software
49101 + * Foundation, either version 2 of that License or (at your option) any
49102 + * later version.
49103 + *
49104 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49105 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49106 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49107 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49108 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49109 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49110 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49111 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49112 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49113 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49114 + */
49115 +
49116 +
49117 +/******************************************************************************
49118 + @File fm_prs.h
49119 +
49120 + @Description FM Parser private header
49121 + *//***************************************************************************/
49122 +#ifndef __FM_PRS_H
49123 +#define __FM_PRS_H
49124 +
49125 +#include "std_ext.h"
49126 +
49127 +/***********************************************************************/
49128 +/* SW parser IP_FRAG patch */
49129 +/***********************************************************************/
49130 +
49131 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49132 +#define SW_PRS_UDP_LITE_PATCH \
49133 +{\
49134 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49135 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
49136 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
49137 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49138 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
49139 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49140 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
49141 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49142 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49143 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49144 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49145 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
49146 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
49147 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
49148 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49149 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49150 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
49151 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
49152 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
49153 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
49154 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
49155 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49156 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
49157 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49158 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49159 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49160 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49161 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
49162 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
49163 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
49164 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
49165 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
49166 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
49167 + 0x00,0x01,0x1B,0xFF \
49168 +}
49169 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
49170 +
49171 +#if (DPAA_VERSION == 10)
49172 +/* Version: 106.1.9 */
49173 +#define SW_PRS_OFFLOAD_PATCH \
49174 +{ \
49175 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
49176 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49177 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
49178 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
49179 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49180 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
49181 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
49182 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
49183 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
49184 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
49185 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
49186 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
49187 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
49188 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
49189 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
49190 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49191 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49192 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49193 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
49194 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49195 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
49196 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49197 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49198 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
49199 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
49200 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
49201 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
49202 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49203 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
49204 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
49205 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
49206 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
49207 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49208 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49209 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
49210 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
49211 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
49212 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
49213 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49214 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49215 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
49216 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
49217 +}
49218 +
49219 +#else
49220 +#define SW_PRS_OFFLOAD_PATCH \
49221 +{ \
49222 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
49223 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
49224 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
49225 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
49226 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
49227 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
49228 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
49229 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
49230 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
49231 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
49232 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
49233 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49234 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49235 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
49236 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49237 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
49238 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
49239 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49240 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
49241 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49242 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
49243 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49244 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49245 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49246 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49247 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
49248 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
49249 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
49250 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49251 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49252 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
49253 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
49254 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
49255 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
49256 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
49257 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
49258 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49259 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
49260 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
49261 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49262 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
49263 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
49264 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49265 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
49266 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49267 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49268 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
49269 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
49270 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
49271 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
49272 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49273 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49274 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
49275 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49276 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
49277 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49278 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
49279 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49280 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49281 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
49282 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49283 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
49284 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
49285 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49286 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
49287 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49288 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
49289 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
49290 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49291 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49292 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
49293 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
49294 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
49295 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
49296 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
49297 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
49298 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
49299 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
49300 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
49301 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
49302 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
49303 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
49304 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
49305 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
49306 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
49307 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
49308 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
49309 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
49310 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
49311 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
49312 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
49313 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
49314 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
49315 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
49316 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
49317 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
49318 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
49319 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
49320 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
49321 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
49322 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
49323 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49324 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
49325 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
49326 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49327 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
49328 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
49329 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49330 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
49331 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49332 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49333 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49334 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49335 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
49336 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49337 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
49338 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49339 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
49340 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49341 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49342 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
49343 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49344 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
49345 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
49346 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49347 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
49348 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49349 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
49350 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
49351 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49352 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49353 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
49354 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
49355 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
49356 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
49357 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
49358 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
49359 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
49360 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
49361 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
49362 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
49363 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
49364 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
49365 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
49366 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
49367 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
49368 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
49369 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
49370 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49371 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49372 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
49373 +}
49374 +#endif /* (DPAA_VERSION == 10) */
49375 +
49376 +/****************************/
49377 +/* Parser defines */
49378 +/****************************/
49379 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
49380 + the end of the SW parser area */
49381 +
49382 +/* masks */
49383 +#define PRS_ERR_CAP 0x80000000
49384 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
49385 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
49386 +#define PRS_ERR_ADDR_MASK 0x000001FF
49387 +
49388 +/* others */
49389 +#define PRS_MAX_CYCLE_LIMIT 8191
49390 +#define PRS_SW_DATA 0x00000800
49391 +#define PRS_REGS_OFFSET 0x00000840
49392 +
49393 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
49394 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
49395 +
49396 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
49397 + bitMask = 0x80000000>>prsPortId
49398 +
49399 +#endif /* __FM_PRS_H */
49400 --- /dev/null
49401 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49402 @@ -0,0 +1,984 @@
49403 +/*
49404 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49405 + *
49406 + * Redistribution and use in source and binary forms, with or without
49407 + * modification, are permitted provided that the following conditions are met:
49408 + * * Redistributions of source code must retain the above copyright
49409 + * notice, this list of conditions and the following disclaimer.
49410 + * * Redistributions in binary form must reproduce the above copyright
49411 + * notice, this list of conditions and the following disclaimer in the
49412 + * documentation and/or other materials provided with the distribution.
49413 + * * Neither the name of Freescale Semiconductor nor the
49414 + * names of its contributors may be used to endorse or promote products
49415 + * derived from this software without specific prior written permission.
49416 + *
49417 + *
49418 + * ALTERNATIVELY, this software may be distributed under the terms of the
49419 + * GNU General Public License ("GPL") as published by the Free Software
49420 + * Foundation, either version 2 of that License or (at your option) any
49421 + * later version.
49422 + *
49423 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49424 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49425 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49426 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49427 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49428 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49429 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49430 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49431 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49432 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49433 + */
49434 +
49435 +
49436 +/******************************************************************************
49437 + @File fm_replic.c
49438 +
49439 + @Description FM frame replicator
49440 +*//***************************************************************************/
49441 +#include "std_ext.h"
49442 +#include "error_ext.h"
49443 +#include "string_ext.h"
49444 +#include "debug_ext.h"
49445 +#include "fm_pcd_ext.h"
49446 +#include "fm_muram_ext.h"
49447 +#include "fm_common.h"
49448 +#include "fm_hc.h"
49449 +#include "fm_replic.h"
49450 +#include "fm_cc.h"
49451 +#include "list_ext.h"
49452 +
49453 +
49454 +/****************************************/
49455 +/* static functions */
49456 +/****************************************/
49457 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49458 + uint32_t memberIndex,
49459 + bool isAddOperation)
49460 +{
49461 + uint8_t memberPosition;
49462 + uint32_t lastMemberIndex;
49463 +
49464 + ASSERT_COND(p_ReplicGroup);
49465 +
49466 + /* the last member index is different between add and remove operation -
49467 + in case of remove - this is exactly the last member index
49468 + in case of add - this is the last member index + 1 - e.g.
49469 + if we have 4 members, the index of the actual last member is 3(because the
49470 + index starts from 0) therefore in order to add a new member as the last
49471 + member we shall use memberIndex = 4 and not 3
49472 + */
49473 + if (isAddOperation)
49474 + lastMemberIndex = p_ReplicGroup->numOfEntries;
49475 + else
49476 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
49477 +
49478 + /* last */
49479 + if (memberIndex == lastMemberIndex)
49480 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
49481 + else
49482 + {
49483 + /* first */
49484 + if (memberIndex == 0)
49485 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
49486 + else
49487 + {
49488 + /* middle */
49489 + ASSERT_COND(memberIndex < lastMemberIndex);
49490 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
49491 + }
49492 + }
49493 + return memberPosition;
49494 +}
49495 +
49496 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
49497 + t_FmPcdCcNextEngineParams *p_MemberParams)
49498 +{
49499 + t_Error err;
49500 +
49501 +
49502 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
49503 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
49504 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
49505 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
49506 +
49507 + /* check the regular parameters of the next engine */
49508 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
49509 + if (err)
49510 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
49511 +
49512 + return E_OK;
49513 +}
49514 +
49515 +static t_Error CheckParams(t_Handle h_FmPcd,
49516 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
49517 +{
49518 + int i;
49519 + t_Error err;
49520 +
49521 + /* check that max num of entries is at least 2 */
49522 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
49523 + 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));
49524 +
49525 + /* check that number of entries is greater than zero */
49526 + if (!p_ReplicGroupParam->numOfEntries)
49527 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
49528 +
49529 + /* check that max num of entries is equal or greater than number of entries */
49530 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
49531 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
49532 +
49533 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
49534 + {
49535 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
49536 + if (err)
49537 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
49538 + }
49539 + return E_OK;
49540 +}
49541 +
49542 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49543 +{
49544 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
49545 + t_List *p_Next;
49546 +
49547 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
49548 + {
49549 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
49550 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
49551 + ASSERT_COND(p_ReplicMember);
49552 + LIST_DelAndInit(p_Next);
49553 + }
49554 + return p_ReplicMember;
49555 +}
49556 +
49557 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49558 + t_FmPcdFrmReplicMember *p_ReplicMember)
49559 +{
49560 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
49561 +}
49562 +
49563 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49564 + t_FmPcdFrmReplicMember *p_CurrentMember,
49565 + t_List *p_ListHead)
49566 +{
49567 + LIST_Add(&p_CurrentMember->node, p_ListHead);
49568 +
49569 + p_ReplicGroup->numOfEntries++;
49570 +}
49571 +
49572 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49573 + t_FmPcdFrmReplicMember *p_CurrentMember)
49574 +{
49575 + ASSERT_COND(p_ReplicGroup->numOfEntries);
49576 + LIST_DelAndInit(&p_CurrentMember->node);
49577 + p_ReplicGroup->numOfEntries--;
49578 +}
49579 +
49580 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49581 + t_AdOfTypeContLookup *p_SourceTd,
49582 + t_FmPcdFrmReplicMember *p_ReplicMember)
49583 +{
49584 + t_FmPcd *p_FmPcd;
49585 +
49586 + ASSERT_COND(p_SourceTd);
49587 + ASSERT_COND(p_ReplicMember);
49588 + ASSERT_COND(p_ReplicGroup);
49589 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49590 +
49591 + /* Link the first member in the group to the source TD */
49592 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49593 +
49594 + WRITE_UINT32(p_SourceTd->matchTblPtr,
49595 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
49596 + p_FmPcd->physicalMuramBase));
49597 +}
49598 +
49599 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49600 + t_FmPcdFrmReplicMember *p_CurrentMember,
49601 + t_FmPcdFrmReplicMember *p_NextMember)
49602 +{
49603 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
49604 + t_AdOfTypeResult *p_NextReplicAd = NULL;
49605 + t_FmPcd *p_FmPcd;
49606 + uint32_t offset = 0;
49607 +
49608 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
49609 + if (p_NextMember)
49610 + {
49611 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
49612 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49613 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
49614 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
49615 + }
49616 +
49617 + /* link the current AD to point to the AD of the next member */
49618 + WRITE_UINT32(p_CurrReplicAd->res, offset);
49619 +}
49620 +
49621 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49622 + void *p_OldDescriptor,
49623 + void *p_NewDescriptor)
49624 +{
49625 + t_Handle h_Hc;
49626 + t_Error err;
49627 + t_FmPcd *p_FmPcd;
49628 +
49629 + ASSERT_COND(p_ReplicGroup);
49630 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49631 + ASSERT_COND(p_OldDescriptor);
49632 + ASSERT_COND(p_NewDescriptor);
49633 +
49634 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49635 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
49636 + if (!h_Hc)
49637 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
49638 +
49639 + err = FmHcPcdCcDoDynamicChange(h_Hc,
49640 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
49641 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
49642 + if (err)
49643 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
49644 +
49645 + return E_OK;
49646 +}
49647 +
49648 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
49649 +{
49650 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
49651 + uint32_t tmp;
49652 +
49653 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
49654 + if (last)
49655 + /* clear the NL bit in case it's the last member in the group*/
49656 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
49657 + else
49658 + /* set the NL bit in case it's not the last member in the group */
49659 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
49660 +
49661 + /* set FR bit in the action descriptor */
49662 + tmp = GET_UINT32(p_CurrReplicAd->nia);
49663 + WRITE_UINT32(p_CurrReplicAd->nia,
49664 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
49665 +}
49666 +
49667 +static void BuildSourceTd(void *p_Ad)
49668 +{
49669 + t_AdOfTypeContLookup *p_SourceTd;
49670 +
49671 + ASSERT_COND(p_Ad);
49672 +
49673 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
49674 +
49675 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49676 +
49677 + /* initialize the source table descriptor */
49678 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
49679 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
49680 +}
49681 +
49682 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49683 + t_FmPcdFrmReplicMember *p_NextMember,
49684 + t_FmPcdFrmReplicMember *p_CurrentMember,
49685 + bool sourceDescriptor,
49686 + bool last)
49687 +{
49688 + t_FmPcd *p_FmPcd;
49689 + t_FmPcdFrmReplicMember shadowMember;
49690 + t_Error err;
49691 +
49692 + ASSERT_COND(p_ReplicGroup);
49693 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49694 +
49695 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49696 + ASSERT_COND(p_FmPcd->p_CcShadow);
49697 +
49698 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
49699 + return ERROR_CODE(E_BUSY);
49700 +
49701 + if (sourceDescriptor)
49702 + {
49703 + BuildSourceTd(p_FmPcd->p_CcShadow);
49704 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
49705 +
49706 + /* Modify the source table descriptor according to the prepared shadow descriptor */
49707 + err = ModifyDescriptor(p_ReplicGroup,
49708 + p_ReplicGroup->p_SourceTd,
49709 + p_FmPcd->p_CcShadow/* new prepared source td */);
49710 +
49711 + RELEASE_LOCK(p_FmPcd->shadowLock);
49712 + if (err)
49713 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
49714 +
49715 + }
49716 + else
49717 + {
49718 + IO2IOCpy32(p_FmPcd->p_CcShadow,
49719 + p_CurrentMember->p_MemberAd,
49720 + FM_PCD_CC_AD_ENTRY_SIZE);
49721 +
49722 + /* update the last bit in the shadow ad */
49723 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
49724 +
49725 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
49726 +
49727 + /* update the next FR member index */
49728 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
49729 +
49730 + /* Modify the next member according to the prepared shadow descriptor */
49731 + err = ModifyDescriptor(p_ReplicGroup,
49732 + p_CurrentMember->p_MemberAd,
49733 + p_FmPcd->p_CcShadow);
49734 +
49735 + RELEASE_LOCK(p_FmPcd->shadowLock);
49736 + if (err)
49737 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
49738 + }
49739 +
49740 +
49741 + return E_OK;
49742 +}
49743 +
49744 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49745 + uint16_t memberIndex)
49746 +{
49747 + int i=0;
49748 + t_List *p_Pos;
49749 + t_FmPcdFrmReplicMember *p_Member = NULL;
49750 +
49751 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
49752 + {
49753 + if (i == memberIndex)
49754 + {
49755 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
49756 + return p_Member;
49757 + }
49758 + i++;
49759 + }
49760 + return p_Member;
49761 +}
49762 +
49763 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49764 +{
49765 + t_FmPcdFrmReplicMember *p_CurrentMember;
49766 + t_Handle h_Muram;
49767 +
49768 + ASSERT_COND(p_ReplicGroup);
49769 +
49770 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
49771 + ASSERT_COND(h_Muram);
49772 +
49773 + /* Initialize an internal structure of a member to add to the available members list */
49774 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
49775 + if (!p_CurrentMember)
49776 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
49777 +
49778 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
49779 +
49780 + /* Allocate the member AD */
49781 + p_CurrentMember->p_MemberAd =
49782 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
49783 + FM_PCD_CC_AD_ENTRY_SIZE,
49784 + FM_PCD_CC_AD_TABLE_ALIGN);
49785 + if (!p_CurrentMember->p_MemberAd)
49786 + {
49787 + XX_Free(p_CurrentMember);
49788 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
49789 + }
49790 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49791 +
49792 + /* Add the new member to the available members list */
49793 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
49794 +
49795 + return E_OK;
49796 +}
49797 +
49798 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49799 + t_FmPcdCcNextEngineParams *p_MemberParams,
49800 + bool last)
49801 +{
49802 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
49803 +
49804 + ASSERT_COND(p_ReplicGroup);
49805 +
49806 + /* Get an available member from the internal members list */
49807 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
49808 + if (!p_CurrentMember)
49809 + {
49810 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
49811 + return NULL;
49812 + }
49813 + p_CurrentMember->h_Manip = NULL;
49814 +
49815 + /* clear the Ad of the new member */
49816 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49817 +
49818 + INIT_LIST(&p_CurrentMember->node);
49819 +
49820 + /* Initialize the Ad of the member */
49821 + NextStepAd(p_CurrentMember->p_MemberAd,
49822 + NULL,
49823 + p_MemberParams,
49824 + p_ReplicGroup->h_FmPcd);
49825 +
49826 + /* save Manip handle (for free needs) */
49827 + if (p_MemberParams->h_Manip)
49828 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
49829 +
49830 + /* Initialize the relevant frame replicator fields in the AD */
49831 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
49832 +
49833 + return p_CurrentMember;
49834 +}
49835 +
49836 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49837 + t_FmPcdFrmReplicMember *p_Member)
49838 +{
49839 + /* Note: Can't free the member AD just returns the member to the available
49840 + member list - therefore only memset the AD */
49841 +
49842 + /* zero the AD */
49843 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
49844 +
49845 +
49846 + /* return the member to the available members list */
49847 + PutAvailableMember(p_ReplicGroup, p_Member);
49848 +}
49849 +
49850 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49851 + uint16_t memberIndex)
49852 +{
49853 + t_FmPcd *p_FmPcd = NULL;
49854 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
49855 + t_Error err;
49856 + uint8_t memberPosition;
49857 +
49858 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49859 + ASSERT_COND(p_FmPcd);
49860 + UNUSED(p_FmPcd);
49861 +
49862 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
49863 + ASSERT_COND(p_CurrentMember);
49864 +
49865 + /* determine the member position in the group */
49866 + memberPosition = GetMemberPosition(p_ReplicGroup,
49867 + memberIndex,
49868 + FALSE/*remove operation*/);
49869 +
49870 + switch (memberPosition)
49871 + {
49872 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
49873 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
49874 + ASSERT_COND(p_NextMember);
49875 +
49876 + /* update the source td itself by using a host command */
49877 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
49878 + p_NextMember,
49879 + NULL,
49880 + TRUE/*sourceDescriptor*/,
49881 + FALSE/*last*/);
49882 + break;
49883 +
49884 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
49885 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
49886 + ASSERT_COND(p_PreviousMember);
49887 +
49888 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
49889 + ASSERT_COND(p_NextMember);
49890 +
49891 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
49892 + p_NextMember,
49893 + p_PreviousMember,
49894 + FALSE/*sourceDescriptor*/,
49895 + FALSE/*last*/);
49896 +
49897 + break;
49898 +
49899 + case FRM_REPLIC_LAST_MEMBER_INDEX:
49900 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
49901 + ASSERT_COND(p_PreviousMember);
49902 +
49903 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
49904 + NULL,
49905 + p_PreviousMember,
49906 + FALSE/*sourceDescriptor*/,
49907 + TRUE/*last*/);
49908 + break;
49909 +
49910 + default:
49911 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
49912 + }
49913 +
49914 + if (err)
49915 + RETURN_ERROR(MAJOR, err, NO_MSG);
49916 +
49917 + if (p_CurrentMember->h_Manip)
49918 + {
49919 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
49920 + p_CurrentMember->h_Manip = NULL;
49921 + }
49922 +
49923 + /* remove the member from the driver internal members list */
49924 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
49925 +
49926 + /* return the member to the available members list */
49927 + FreeMember(p_ReplicGroup, p_CurrentMember);
49928 +
49929 + return E_OK;
49930 +}
49931 +
49932 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49933 +{
49934 + int i, j;
49935 + t_Handle h_Muram;
49936 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
49937 +
49938 + if (p_ReplicGroup)
49939 + {
49940 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49941 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
49942 + ASSERT_COND(h_Muram);
49943 +
49944 + /* free the source table descriptor */
49945 + if (p_ReplicGroup->p_SourceTd)
49946 + {
49947 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
49948 + p_ReplicGroup->p_SourceTd = NULL;
49949 + }
49950 +
49951 + /* Remove all members from the members linked list (hw and sw) and
49952 + return the members to the available members list */
49953 + if (p_ReplicGroup->numOfEntries)
49954 + {
49955 + j = p_ReplicGroup->numOfEntries-1;
49956 +
49957 + /* manually removal of the member because there are no owners of
49958 + this group */
49959 + for (i=j; i>=0; i--)
49960 + {
49961 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
49962 + ASSERT_COND(p_CurrentMember);
49963 +
49964 + if (p_CurrentMember->h_Manip)
49965 + {
49966 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
49967 + p_CurrentMember->h_Manip = NULL;
49968 + }
49969 +
49970 + /* remove the member from the internal driver members list */
49971 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
49972 +
49973 + /* return the member to the available members list */
49974 + FreeMember(p_ReplicGroup, p_CurrentMember);
49975 + }
49976 + }
49977 +
49978 + /* Free members AD */
49979 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
49980 + {
49981 + p_Member = GetAvailableMember(p_ReplicGroup);
49982 + ASSERT_COND(p_Member);
49983 + if (p_Member->p_MemberAd)
49984 + {
49985 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
49986 + p_Member->p_MemberAd = NULL;
49987 + }
49988 + XX_Free(p_Member);
49989 + }
49990 +
49991 + /* release the group lock */
49992 + if (p_ReplicGroup->p_Lock)
49993 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
49994 +
49995 + /* free the replicator group */
49996 + XX_Free(p_ReplicGroup);
49997 + }
49998 +}
49999 +
50000 +
50001 +/*****************************************************************************/
50002 +/* Inter-module API routines */
50003 +/*****************************************************************************/
50004 +
50005 +/* NOTE: the inter-module routines are locked by cc in case of using them */
50006 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
50007 +{
50008 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50009 + ASSERT_COND(p_ReplicGroup);
50010 +
50011 + return (p_ReplicGroup->p_SourceTd);
50012 +}
50013 +
50014 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
50015 + void *p_Ad,
50016 + t_Handle *h_AdNew)
50017 +{
50018 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50019 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
50020 + t_FmPcd *p_FmPcd;
50021 +
50022 + ASSERT_COND(p_ReplicGroup);
50023 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50024 +
50025 + /* build a bypass ad */
50026 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
50027 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
50028 +
50029 + *h_AdNew = NULL;
50030 +}
50031 +
50032 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
50033 + bool add)
50034 +{
50035 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50036 + ASSERT_COND(p_ReplicGroup);
50037 +
50038 + /* update the group owner counter */
50039 + if (add)
50040 + p_ReplicGroup->owners++;
50041 + else
50042 + {
50043 + ASSERT_COND(p_ReplicGroup->owners);
50044 + p_ReplicGroup->owners--;
50045 + }
50046 +}
50047 +
50048 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
50049 +{
50050 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50051 +
50052 + ASSERT_COND(h_ReplicGroup);
50053 +
50054 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
50055 + return E_OK;
50056 +
50057 + return ERROR_CODE(E_BUSY);
50058 +}
50059 +
50060 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
50061 +{
50062 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50063 +
50064 + ASSERT_COND(h_ReplicGroup);
50065 +
50066 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
50067 +}
50068 +/*********************** End of inter-module routines ************************/
50069 +
50070 +
50071 +/****************************************/
50072 +/* API Init unit functions */
50073 +/****************************************/
50074 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
50075 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
50076 +{
50077 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
50078 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
50079 + int i;
50080 + t_Error err;
50081 + bool last = FALSE;
50082 + t_Handle h_Muram;
50083 +
50084 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50085 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
50086 +
50087 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
50088 + {
50089 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
50090 + return NULL;
50091 + }
50092 +
50093 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
50094 + if (err)
50095 + {
50096 + REPORT_ERROR(MAJOR, err, (NO_MSG));
50097 + return NULL;
50098 + }
50099 +
50100 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
50101 + if (!p_ReplicGroup)
50102 + {
50103 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
50104 + return NULL;
50105 + }
50106 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
50107 +
50108 + /* initialize lists for internal driver use */
50109 + INIT_LIST(&p_ReplicGroup->availableMembersList);
50110 + INIT_LIST(&p_ReplicGroup->membersList);
50111 +
50112 + p_ReplicGroup->h_FmPcd = h_FmPcd;
50113 +
50114 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50115 + ASSERT_COND(h_Muram);
50116 +
50117 + /* initialize the group lock */
50118 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
50119 + if (!p_ReplicGroup->p_Lock)
50120 + {
50121 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
50122 + DeleteGroup(p_ReplicGroup);
50123 + return NULL;
50124 + }
50125 +
50126 + /* Allocate the frame replicator source table descriptor */
50127 + p_ReplicGroup->p_SourceTd =
50128 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
50129 + FM_PCD_CC_AD_ENTRY_SIZE,
50130 + FM_PCD_CC_AD_TABLE_ALIGN);
50131 + if (!p_ReplicGroup->p_SourceTd)
50132 + {
50133 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
50134 + DeleteGroup(p_ReplicGroup);
50135 + return NULL;
50136 + }
50137 +
50138 + /* update the shadow size - required for the host commands */
50139 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
50140 + FM_PCD_CC_AD_ENTRY_SIZE,
50141 + FM_PCD_CC_AD_TABLE_ALIGN);
50142 + if (err)
50143 + {
50144 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
50145 + DeleteGroup(p_ReplicGroup);
50146 + return NULL;
50147 + }
50148 +
50149 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
50150 +
50151 + /* Allocate the maximal number of members ADs and Statistics AD for the group
50152 + It prevents allocation of Muram in run-time */
50153 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50154 + {
50155 + err = AllocMember(p_ReplicGroup);
50156 + if (err)
50157 + {
50158 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
50159 + DeleteGroup(p_ReplicGroup);
50160 + return NULL;
50161 + }
50162 + }
50163 +
50164 + /* Initialize the members linked lists:
50165 + (hw - the one that is used by the FMan controller and
50166 + sw - the one that is managed by the driver internally) */
50167 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
50168 + {
50169 + /* check if this is the last member in the group */
50170 + if (i == (p_ReplicGroupParam->numOfEntries-1))
50171 + last = TRUE;
50172 + else
50173 + last = FALSE;
50174 +
50175 + /* Initialize a new member */
50176 + p_CurrentMember = InitMember(p_ReplicGroup,
50177 + &(p_ReplicGroupParam->nextEngineParams[i]),
50178 + last);
50179 + if (!p_CurrentMember)
50180 + {
50181 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50182 + DeleteGroup(p_ReplicGroup);
50183 + return NULL;
50184 + }
50185 +
50186 + /* Build the members group - link two consecutive members in the hw linked list */
50187 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
50188 +
50189 + /* update the driver internal members list to be compatible to the hw members linked list */
50190 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
50191 +
50192 + p_NextMember = p_CurrentMember;
50193 + }
50194 +
50195 + /* initialize the source table descriptor */
50196 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
50197 +
50198 + /* link the source table descriptor to point to the first member in the group */
50199 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
50200 +
50201 + return p_ReplicGroup;
50202 +}
50203 +
50204 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
50205 +{
50206 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50207 +
50208 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50209 +
50210 + if (p_ReplicGroup->owners)
50211 + RETURN_ERROR(MAJOR,
50212 + E_INVALID_STATE,
50213 + ("the group has owners and can't be deleted"));
50214 +
50215 + DeleteGroup(p_ReplicGroup);
50216 +
50217 + return E_OK;
50218 +}
50219 +
50220 +
50221 +/*****************************************************************************/
50222 +/* API Run-time Frame replicator Control unit functions */
50223 +/*****************************************************************************/
50224 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
50225 + uint16_t memberIndex,
50226 + t_FmPcdCcNextEngineParams *p_MemberParams)
50227 +{
50228 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50229 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
50230 + t_Error err;
50231 + uint8_t memberPosition;
50232 +
50233 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50234 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
50235 +
50236 + /* group lock */
50237 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50238 + if (GET_ERROR_TYPE(err) == E_BUSY)
50239 + return ERROR_CODE(E_BUSY);
50240 +
50241 + if (memberIndex > p_ReplicGroup->numOfEntries)
50242 + {
50243 + /* unlock */
50244 + FrmReplicGroupUnlock(p_ReplicGroup);
50245 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
50246 + ("memberIndex is greater than the members in the list"));
50247 + }
50248 +
50249 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
50250 + {
50251 + /* unlock */
50252 + FrmReplicGroupUnlock(p_ReplicGroup);
50253 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
50254 + }
50255 +
50256 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
50257 + {
50258 + /* unlock */
50259 + FrmReplicGroupUnlock(p_ReplicGroup);
50260 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
50261 + ("numOfEntries with new entry can not be larger than %d\n",
50262 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
50263 + }
50264 +
50265 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
50266 + if (err)
50267 + {
50268 + /* unlock */
50269 + FrmReplicGroupUnlock(p_ReplicGroup);
50270 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
50271 + }
50272 + /* determine the member position in the group */
50273 + memberPosition = GetMemberPosition(p_ReplicGroup,
50274 + memberIndex,
50275 + TRUE/* add operation */);
50276 +
50277 + /* Initialize a new member */
50278 + p_NewMember = InitMember(p_ReplicGroup,
50279 + p_MemberParams,
50280 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
50281 + if (!p_NewMember)
50282 + {
50283 + /* unlock */
50284 + FrmReplicGroupUnlock(p_ReplicGroup);
50285 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50286 + }
50287 +
50288 + switch (memberPosition)
50289 + {
50290 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50291 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50292 + ASSERT_COND(p_CurrentMember);
50293 +
50294 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50295 +
50296 + /* update the internal group source TD */
50297 + LinkSourceToMember(p_ReplicGroup,
50298 + p_ReplicGroup->p_SourceTd,
50299 + p_NewMember);
50300 +
50301 + /* add member to the internal sw member list */
50302 + AddMemberToList(p_ReplicGroup,
50303 + p_NewMember,
50304 + &p_ReplicGroup->membersList);
50305 + break;
50306 +
50307 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50308 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50309 + ASSERT_COND(p_CurrentMember);
50310 +
50311 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50312 + ASSERT_COND(p_PreviousMember);
50313 +
50314 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50315 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50316 +
50317 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50318 + break;
50319 +
50320 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50321 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50322 + ASSERT_COND(p_PreviousMember);
50323 +
50324 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50325 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
50326 +
50327 + /* add the new member to the internal sw member list */
50328 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50329 + break;
50330 +
50331 + default:
50332 + /* unlock */
50333 + FrmReplicGroupUnlock(p_ReplicGroup);
50334 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
50335 +
50336 + }
50337 +
50338 + /* unlock */
50339 + FrmReplicGroupUnlock(p_ReplicGroup);
50340 +
50341 + return E_OK;
50342 +}
50343 +
50344 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
50345 + uint16_t memberIndex)
50346 +{
50347 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50348 + t_Error err;
50349 +
50350 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50351 +
50352 + /* lock */
50353 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50354 + if (GET_ERROR_TYPE(err) == E_BUSY)
50355 + return ERROR_CODE(E_BUSY);
50356 +
50357 + if (memberIndex >= p_ReplicGroup->numOfEntries)
50358 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
50359 +
50360 + /* Design decision: group must contain at least one member
50361 + No possibility to remove the last member from the group */
50362 + if (p_ReplicGroup->numOfEntries == 1)
50363 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
50364 +
50365 + err = RemoveMember(p_ReplicGroup, memberIndex);
50366 +
50367 + /* unlock */
50368 + FrmReplicGroupUnlock(p_ReplicGroup);
50369 +
50370 + switch (GET_ERROR_TYPE(err))
50371 + {
50372 + case E_OK:
50373 + return E_OK;
50374 +
50375 + case E_BUSY:
50376 + DBG(TRACE, ("E_BUSY error"));
50377 + return ERROR_CODE(E_BUSY);
50378 +
50379 + default:
50380 + RETURN_ERROR(MAJOR, err, NO_MSG);
50381 + }
50382 +}
50383 +
50384 +/*********************** End of API routines ************************/
50385 +
50386 +
50387 --- /dev/null
50388 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50389 @@ -0,0 +1,101 @@
50390 +/*
50391 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50392 + *
50393 + * Redistribution and use in source and binary forms, with or without
50394 + * modification, are permitted provided that the following conditions are met:
50395 + * * Redistributions of source code must retain the above copyright
50396 + * notice, this list of conditions and the following disclaimer.
50397 + * * Redistributions in binary form must reproduce the above copyright
50398 + * notice, this list of conditions and the following disclaimer in the
50399 + * documentation and/or other materials provided with the distribution.
50400 + * * Neither the name of Freescale Semiconductor nor the
50401 + * names of its contributors may be used to endorse or promote products
50402 + * derived from this software without specific prior written permission.
50403 + *
50404 + *
50405 + * ALTERNATIVELY, this software may be distributed under the terms of the
50406 + * GNU General Public License ("GPL") as published by the Free Software
50407 + * Foundation, either version 2 of that License or (at your option) any
50408 + * later version.
50409 + *
50410 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50411 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50412 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50413 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50414 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50415 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50416 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50417 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50418 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50419 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50420 + */
50421 +
50422 +
50423 +/******************************************************************************
50424 + @File fm_replic.h
50425 +
50426 + @Description FM frame replicator
50427 +*//***************************************************************************/
50428 +#ifndef __FM_REPLIC_H
50429 +#define __FM_REPLIC_H
50430 +
50431 +#include "std_ext.h"
50432 +#include "error_ext.h"
50433 +
50434 +
50435 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
50436 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
50437 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
50438 +#define FRM_REPLIC_FR_BIT 0x08000000
50439 +#define FRM_REPLIC_NL_BIT 0x10000000
50440 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
50441 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
50442 +
50443 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
50444 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
50445 +
50446 +#define SOURCE_TD_ITSELF_OPTION 0x01
50447 +#define SOURCE_TD_COPY_OPTION 0x02
50448 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
50449 +#define SOURCE_TD_NONE 0x04
50450 +
50451 +/*typedef enum e_SourceTdOption
50452 +{
50453 + e_SOURCE_TD_NONE = 0,
50454 + e_SOURCE_TD_ITSELF_OPTION = 1,
50455 + e_SOURCE_TD_COPY_OPTION = 2,
50456 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
50457 +} e_SourceTdOption;
50458 +*/
50459 +
50460 +typedef struct
50461 +{
50462 + volatile uint32_t type;
50463 + volatile uint32_t frGroupPointer;
50464 + volatile uint32_t operationCode;
50465 + volatile uint32_t reserved;
50466 +} t_FrmReplicGroupSourceAd;
50467 +
50468 +typedef struct t_FmPcdFrmReplicMember
50469 +{
50470 + void *p_MemberAd; /**< pointer to the member AD */
50471 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
50472 + t_Handle h_Manip; /**< manip handle - need for free routines */
50473 + t_List node;
50474 +} t_FmPcdFrmReplicMember;
50475 +
50476 +typedef struct t_FmPcdFrmReplicGroup
50477 +{
50478 + t_Handle h_FmPcd;
50479 +
50480 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
50481 + uint8_t numOfEntries; /**< actual number of members in the group */
50482 + uint16_t owners; /**< how many keys share this frame replicator group */
50483 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
50484 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
50485 + t_List availableMembersList;/**< list of all the available members in the group */
50486 + t_FmPcdLock *p_Lock;
50487 +} t_FmPcdFrmReplicGroup;
50488 +
50489 +
50490 +#endif /* __FM_REPLIC_H */
50491 --- /dev/null
50492 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50493 @@ -0,0 +1,888 @@
50494 +/*
50495 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50496 + *
50497 + * Redistribution and use in source and binary forms, with or without
50498 + * modification, are permitted provided that the following conditions are met:
50499 + * * Redistributions of source code must retain the above copyright
50500 + * notice, this list of conditions and the following disclaimer.
50501 + * * Redistributions in binary form must reproduce the above copyright
50502 + * notice, this list of conditions and the following disclaimer in the
50503 + * documentation and/or other materials provided with the distribution.
50504 + * * Neither the name of Freescale Semiconductor nor the
50505 + * names of its contributors may be used to endorse or promote products
50506 + * derived from this software without specific prior written permission.
50507 + *
50508 + *
50509 + * ALTERNATIVELY, this software may be distributed under the terms of the
50510 + * GNU General Public License ("GPL") as published by the Free Software
50511 + * Foundation, either version 2 of that License or (at your option) any
50512 + * later version.
50513 + *
50514 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50515 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50516 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50517 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50518 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50519 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50520 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50521 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50522 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50523 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50524 + */
50525 +
50526 +#include "fsl_fman_kg.h"
50527 +
50528 +/****************************************/
50529 +/* static functions */
50530 +/****************************************/
50531 +
50532 +
50533 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
50534 +{
50535 + uint32_t rw;
50536 +
50537 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50538 +
50539 + return (uint32_t)(FM_KG_KGAR_GO |
50540 + rw |
50541 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50542 + hwport_id |
50543 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
50544 +}
50545 +
50546 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
50547 +{
50548 + uint32_t ar;
50549 +
50550 + fman_kg_write_sp(regs, 0xffffffff, 0);
50551 +
50552 + ar = build_ar_bind_scheme(hwport_id, TRUE);
50553 + fman_kg_write_ar_wait(regs, ar);
50554 +}
50555 +
50556 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
50557 +{
50558 + uint32_t rw;
50559 +
50560 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50561 +
50562 + return (uint32_t)(FM_KG_KGAR_GO |
50563 + rw |
50564 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50565 + hwport_id |
50566 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
50567 +}
50568 +
50569 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
50570 +{
50571 + uint32_t ar;
50572 +
50573 + fman_kg_write_cpp(regs, 0);
50574 +
50575 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
50576 + fman_kg_write_ar_wait(regs, ar);
50577 +}
50578 +
50579 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
50580 + bool no_validation,
50581 + uint8_t *offset)
50582 +{
50583 + int code;
50584 +
50585 + switch (src) {
50586 + case E_FMAN_KG_GEN_EXTRACT_ETH:
50587 + code = no_validation ? 0x73 : 0x3;
50588 + break;
50589 +
50590 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
50591 + code = no_validation ? 0x77 : 0x7;
50592 + break;
50593 +
50594 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
50595 + code = no_validation ? 0x74 : 0x4;
50596 + break;
50597 +
50598 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
50599 + code = no_validation ? 0x75 : 0x5;
50600 + break;
50601 +
50602 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
50603 + code = no_validation ? 0x76 : 0x6;
50604 + break;
50605 +
50606 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
50607 + code = no_validation ? 0x78 : 0x8;
50608 + break;
50609 +
50610 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
50611 + code = no_validation ? 0x79 : 0x9;
50612 + break;
50613 +
50614 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
50615 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
50616 + break;
50617 +
50618 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
50619 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
50620 + break;
50621 +
50622 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
50623 + code = no_validation ? 0x7a : 0xa;
50624 + break;
50625 +
50626 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
50627 + code = no_validation ? 0x7b : 0xb;
50628 + break;
50629 +
50630 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
50631 + code = no_validation ? 0x7b : 0x1b;
50632 + break;
50633 +
50634 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
50635 + code = no_validation ? 0x7c : 0xc;
50636 + break;
50637 +
50638 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
50639 + code = no_validation ? 0x7c : 0x1c;
50640 + break;
50641 +
50642 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
50643 + code = no_validation ? 0x7c : 0x2c;
50644 + break;
50645 +
50646 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
50647 + code = no_validation ? 0x72 : 0x2;
50648 + break;
50649 +
50650 + case E_FMAN_KG_GEN_EXTRACT_GRE:
50651 + code = no_validation ? 0x7d : 0xd;
50652 + break;
50653 +
50654 + case E_FMAN_KG_GEN_EXTRACT_TCP:
50655 + code = no_validation ? 0x7e : 0xe;
50656 + break;
50657 +
50658 + case E_FMAN_KG_GEN_EXTRACT_UDP:
50659 + code = no_validation ? 0x7e : 0x1e;
50660 + break;
50661 +
50662 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
50663 + code = no_validation ? 0x7e : 0x3e;
50664 + break;
50665 +
50666 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
50667 + code = no_validation ? 0x7e : 0x4e;
50668 + break;
50669 +
50670 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
50671 + code = no_validation ? 0x7e : 0x2e;
50672 + break;
50673 +
50674 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
50675 + code = no_validation ? 0x7e : 0x6e;
50676 + break;
50677 +
50678 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
50679 + code = 0x70;
50680 + break;
50681 +
50682 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
50683 + code = 0x71;
50684 + break;
50685 +
50686 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
50687 + code = 0x10;
50688 + break;
50689 +
50690 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
50691 + code = 0x40;
50692 + break;
50693 +
50694 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
50695 + code = 0x20;
50696 + break;
50697 +
50698 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
50699 + code = 0x7f;
50700 + break;
50701 +
50702 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
50703 + code = 0x20;
50704 + *offset += 0x20;
50705 + break;
50706 +
50707 + default:
50708 + code = FM_KG_SCH_GEN_HT_INVALID;
50709 + }
50710 +
50711 + return (uint8_t)code;
50712 +}
50713 +
50714 +static uint32_t build_ar_scheme(uint8_t scheme,
50715 + uint8_t hwport_id,
50716 + bool update_counter,
50717 + bool write)
50718 +{
50719 + uint32_t rw;
50720 +
50721 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50722 +
50723 + return (uint32_t)(FM_KG_KGAR_GO |
50724 + rw |
50725 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
50726 + hwport_id |
50727 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
50728 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
50729 +}
50730 +
50731 +static uint32_t build_ar_cls_plan(uint8_t grp,
50732 + uint8_t entries_mask,
50733 + uint8_t hwport_id,
50734 + bool write)
50735 +{
50736 + uint32_t rw;
50737 +
50738 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
50739 +
50740 + return (uint32_t)(FM_KG_KGAR_GO |
50741 + rw |
50742 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
50743 + hwport_id |
50744 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
50745 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
50746 +}
50747 +
50748 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
50749 +{
50750 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
50751 + /* Wait for GO to be idle and read error */
50752 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
50753 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
50754 + return -EINVAL;
50755 + return 0;
50756 +}
50757 +
50758 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
50759 +{
50760 +
50761 + struct fman_kg_pe_regs *kgpe_regs;
50762 + uint32_t tmp;
50763 +
50764 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50765 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
50766 +
50767 + if (add)
50768 + tmp |= sp;
50769 + else /* clear */
50770 + tmp &= ~sp;
50771 +
50772 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
50773 +
50774 +}
50775 +
50776 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
50777 +{
50778 + struct fman_kg_pe_regs *kgpe_regs;
50779 +
50780 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
50781 +
50782 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
50783 +}
50784 +
50785 +void fman_kg_get_event(struct fman_kg_regs *regs,
50786 + uint32_t *event,
50787 + uint32_t *scheme_idx)
50788 +{
50789 + uint32_t mask, force;
50790 +
50791 + *event = ioread32be(&regs->fmkg_eer);
50792 + mask = ioread32be(&regs->fmkg_eeer);
50793 + *scheme_idx = ioread32be(&regs->fmkg_seer);
50794 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
50795 +
50796 + *event &= mask;
50797 +
50798 + /* clear the forced events */
50799 + force = ioread32be(&regs->fmkg_feer);
50800 + if (force & *event)
50801 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
50802 +
50803 + iowrite32be(*event, &regs->fmkg_eer);
50804 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
50805 +}
50806 +
50807 +
50808 +void fman_kg_init(struct fman_kg_regs *regs,
50809 + uint32_t exceptions,
50810 + uint32_t dflt_nia)
50811 +{
50812 + uint32_t tmp;
50813 + int i;
50814 +
50815 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
50816 + &regs->fmkg_eer);
50817 +
50818 + tmp = 0;
50819 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
50820 + tmp |= FM_EX_KG_DOUBLE_ECC;
50821 +
50822 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
50823 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
50824 +
50825 + iowrite32be(tmp, &regs->fmkg_eeer);
50826 + iowrite32be(0, &regs->fmkg_fdor);
50827 + iowrite32be(0, &regs->fmkg_gdv0r);
50828 + iowrite32be(0, &regs->fmkg_gdv1r);
50829 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
50830 +
50831 + /* Clear binding between ports to schemes and classification plans
50832 + * so that all ports are not bound to any scheme/classification plan */
50833 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
50834 + clear_pe_all_scheme(regs, (uint8_t)i);
50835 + clear_pe_all_cls_plan(regs, (uint8_t)i);
50836 + }
50837 +}
50838 +
50839 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
50840 +{
50841 + /* enable and enable all scheme interrupts */
50842 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
50843 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
50844 +}
50845 +
50846 +void fman_kg_enable(struct fman_kg_regs *regs)
50847 +{
50848 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
50849 + &regs->fmkg_gcr);
50850 +}
50851 +
50852 +void fman_kg_disable(struct fman_kg_regs *regs)
50853 +{
50854 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
50855 + &regs->fmkg_gcr);
50856 +}
50857 +
50858 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
50859 +{
50860 + iowrite32be(offset, &regs->fmkg_fdor);
50861 +}
50862 +
50863 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
50864 + uint8_t def_id,
50865 + uint32_t val)
50866 +{
50867 + if(def_id == 0)
50868 + iowrite32be(val, &regs->fmkg_gdv0r);
50869 + else
50870 + iowrite32be(val, &regs->fmkg_gdv1r);
50871 +}
50872 +
50873 +
50874 +void fman_kg_set_exception(struct fman_kg_regs *regs,
50875 + uint32_t exception,
50876 + bool enable)
50877 +{
50878 + uint32_t tmp;
50879 +
50880 + tmp = ioread32be(&regs->fmkg_eeer);
50881 +
50882 + if (enable) {
50883 + tmp |= exception;
50884 + } else {
50885 + tmp &= ~exception;
50886 + }
50887 +
50888 + iowrite32be(tmp, &regs->fmkg_eeer);
50889 +}
50890 +
50891 +void fman_kg_get_exception(struct fman_kg_regs *regs,
50892 + uint32_t *events,
50893 + uint32_t *scheme_ids,
50894 + bool clear)
50895 +{
50896 + uint32_t mask;
50897 +
50898 + *events = ioread32be(&regs->fmkg_eer);
50899 + mask = ioread32be(&regs->fmkg_eeer);
50900 + *events &= mask;
50901 +
50902 + *scheme_ids = 0;
50903 +
50904 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
50905 + *scheme_ids = ioread32be(&regs->fmkg_seer);
50906 + mask = ioread32be(&regs->fmkg_seeer);
50907 + *scheme_ids &= mask;
50908 + }
50909 +
50910 + if (clear) {
50911 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
50912 + iowrite32be(*events, &regs->fmkg_eer);
50913 + }
50914 +}
50915 +
50916 +void fman_kg_get_capture(struct fman_kg_regs *regs,
50917 + struct fman_kg_ex_ecc_attr *ecc_attr,
50918 + bool clear)
50919 +{
50920 + uint32_t tmp;
50921 +
50922 + tmp = ioread32be(&regs->fmkg_serc);
50923 +
50924 + if (tmp & KG_FMKG_SERC_CAP) {
50925 + /* Captured data is valid */
50926 + ecc_attr->valid = TRUE;
50927 + ecc_attr->double_ecc =
50928 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
50929 + ecc_attr->single_ecc_count =
50930 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
50931 + KG_FMKG_SERC_CNT_SHIFT);
50932 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
50933 +
50934 + if (clear)
50935 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
50936 + } else {
50937 + /* No ECC error is captured */
50938 + ecc_attr->valid = FALSE;
50939 + }
50940 +}
50941 +
50942 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
50943 + struct fman_kg_scheme_regs *scheme_regs)
50944 +{
50945 + struct fman_kg_extract_params *extract_params;
50946 + struct fman_kg_gen_extract_params *gen_params;
50947 + uint32_t tmp_reg, i, select, mask, fqb;
50948 + uint8_t offset, shift, ht;
50949 +
50950 + /* Zero out all registers so no need to care about unused ones */
50951 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
50952 +
50953 + /* Mode register */
50954 + tmp_reg = fm_kg_build_nia(params->next_engine,
50955 + params->next_engine_action);
50956 + if (tmp_reg == KG_NIA_INVALID) {
50957 + return -EINVAL;
50958 + }
50959 +
50960 + if (params->next_engine == E_FMAN_PCD_PLCR) {
50961 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
50962 + }
50963 + else if (params->next_engine == E_FMAN_PCD_CC) {
50964 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
50965 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
50966 + }
50967 +
50968 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
50969 + scheme_regs->kgse_mode = tmp_reg;
50970 +
50971 + /* Match vector */
50972 + scheme_regs->kgse_mv = params->match_vector;
50973 +
50974 + extract_params = &params->extract_params;
50975 +
50976 + /* Scheme default values registers */
50977 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
50978 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
50979 +
50980 + /* Extract Known Fields Command register */
50981 + scheme_regs->kgse_ekfc = extract_params->known_fields;
50982 +
50983 + /* Entry Extract Known Default Value register */
50984 + tmp_reg = 0;
50985 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
50986 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
50987 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
50988 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
50989 + tmp_reg |= extract_params->known_fields_def.etype <<
50990 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
50991 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
50992 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
50993 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
50994 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
50995 + tmp_reg |= extract_params->known_fields_def.mpls <<
50996 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
50997 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
50998 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
50999 + tmp_reg |= extract_params->known_fields_def.ptype <<
51000 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
51001 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
51002 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
51003 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
51004 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
51005 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
51006 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
51007 + tmp_reg |= extract_params->known_fields_def.l4_port <<
51008 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
51009 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
51010 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
51011 +
51012 + scheme_regs->kgse_ekdv = tmp_reg;
51013 +
51014 + /* Generic extract registers */
51015 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
51016 + return -EINVAL;
51017 + }
51018 +
51019 + for (i = 0; i < extract_params->gen_extract_num; i++) {
51020 + gen_params = extract_params->gen_extract + i;
51021 +
51022 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
51023 + tmp_reg |= (uint32_t)gen_params->def_val <<
51024 + FMAN_KG_SCH_GEN_DEF_SHIFT;
51025 +
51026 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
51027 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
51028 + (gen_params->extract == 0)) {
51029 + return -EINVAL;
51030 + }
51031 + } else {
51032 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
51033 + }
51034 +
51035 + tmp_reg |= (uint32_t)gen_params->extract <<
51036 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
51037 + tmp_reg |= (uint32_t)gen_params->mask <<
51038 + FMAN_KG_SCH_GEN_MASK_SHIFT;
51039 +
51040 + offset = gen_params->offset;
51041 + ht = get_gen_ht_code(gen_params->src,
51042 + gen_params->no_validation,
51043 + &offset);
51044 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
51045 + tmp_reg |= offset;
51046 +
51047 + scheme_regs->kgse_gec[i] = tmp_reg;
51048 + }
51049 +
51050 + /* Masks registers */
51051 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
51052 + return -EINVAL;
51053 + }
51054 +
51055 + select = 0;
51056 + mask = 0;
51057 + fqb = 0;
51058 + for (i = 0; i < extract_params->masks_num; i++) {
51059 + /* MCSx fields */
51060 + KG_GET_MASK_SEL_SHIFT(shift, i);
51061 + if (extract_params->masks[i].is_known) {
51062 + /* Mask known field */
51063 + select |= extract_params->masks[i].field_or_gen_idx <<
51064 + shift;
51065 + } else {
51066 + /* Mask generic extract */
51067 + select |= (extract_params->masks[i].field_or_gen_idx +
51068 + FM_KG_MASK_SEL_GEN_BASE) << shift;
51069 + }
51070 +
51071 + /* MOx fields - spread between se_bmch and se_fqb registers */
51072 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
51073 + if (i < 2) {
51074 + select |= (uint32_t)extract_params->masks[i].offset <<
51075 + shift;
51076 + } else {
51077 + fqb |= (uint32_t)extract_params->masks[i].offset <<
51078 + shift;
51079 + }
51080 +
51081 + /* BMx fields */
51082 + KG_GET_MASK_SHIFT(shift, i);
51083 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
51084 + }
51085 +
51086 + /* Finish with rest of BMx fileds -
51087 + * don't mask bits for unused masks by setting
51088 + * corresponding BMx field = 0xFF */
51089 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
51090 + KG_GET_MASK_SHIFT(shift, i);
51091 + mask |= 0xFF << shift;
51092 + }
51093 +
51094 + scheme_regs->kgse_bmch = select;
51095 + scheme_regs->kgse_bmcl = mask;
51096 +
51097 + /* Finish with FQB register initialization.
51098 + * Check fqid is 24-bit value. */
51099 + if (params->base_fqid & ~0x00FFFFFF) {
51100 + return -EINVAL;
51101 + }
51102 +
51103 + fqb |= params->base_fqid;
51104 + scheme_regs->kgse_fqb = fqb;
51105 +
51106 + /* Hash Configuration register */
51107 + tmp_reg = 0;
51108 + if (params->hash_params.use_hash) {
51109 + /* Check hash mask is 24-bit value */
51110 + if (params->hash_params.mask & ~0x00FFFFFF) {
51111 + return -EINVAL;
51112 + }
51113 +
51114 + /* Hash function produces 64-bit value, 24 bits of that
51115 + * are used to generate fq_id and policer profile.
51116 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
51117 + */
51118 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
51119 + return -EINVAL;
51120 + }
51121 +
51122 + tmp_reg |= params->hash_params.mask;
51123 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
51124 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
51125 +
51126 + if (params->hash_params.sym) {
51127 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
51128 + }
51129 +
51130 + }
51131 +
51132 + if (params->bypass_fqid_gen) {
51133 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
51134 + }
51135 +
51136 + scheme_regs->kgse_hc = tmp_reg;
51137 +
51138 + /* Policer Profile register */
51139 + if (params->policer_params.bypass_pp_gen) {
51140 + tmp_reg = 0;
51141 + } else {
51142 + /* Lower 8 bits of 24-bits extracted from hash result
51143 + * are used for policer profile generation.
51144 + * That leaves maximum shift value = 23. */
51145 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
51146 + return -EINVAL;
51147 + }
51148 +
51149 + tmp_reg = params->policer_params.base;
51150 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51151 + FMAN_KG_SCH_PP_SH_SHIFT) &
51152 + FMAN_KG_SCH_PP_SH_MASK;
51153 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51154 + FMAN_KG_SCH_PP_SL_SHIFT) &
51155 + FMAN_KG_SCH_PP_SL_MASK;
51156 + tmp_reg |= (uint32_t)params->policer_params.mask <<
51157 + FMAN_KG_SCH_PP_MASK_SHIFT;
51158 + }
51159 +
51160 + scheme_regs->kgse_ppc = tmp_reg;
51161 +
51162 + /* Coarse Classification Bit Select register */
51163 + if (params->next_engine == E_FMAN_PCD_CC) {
51164 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
51165 + }
51166 +
51167 + /* Packets Counter register */
51168 + if (params->update_counter) {
51169 + scheme_regs->kgse_spc = params->counter_value;
51170 + }
51171 +
51172 + return 0;
51173 +}
51174 +
51175 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
51176 + uint8_t scheme_id,
51177 + uint8_t hwport_id,
51178 + struct fman_kg_scheme_regs *scheme_regs,
51179 + bool update_counter)
51180 +{
51181 + struct fman_kg_scheme_regs *kgse_regs;
51182 + uint32_t tmp_reg;
51183 + int err, i;
51184 +
51185 + /* Write indirect scheme registers */
51186 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51187 +
51188 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
51189 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
51190 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
51191 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
51192 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
51193 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
51194 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
51195 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
51196 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
51197 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
51198 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
51199 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
51200 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
51201 +
51202 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
51203 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
51204 +
51205 + /* Write AR (Action register) */
51206 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
51207 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51208 + return err;
51209 +}
51210 +
51211 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
51212 + uint8_t scheme_id,
51213 + uint8_t hwport_id)
51214 +{
51215 + struct fman_kg_scheme_regs *kgse_regs;
51216 + uint32_t tmp_reg;
51217 + int err, i;
51218 +
51219 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51220 +
51221 + /* Clear all registers including enable bit in mode register */
51222 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
51223 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
51224 + }
51225 +
51226 + /* Write AR (Action register) */
51227 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
51228 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51229 + return err;
51230 +}
51231 +
51232 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
51233 + uint8_t scheme_id,
51234 + uint8_t hwport_id,
51235 + uint32_t *counter)
51236 +{
51237 + struct fman_kg_scheme_regs *kgse_regs;
51238 + uint32_t tmp_reg;
51239 + int err;
51240 +
51241 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51242 +
51243 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51244 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51245 +
51246 + if (err != 0)
51247 + return err;
51248 +
51249 + *counter = ioread32be(&kgse_regs->kgse_spc);
51250 +
51251 + return 0;
51252 +}
51253 +
51254 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
51255 + uint8_t scheme_id,
51256 + uint8_t hwport_id,
51257 + uint32_t counter)
51258 +{
51259 + struct fman_kg_scheme_regs *kgse_regs;
51260 + uint32_t tmp_reg;
51261 + int err;
51262 +
51263 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51264 +
51265 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51266 +
51267 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51268 + if (err != 0)
51269 + return err;
51270 +
51271 + /* Keygen indirect access memory contains all scheme_id registers
51272 + * by now. Change only counter value. */
51273 + iowrite32be(counter, &kgse_regs->kgse_spc);
51274 +
51275 + /* Write back scheme registers */
51276 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
51277 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51278 +
51279 + return err;
51280 +}
51281 +
51282 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
51283 +{
51284 + return ioread32be(&regs->fmkg_tpc);
51285 +}
51286 +
51287 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
51288 + struct fman_kg_cp_regs *cls_plan_regs)
51289 +{
51290 + uint8_t entries_set, entry_bit;
51291 + int i;
51292 +
51293 + /* Zero out all group's register */
51294 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
51295 +
51296 + /* Go over all classification entries in params->entries_mask and
51297 + * configure the corresponding cpe register */
51298 + entries_set = params->entries_mask;
51299 + for (i = 0; entries_set; i++) {
51300 + entry_bit = (uint8_t)(0x80 >> i);
51301 + if ((entry_bit & entries_set) == 0)
51302 + continue;
51303 + entries_set ^= entry_bit;
51304 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
51305 + }
51306 +
51307 + return 0;
51308 +}
51309 +
51310 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
51311 + uint8_t grp_id,
51312 + uint8_t entries_mask,
51313 + uint8_t hwport_id,
51314 + struct fman_kg_cp_regs *cls_plan_regs)
51315 +{
51316 + struct fman_kg_cp_regs *kgcpe_regs;
51317 + uint32_t tmp_reg;
51318 + int i, err;
51319 +
51320 + /* Check group index is valid and the group isn't empty */
51321 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
51322 + return -EINVAL;
51323 +
51324 + /* Write indirect classification plan registers */
51325 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
51326 +
51327 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
51328 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
51329 + }
51330 +
51331 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
51332 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51333 + return err;
51334 +}
51335 +
51336 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
51337 + uint8_t hwport_id,
51338 + uint32_t schemes)
51339 +{
51340 + struct fman_kg_pe_regs *kg_pe_regs;
51341 + uint32_t tmp_reg;
51342 + int err;
51343 +
51344 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51345 +
51346 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
51347 +
51348 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
51349 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51350 + return err;
51351 +}
51352 +
51353 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
51354 + uint8_t grp_mask,
51355 + uint32_t *bind_cls_plans)
51356 +{
51357 + /* Check grp_base and grp_mask are 5-bits values */
51358 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
51359 + return -EINVAL;
51360 +
51361 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
51362 + return 0;
51363 +}
51364 +
51365 +
51366 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
51367 + uint8_t hwport_id,
51368 + uint32_t bind_cls_plans)
51369 +{
51370 + struct fman_kg_pe_regs *kg_pe_regs;
51371 + uint32_t tmp_reg;
51372 + int err;
51373 +
51374 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51375 +
51376 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
51377 +
51378 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
51379 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51380 + return err;
51381 +}
51382 --- /dev/null
51383 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51384 @@ -0,0 +1,129 @@
51385 +/*
51386 + * Copyright 2012 Freescale Semiconductor Inc.
51387 + *
51388 + * Redistribution and use in source and binary forms, with or without
51389 + * modification, are permitted provided that the following conditions are met:
51390 + * * Redistributions of source code must retain the above copyright
51391 + * notice, this list of conditions and the following disclaimer.
51392 + * * Redistributions in binary form must reproduce the above copyright
51393 + * notice, this list of conditions and the following disclaimer in the
51394 + * documentation and/or other materials provided with the distribution.
51395 + * * Neither the name of Freescale Semiconductor nor the
51396 + * names of its contributors may be used to endorse or promote products
51397 + * derived from this software without specific prior written permission.
51398 + *
51399 + *
51400 + * ALTERNATIVELY, this software may be distributed under the terms of the
51401 + * GNU General Public License ("GPL") as published by the Free Software
51402 + * Foundation, either version 2 of that License or (at your option) any
51403 + * later version.
51404 + *
51405 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51406 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51407 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51408 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51409 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51410 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51411 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51412 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51413 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51414 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51415 + */
51416 +
51417 +#include "fsl_fman_prs.h"
51418 +
51419 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51420 +{
51421 + return ioread32be(&regs->fmpr_perr) & ev_mask;
51422 +}
51423 +
51424 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
51425 +{
51426 + return ioread32be(&regs->fmpr_perer);
51427 +}
51428 +
51429 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
51430 +{
51431 + iowrite32be(event, &regs->fmpr_perr);
51432 +}
51433 +
51434 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51435 +{
51436 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
51437 +}
51438 +
51439 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
51440 +{
51441 + return ioread32be(&regs->fmpr_pever);
51442 +}
51443 +
51444 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
51445 +{
51446 + iowrite32be(event, &regs->fmpr_pevr);
51447 +}
51448 +
51449 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
51450 +{
51451 + cfg->port_id_stat = 0;
51452 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
51453 + cfg->prs_exceptions = 0x03000000;
51454 +}
51455 +
51456 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
51457 +{
51458 + uint32_t tmp;
51459 +
51460 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
51461 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
51462 + &regs->fmpr_pevr);
51463 +
51464 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
51465 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
51466 + else
51467 + iowrite32be(0, &regs->fmpr_pever);
51468 +
51469 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
51470 +
51471 + tmp = 0;
51472 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
51473 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
51474 + iowrite32be(tmp, &regs->fmpr_perer);
51475 +
51476 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
51477 +
51478 + return 0;
51479 +}
51480 +
51481 +void fman_prs_enable(struct fman_prs_regs *regs)
51482 +{
51483 + uint32_t tmp;
51484 +
51485 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
51486 + iowrite32be(tmp, &regs->fmpr_rpimac);
51487 +}
51488 +
51489 +void fman_prs_disable(struct fman_prs_regs *regs)
51490 +{
51491 + uint32_t tmp;
51492 +
51493 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
51494 + iowrite32be(tmp, &regs->fmpr_rpimac);
51495 +}
51496 +
51497 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
51498 +{
51499 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
51500 +}
51501 +
51502 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
51503 +{
51504 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
51505 +}
51506 +
51507 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
51508 +{
51509 + if (enable)
51510 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
51511 + else
51512 + iowrite32be(0, &regs->fmpr_ppsc);
51513 +}
51514 --- /dev/null
51515 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51516 @@ -0,0 +1,15 @@
51517 +#
51518 +# Makefile for the Freescale Ethernet controllers
51519 +#
51520 +ccflags-y += -DVERSION=\"\"
51521 +#
51522 +#Include netcomm SW specific definitions
51523 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
51524 +
51525 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
51526 +
51527 +ccflags-y += -I$(NCSW_FM_INC)
51528 +
51529 +obj-y += fsl-ncsw-Pcd.o
51530 +
51531 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
51532 --- /dev/null
51533 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51534 @@ -0,0 +1,6436 @@
51535 +/*
51536 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51537 + *
51538 + * Redistribution and use in source and binary forms, with or without
51539 + * modification, are permitted provided that the following conditions are met:
51540 + * * Redistributions of source code must retain the above copyright
51541 + * notice, this list of conditions and the following disclaimer.
51542 + * * Redistributions in binary form must reproduce the above copyright
51543 + * notice, this list of conditions and the following disclaimer in the
51544 + * documentation and/or other materials provided with the distribution.
51545 + * * Neither the name of Freescale Semiconductor nor the
51546 + * names of its contributors may be used to endorse or promote products
51547 + * derived from this software without specific prior written permission.
51548 + *
51549 + *
51550 + * ALTERNATIVELY, this software may be distributed under the terms of the
51551 + * GNU General Public License ("GPL") as published by the Free Software
51552 + * Foundation, either version 2 of that License or (at your option) any
51553 + * later version.
51554 + *
51555 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51556 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51557 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51558 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51559 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51560 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51561 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51562 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51563 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51564 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51565 + */
51566 +
51567 +
51568 +/******************************************************************************
51569 + @File fm_port.c
51570 +
51571 + @Description FM driver routines implementation.
51572 + *//***************************************************************************/
51573 +#include "error_ext.h"
51574 +#include "std_ext.h"
51575 +#include "string_ext.h"
51576 +#include "sprint_ext.h"
51577 +#include "debug_ext.h"
51578 +#include "fm_muram_ext.h"
51579 +
51580 +#include "fman_common.h"
51581 +#include "fm_port.h"
51582 +#include "fm_port_dsar.h"
51583 +#include "common/general.h"
51584 +
51585 +/****************************************/
51586 +/* static functions */
51587 +/****************************************/
51588 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
51589 +
51590 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
51591 +{
51592 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
51593 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
51594 + t_Error ans = E_OK;
51595 + uint32_t unusedMask;
51596 +
51597 + if (p_FmPort->imEn)
51598 + {
51599 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51600 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51601 + > 2)
51602 + RETURN_ERROR(
51603 + MAJOR,
51604 + E_INVALID_VALUE,
51605 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
51606 +
51607 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
51608 + return ERROR_CODE(ans);
51609 + }
51610 + else
51611 + {
51612 + /****************************************/
51613 + /* Rx only */
51614 + /****************************************/
51615 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51616 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51617 + {
51618 + /* external buffer pools */
51619 + if (!p_Params->extBufPools.numOfPoolsUsed)
51620 + RETURN_ERROR(
51621 + MAJOR,
51622 + E_INVALID_VALUE,
51623 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
51624 +
51625 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
51626 + p_Params->p_BackupBmPools,
51627 + &p_Params->bufPoolDepletion) != E_OK)
51628 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51629 +
51630 + /* Check that part of IC that needs copying is small enough to enter start margin */
51631 + if (p_Params->intContext.size
51632 + && (p_Params->intContext.size
51633 + + p_Params->intContext.extBufOffset
51634 + > p_Params->bufMargins.startMargins))
51635 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51636 + ("intContext.size is larger than start margins"));
51637 +
51638 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
51639 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
51640 + RETURN_ERROR(
51641 + MAJOR,
51642 + E_INVALID_VALUE,
51643 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
51644 +
51645 +#ifdef FM_NO_BACKUP_POOLS
51646 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
51647 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
51648 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
51649 +#endif /* FM_NO_BACKUP_POOLS */
51650 + }
51651 +
51652 + /****************************************/
51653 + /* Non Rx ports */
51654 + /****************************************/
51655 + else
51656 + {
51657 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
51658 + RETURN_ERROR(
51659 + MAJOR,
51660 + E_INVALID_VALUE,
51661 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
51662 +
51663 + /* to protect HW internal-context from overwrite */
51664 + if ((p_Params->intContext.size)
51665 + && (p_Params->intContext.intContextOffset
51666 + < MIN_TX_INT_OFFSET))
51667 + RETURN_ERROR(
51668 + MAJOR,
51669 + E_INVALID_VALUE,
51670 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
51671 +
51672 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51673 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
51674 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
51675 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51676 + != DEFAULT_notSupported))
51677 + {
51678 + /* Check that not larger than 8 */
51679 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
51680 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51681 + > MAX_FIFO_PIPELINE_DEPTH))
51682 + RETURN_ERROR(
51683 + MAJOR,
51684 + E_INVALID_VALUE,
51685 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
51686 + }
51687 + }
51688 +
51689 + /****************************************/
51690 + /* Rx Or Offline Parsing */
51691 + /****************************************/
51692 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51693 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51694 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
51695 + {
51696 + if (!p_Params->dfltFqid)
51697 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51698 + ("dfltFqid must be between 1 and 2^24-1"));
51699 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
51700 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
51701 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
51702 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
51703 + }
51704 +
51705 + /****************************************/
51706 + /* All ports */
51707 + /****************************************/
51708 + /* common BMI registers values */
51709 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
51710 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
51711 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51712 + ("errFqid must be between 1 and 2^24-1"));
51713 + if (p_Params->dfltFqid & ~0x00FFFFFF)
51714 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51715 + ("dfltFqid must be between 1 and 2^24-1"));
51716 + }
51717 +
51718 + /****************************************/
51719 + /* Rx only */
51720 + /****************************************/
51721 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51722 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51723 + {
51724 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
51725 + RETURN_ERROR(
51726 + MAJOR,
51727 + E_INVALID_VALUE,
51728 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
51729 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
51730 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
51731 + RETURN_ERROR(
51732 + MAJOR,
51733 + E_INVALID_VALUE,
51734 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51735 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
51736 + RETURN_ERROR(
51737 + MAJOR,
51738 + E_INVALID_VALUE,
51739 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
51740 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
51741 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
51742 + RETURN_ERROR(
51743 + MAJOR,
51744 + E_INVALID_VALUE,
51745 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51746 +
51747 + /* Check that not larger than 16 */
51748 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
51749 + RETURN_ERROR(
51750 + MAJOR,
51751 + E_INVALID_VALUE,
51752 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51753 +
51754 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
51755 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51756 +
51757 + /* extra FIFO size (allowed only to Rx ports) */
51758 + if (p_Params->setSizeOfFifo
51759 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
51760 + RETURN_ERROR(
51761 + MAJOR,
51762 + E_INVALID_VALUE,
51763 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
51764 +
51765 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
51766 + && !p_Params->bufPoolDepletion.numOfPools)
51767 + RETURN_ERROR(
51768 + MAJOR,
51769 + E_INVALID_VALUE,
51770 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
51771 +#ifdef FM_CSI_CFED_LIMIT
51772 + if (p_FmPort->fmRevInfo.majorRev == 4)
51773 + {
51774 + /* Check that not larger than 16 */
51775 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
51776 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
51777 + }
51778 +#endif /* FM_CSI_CFED_LIMIT */
51779 + }
51780 +
51781 + /****************************************/
51782 + /* Non Rx ports */
51783 + /****************************************/
51784 + /* extra FIFO size (allowed only to Rx ports) */
51785 + else
51786 + if (p_FmPort->fifoBufs.extra)
51787 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51788 + (" No fifoBufs.extra for non Rx ports"));
51789 +
51790 + /****************************************/
51791 + /* Tx only */
51792 + /****************************************/
51793 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51794 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
51795 + {
51796 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
51797 + RETURN_ERROR(
51798 + MAJOR,
51799 + E_INVALID_VALUE,
51800 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
51801 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
51802 + RETURN_ERROR(
51803 + MAJOR,
51804 + E_INVALID_VALUE,
51805 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
51806 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
51807 + RETURN_ERROR(
51808 + MAJOR,
51809 + E_INVALID_VALUE,
51810 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
51811 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
51812 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
51813 + RETURN_ERROR(
51814 + MAJOR,
51815 + E_INVALID_VALUE,
51816 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51817 +
51818 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
51819 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51820 + > 2)
51821 + RETURN_ERROR(
51822 + MAJOR, E_INVALID_VALUE,
51823 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
51824 + }
51825 +
51826 + /****************************************/
51827 + /* Non Tx Ports */
51828 + /****************************************/
51829 + /* If discard override was selected , no frames may be discarded. */
51830 + else
51831 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
51832 + RETURN_ERROR(
51833 + MAJOR,
51834 + E_CONFLICT,
51835 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
51836 +
51837 + /****************************************/
51838 + /* Rx and Offline parsing */
51839 + /****************************************/
51840 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51841 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51842 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
51843 + {
51844 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
51845 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
51846 + else
51847 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
51848 +
51849 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
51850 + if (p_Params->errorsToDiscard & unusedMask)
51851 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
51852 + ("errorsToDiscard contains undefined bits"));
51853 + }
51854 +
51855 + /****************************************/
51856 + /* Offline Ports */
51857 + /****************************************/
51858 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
51859 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
51860 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
51861 + && p_Params->setNumOfOpenDmas
51862 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
51863 + RETURN_ERROR(
51864 + MAJOR,
51865 + E_INVALID_VALUE,
51866 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
51867 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
51868 +
51869 + /****************************************/
51870 + /* Offline & HC Ports */
51871 + /****************************************/
51872 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
51873 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
51874 + {
51875 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
51876 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
51877 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
51878 + /* this is an indication that user called config for this mode which is not supported in this integration */
51879 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
51880 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
51881 +
51882 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
51883 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
51884 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
51885 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
51886 + /* this is an indication that user called config for this mode which is not supported in this integration */
51887 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
51888 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
51889 + }
51890 +
51891 + /****************************************/
51892 + /* All ports */
51893 + /****************************************/
51894 + /* Check that not larger than 16 */
51895 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
51896 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
51897 + RETURN_ERROR(
51898 + MAJOR,
51899 + E_INVALID_VALUE,
51900 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
51901 +
51902 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
51903 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51904 +
51905 + /* common BMI registers values */
51906 + if (p_Params->setNumOfTasks
51907 + && ((!p_FmPort->tasks.num)
51908 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
51909 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51910 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
51911 + if (p_Params->setNumOfTasks
51912 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
51913 + RETURN_ERROR(
51914 + MAJOR,
51915 + E_INVALID_VALUE,
51916 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
51917 + if (p_Params->setNumOfOpenDmas
51918 + && ((!p_FmPort->openDmas.num)
51919 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
51920 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51921 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
51922 + if (p_Params->setNumOfOpenDmas
51923 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
51924 + RETURN_ERROR(
51925 + MAJOR,
51926 + E_INVALID_VALUE,
51927 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
51928 + if (p_Params->setSizeOfFifo
51929 + && (!p_FmPort->fifoBufs.num
51930 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
51931 + RETURN_ERROR(
51932 + MAJOR,
51933 + E_INVALID_VALUE,
51934 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
51935 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
51936 + RETURN_ERROR(
51937 + MAJOR, E_INVALID_VALUE,
51938 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
51939 +
51940 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
51941 + if (p_FmPort->fmRevInfo.majorRev == 4)
51942 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
51943 + /* this is an indication that user called config for this mode which is not supported in this integration */
51944 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
51945 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
51946 +
51947 + return E_OK;
51948 +}
51949 +
51950 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
51951 +{
51952 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
51953 +
51954 + /*************************/
51955 + /* TX PORTS */
51956 + /*************************/
51957 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
51958 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
51959 + {
51960 + minFifoSizeRequired =
51961 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
51962 + + (3 * BMI_FIFO_UNITS));
51963 + if (!p_FmPort->imEn)
51964 + minFifoSizeRequired +=
51965 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51966 + * BMI_FIFO_UNITS;
51967 +
51968 + optFifoSizeForB2B = minFifoSizeRequired;
51969 +
51970 + /* Add some margin for back-to-back capability to improve performance,
51971 + allows the hardware to pipeline new frame dma while the previous
51972 + frame not yet transmitted. */
51973 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
51974 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
51975 + else
51976 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
51977 + }
51978 +
51979 + /*************************/
51980 + /* RX IM PORTS */
51981 + /*************************/
51982 + else
51983 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51984 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51985 + && p_FmPort->imEn)
51986 + {
51987 + optFifoSizeForB2B =
51988 + minFifoSizeRequired =
51989 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
51990 + + (4 * BMI_FIFO_UNITS));
51991 + }
51992 +
51993 + /*************************/
51994 + /* RX non-IM PORTS */
51995 + /*************************/
51996 + else
51997 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51998 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51999 + && !p_FmPort->imEn)
52000 + {
52001 + if (p_FmPort->fmRevInfo.majorRev == 4)
52002 + {
52003 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
52004 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
52005 + else
52006 + minFifoSizeRequired =
52007 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
52008 + + (7 * BMI_FIFO_UNITS));
52009 + }
52010 + else
52011 + {
52012 +#if (DPAA_VERSION >= 11)
52013 + minFifoSizeRequired =
52014 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52015 + + (5 * BMI_FIFO_UNITS));
52016 + /* 4 according to spec + 1 for FOF>0 */
52017 +#else
52018 + minFifoSizeRequired = (uint32_t)
52019 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
52020 + + (7*BMI_FIFO_UNITS));
52021 +#endif /* (DPAA_VERSION >= 11) */
52022 + }
52023 +
52024 + optFifoSizeForB2B = minFifoSizeRequired;
52025 +
52026 + /* Add some margin for back-to-back capability to improve performance,
52027 + allows the hardware to pipeline new frame dma while the previous
52028 + frame not yet transmitted. */
52029 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52030 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
52031 + else
52032 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52033 + }
52034 +
52035 + /* For O/H ports, check fifo size and update if necessary */
52036 + else
52037 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52038 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52039 + {
52040 +#if (DPAA_VERSION >= 11)
52041 + optFifoSizeForB2B =
52042 + minFifoSizeRequired =
52043 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52044 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52045 + + 5) * BMI_FIFO_UNITS));
52046 + /* 4 according to spec + 1 for FOF>0 */
52047 +#else
52048 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
52049 +#endif /* (DPAA_VERSION >= 11) */
52050 + }
52051 +
52052 + ASSERT_COND(minFifoSizeRequired > 0);
52053 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
52054 +
52055 + /* Verify the size */
52056 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
52057 + DBG(INFO,
52058 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
52059 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
52060 + DBG(INFO,
52061 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
52062 +
52063 + return E_OK;
52064 +}
52065 +
52066 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
52067 +{
52068 + if (p_FmPort->p_FmPortDriverParam)
52069 + {
52070 + XX_Free(p_FmPort->p_FmPortDriverParam);
52071 + p_FmPort->p_FmPortDriverParam = NULL;
52072 + }
52073 +}
52074 +
52075 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
52076 +{
52077 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
52078 + t_FmBufPoolDepletion *p_BufPoolDepletion =
52079 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
52080 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
52081 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
52082 + int i = 0, j = 0, err;
52083 + struct fman_port_bpools bpools;
52084 +
52085 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
52086 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
52087 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
52088 +
52089 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
52090 + sizesArray);
52091 +
52092 + /* Prepare flibs bpools structure */
52093 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
52094 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
52095 + bpools.counters_enable = TRUE;
52096 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
52097 + {
52098 + bpools.bpool[i].bpid = orderedArray[i];
52099 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
52100 + /* functionality available only for some derivatives (limited by config) */
52101 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52102 + for (j = 0;
52103 + j
52104 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
52105 + j++)
52106 + if (orderedArray[i]
52107 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
52108 + {
52109 + bpools.bpool[i].is_backup = TRUE;
52110 + break;
52111 + }
52112 + }
52113 +
52114 + /* save pools parameters for later use */
52115 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
52116 + p_FmPort->rxPoolsParams.largestBufSize =
52117 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
52118 + p_FmPort->rxPoolsParams.secondLargestBufSize =
52119 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
52120 +
52121 + /* FMBM_RMPD reg. - pool depletion */
52122 + if (p_BufPoolDepletion->poolsGrpModeEnable)
52123 + {
52124 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
52125 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52126 + {
52127 + if (p_BufPoolDepletion->poolsToConsider[i])
52128 + {
52129 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52130 + {
52131 + if (i == orderedArray[j])
52132 + {
52133 + bpools.bpool[j].grp_bp_depleted = TRUE;
52134 + break;
52135 + }
52136 + }
52137 + }
52138 + }
52139 + }
52140 +
52141 + if (p_BufPoolDepletion->singlePoolModeEnable)
52142 + {
52143 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52144 + {
52145 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
52146 + {
52147 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52148 + {
52149 + if (i == orderedArray[j])
52150 + {
52151 + bpools.bpool[j].single_bp_depleted = TRUE;
52152 + break;
52153 + }
52154 + }
52155 + }
52156 + }
52157 + }
52158 +
52159 +#if (DPAA_VERSION >= 11)
52160 + /* fill QbbPEV */
52161 + if (p_BufPoolDepletion->poolsGrpModeEnable
52162 + || p_BufPoolDepletion->singlePoolModeEnable)
52163 + {
52164 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
52165 + {
52166 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
52167 + {
52168 + bpools.bpool[i].pfc_priorities_en = TRUE;
52169 + }
52170 + }
52171 + }
52172 +#endif /* (DPAA_VERSION >= 11) */
52173 +
52174 + /* Issue flibs function */
52175 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
52176 + if (err != 0)
52177 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
52178 +
52179 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52180 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
52181 +
52182 + return E_OK;
52183 +}
52184 +
52185 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
52186 +{
52187 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52188 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
52189 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
52190 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
52191 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
52192 + return E_OK;
52193 +}
52194 +
52195 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
52196 +{
52197 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
52198 + struct fman_port_params portParams;
52199 + uint32_t tmpVal;
52200 + t_Error err;
52201 +
52202 + /* Set up flibs parameters and issue init function */
52203 +
52204 + memset(&portParams, 0, sizeof(struct fman_port_params));
52205 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
52206 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
52207 + portParams.err_fqid = p_DriverParams->errFqid;
52208 + portParams.deq_sp = p_DriverParams->deqSubPortal;
52209 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
52210 + switch (p_FmPort->portType)
52211 + {
52212 + case (e_FM_PORT_TYPE_RX_10G):
52213 + case (e_FM_PORT_TYPE_RX):
52214 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
52215 + if (!p_FmPort->imEn)
52216 + {
52217 + if (p_DriverParams->forwardReuseIntContext)
52218 + p_DriverParams->dfltCfg.rx_fd_bits =
52219 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
52220 + }
52221 + break;
52222 +
52223 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52224 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
52225 + break;
52226 + break;
52227 +
52228 + default:
52229 + break;
52230 + }
52231 +
52232 + tmpVal =
52233 + (uint32_t)(
52234 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
52235 + / OFFSET_UNITS + 1) :
52236 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
52237 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
52238 + p_DriverParams->dfltCfg.int_buf_start_margin =
52239 + p_FmPort->internalBufferOffset;
52240 +
52241 + p_DriverParams->dfltCfg.ext_buf_start_margin =
52242 + p_DriverParams->bufMargins.startMargins;
52243 + p_DriverParams->dfltCfg.ext_buf_end_margin =
52244 + p_DriverParams->bufMargins.endMargins;
52245 +
52246 + p_DriverParams->dfltCfg.ic_ext_offset =
52247 + p_DriverParams->intContext.extBufOffset;
52248 + p_DriverParams->dfltCfg.ic_int_offset =
52249 + p_DriverParams->intContext.intContextOffset;
52250 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
52251 +
52252 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
52253 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
52254 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
52255 +
52256 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
52257 + (uint8_t)p_FmPort->tasks.num;
52258 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
52259 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
52260 + else
52261 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
52262 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
52263 + (uint8_t)p_FmPort->openDmas.num;
52264 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
52265 +
52266 + if (0
52267 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
52268 + &portParams))
52269 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
52270 +
52271 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
52272 + RETURN_ERROR(MAJOR, err, NO_MSG);
52273 + else
52274 + {
52275 + // from QMIInit
52276 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52277 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52278 + {
52279 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
52280 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52281 + FALSE);
52282 + else
52283 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52284 + TRUE);
52285 + }
52286 + }
52287 + /* The code bellow is a trick so the FM will not release the buffer
52288 + to BM nor will try to enqueue the frame to QM */
52289 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52290 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
52291 + {
52292 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
52293 + {
52294 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
52295 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
52296 + * buffers to BM regardless of fmbm_tfene
52297 + */
52298 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
52299 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
52300 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
52301 + }
52302 + }
52303 +
52304 + return E_OK;
52305 +}
52306 +
52307 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52308 +{
52309 + UNUSED(p_FmPort);
52310 +
52311 + switch (counter)
52312 + {
52313 + case (e_FM_PORT_COUNTERS_CYCLE):
52314 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52315 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52316 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52317 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52318 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52319 + case (e_FM_PORT_COUNTERS_FRAME):
52320 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52321 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52322 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52323 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52324 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52325 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52326 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52327 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
52328 + return TRUE;
52329 + default:
52330 + return FALSE;
52331 + }
52332 +}
52333 +
52334 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52335 +{
52336 + UNUSED(p_FmPort);
52337 +
52338 + switch (counter)
52339 + {
52340 + case (e_FM_PORT_COUNTERS_CYCLE):
52341 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52342 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52343 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52344 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52345 + case (e_FM_PORT_COUNTERS_FRAME):
52346 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52347 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52348 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52349 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52350 + return TRUE;
52351 + default:
52352 + return FALSE;
52353 + }
52354 +}
52355 +
52356 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52357 +{
52358 + switch (counter)
52359 + {
52360 + case (e_FM_PORT_COUNTERS_CYCLE):
52361 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52362 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52363 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52364 + case (e_FM_PORT_COUNTERS_FRAME):
52365 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52366 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52367 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52368 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52369 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52370 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52371 + return TRUE;
52372 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52373 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
52374 + return FALSE;
52375 + else
52376 + return TRUE;
52377 + default:
52378 + return FALSE;
52379 + }
52380 +}
52381 +
52382 +static t_Error BmiPortCheckAndGetCounterType(
52383 + t_FmPort *p_FmPort, e_FmPortCounters counter,
52384 + enum fman_port_stats_counters *p_StatsType,
52385 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
52386 +{
52387 + volatile uint32_t *p_Reg;
52388 + bool isValid;
52389 +
52390 + switch (p_FmPort->portType)
52391 + {
52392 + case (e_FM_PORT_TYPE_RX_10G):
52393 + case (e_FM_PORT_TYPE_RX):
52394 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
52395 + isValid = CheckRxBmiCounter(p_FmPort, counter);
52396 + break;
52397 + case (e_FM_PORT_TYPE_TX_10G):
52398 + case (e_FM_PORT_TYPE_TX):
52399 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
52400 + isValid = CheckTxBmiCounter(p_FmPort, counter);
52401 + break;
52402 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52403 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
52404 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
52405 + isValid = CheckOhBmiCounter(p_FmPort, counter);
52406 + break;
52407 + default:
52408 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
52409 + }
52410 +
52411 + if (!isValid)
52412 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52413 + ("Requested counter is not available for this port type"));
52414 +
52415 + /* check that counters are enabled */
52416 + switch (counter)
52417 + {
52418 + case (e_FM_PORT_COUNTERS_CYCLE):
52419 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52420 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52421 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52422 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52423 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52424 + /* performance counters - may be read when disabled */
52425 + *p_IsStats = FALSE;
52426 + break;
52427 + case (e_FM_PORT_COUNTERS_FRAME):
52428 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52429 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52430 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52431 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52432 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52433 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52434 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52435 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52436 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52437 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52438 + *p_IsStats = TRUE;
52439 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
52440 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52441 + ("Requested counter was not enabled"));
52442 + break;
52443 + default:
52444 + break;
52445 + }
52446 +
52447 + /* Set counter */
52448 + switch (counter)
52449 + {
52450 + case (e_FM_PORT_COUNTERS_CYCLE):
52451 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
52452 + break;
52453 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52454 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
52455 + break;
52456 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52457 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
52458 + break;
52459 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52460 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
52461 + break;
52462 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52463 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
52464 + break;
52465 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52466 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
52467 + break;
52468 + case (e_FM_PORT_COUNTERS_FRAME):
52469 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
52470 + break;
52471 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52472 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
52473 + break;
52474 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52475 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
52476 + break;
52477 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52478 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
52479 + break;
52480 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52481 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
52482 + break;
52483 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52484 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
52485 + break;
52486 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52487 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
52488 + break;
52489 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52490 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
52491 + break;
52492 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52493 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
52494 + break;
52495 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52496 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
52497 + break;
52498 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52499 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
52500 + break;
52501 + default:
52502 + break;
52503 + }
52504 +
52505 + return E_OK;
52506 +}
52507 +
52508 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
52509 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
52510 + uint32_t *p_SoftSeqAttachReg)
52511 +{
52512 + uint8_t hdrNum, Ipv4HdrNum;
52513 + u_FmPcdHdrPrsOpts *p_prsOpts;
52514 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
52515 +
52516 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
52517 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
52518 + RETURN_ERROR(
52519 + MAJOR, E_NOT_SUPPORTED,
52520 + ("No additional parameters for private or special headers."));
52521 +
52522 + if (p_HdrParams->errDisable)
52523 + tmpReg |= PRS_HDR_ERROR_DIS;
52524 +
52525 + /* Set parser options */
52526 + if (p_HdrParams->usePrsOpts)
52527 + {
52528 + p_prsOpts = &p_HdrParams->prsOpts;
52529 + switch (p_HdrParams->hdr)
52530 + {
52531 + case (HEADER_TYPE_MPLS):
52532 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
52533 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
52534 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
52535 + if (hdrNum == ILLEGAL_HDR_NUM)
52536 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52537 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52538 + if (hdrNum < Ipv4HdrNum)
52539 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52540 + ("Header must be equal or higher than IPv4"));
52541 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
52542 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
52543 + break;
52544 + case (HEADER_TYPE_PPPoE):
52545 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
52546 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
52547 + break;
52548 + case (HEADER_TYPE_IPv6):
52549 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
52550 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
52551 + break;
52552 + case (HEADER_TYPE_TCP):
52553 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
52554 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
52555 + else
52556 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
52557 + break;
52558 + case (HEADER_TYPE_UDP):
52559 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
52560 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
52561 + else
52562 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
52563 + break;
52564 + default:
52565 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
52566 + }
52567 + }
52568 +
52569 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
52570 + if (p_HdrParams->swPrsEnable)
52571 + {
52572 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
52573 + p_HdrParams->indexPerHdr);
52574 + if (tmpPrsOffset == ILLEGAL_BASE)
52575 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52576 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
52577 + }
52578 + *p_SoftSeqAttachReg = tmpReg;
52579 +
52580 + return E_OK;
52581 +}
52582 +
52583 +static uint32_t GetPortSchemeBindParams(
52584 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
52585 +{
52586 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52587 + uint32_t walking1Mask = 0x80000000, tmp;
52588 + uint8_t idx = 0;
52589 +
52590 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
52591 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
52592 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
52593 + p_SchemeBind->numOfSchemes = 0;
52594 + tmp = p_FmPort->schemesPerPortVector;
52595 + if (tmp)
52596 + {
52597 + while (tmp)
52598 + {
52599 + if (tmp & walking1Mask)
52600 + {
52601 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
52602 + p_SchemeBind->numOfSchemes++;
52603 + tmp &= ~walking1Mask;
52604 + }
52605 + walking1Mask >>= 1;
52606 + idx++;
52607 + }
52608 + }
52609 +
52610 + return tmp;
52611 +}
52612 +
52613 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
52614 +{
52615 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52616 + volatile uint32_t *p_BmiCfgReg = NULL;
52617 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
52618 + uint32_t lcv, walking1Mask = 0x80000000;
52619 + uint8_t cnt = 0;
52620 +
52621 + ASSERT_COND(p_FmPort);
52622 + ASSERT_COND(p_FmPort->h_FmPcd);
52623 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
52624 +
52625 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52626 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52627 + return;
52628 +
52629 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
52630 + /* get LCV for MACSEC */
52631 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
52632 + != 0)
52633 + {
52634 + while (!(lcv & walking1Mask))
52635 + {
52636 + cnt++;
52637 + walking1Mask >>= 1;
52638 + }
52639 +
52640 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
52641 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
52642 + }
52643 +}
52644 +
52645 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
52646 +{
52647 + t_Error err = E_OK;
52648 + uint32_t tmpReg;
52649 + volatile uint32_t *p_BmiNia = NULL;
52650 + volatile uint32_t *p_BmiPrsNia = NULL;
52651 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
52652 + volatile uint32_t *p_BmiInitPrsResult = NULL;
52653 + volatile uint32_t *p_BmiCcBase = NULL;
52654 + uint16_t hdrNum, L3HdrNum, greHdrNum;
52655 + int i;
52656 + bool isEmptyClsPlanGrp;
52657 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
52658 + uint16_t absoluteProfileId;
52659 + uint8_t physicalSchemeId;
52660 + uint32_t ccTreePhysOffset;
52661 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
52662 + uint32_t initialSwPrs = 0;
52663 +
52664 + ASSERT_COND(p_FmPort);
52665 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
52666 +
52667 + if (p_FmPort->imEn)
52668 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52669 + ("available for non-independant mode ports only"));
52670 +
52671 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52672 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
52673 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52674 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
52675 + ("available for Rx and offline parsing ports only"));
52676 +
52677 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
52678 +
52679 + p_FmPort->pcdEngines = 0;
52680 +
52681 + /* initialize p_FmPort->pcdEngines field in port's structure */
52682 + switch (p_PcdParams->pcdSupport)
52683 + {
52684 + case (e_FM_PORT_PCD_SUPPORT_NONE):
52685 + RETURN_ERROR(
52686 + MAJOR,
52687 + E_INVALID_STATE,
52688 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
52689 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
52690 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52691 + break;
52692 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
52693 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52694 + break;
52695 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
52696 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52697 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52698 + break;
52699 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
52700 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52701 + p_FmPort->pcdEngines |= FM_PCD_KG;
52702 + break;
52703 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
52704 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52705 + p_FmPort->pcdEngines |= FM_PCD_CC;
52706 + p_FmPort->pcdEngines |= FM_PCD_KG;
52707 + break;
52708 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
52709 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52710 + p_FmPort->pcdEngines |= FM_PCD_KG;
52711 + p_FmPort->pcdEngines |= FM_PCD_CC;
52712 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52713 + break;
52714 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
52715 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52716 + p_FmPort->pcdEngines |= FM_PCD_CC;
52717 + break;
52718 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
52719 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52720 + p_FmPort->pcdEngines |= FM_PCD_CC;
52721 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52722 + break;
52723 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
52724 + p_FmPort->pcdEngines |= FM_PCD_PRS;
52725 + p_FmPort->pcdEngines |= FM_PCD_KG;
52726 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52727 + break;
52728 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
52729 + p_FmPort->pcdEngines |= FM_PCD_CC;
52730 + break;
52731 +#ifdef FM_CAPWAP_SUPPORT
52732 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
52733 + p_FmPort->pcdEngines |= FM_PCD_CC;
52734 + p_FmPort->pcdEngines |= FM_PCD_KG;
52735 + break;
52736 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
52737 + p_FmPort->pcdEngines |= FM_PCD_CC;
52738 + p_FmPort->pcdEngines |= FM_PCD_KG;
52739 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
52740 + break;
52741 +#endif /* FM_CAPWAP_SUPPORT */
52742 +
52743 + default:
52744 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
52745 + }
52746 +
52747 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
52748 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
52749 + > FM_PCD_PRS_NUM_OF_HDRS))
52750 + RETURN_ERROR(
52751 + MAJOR,
52752 + E_INVALID_VALUE,
52753 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
52754 +
52755 + /* check that parameters exist for each and only each defined engine */
52756 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
52757 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
52758 + != !!p_PcdParams->p_KgParams)
52759 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
52760 + != !!p_PcdParams->p_CcParams))
52761 + RETURN_ERROR(
52762 + MAJOR,
52763 + E_INVALID_STATE,
52764 + ("PCD initialization structure is not consistent with pcdSupport"));
52765 +
52766 + /* get PCD registers pointers */
52767 + switch (p_FmPort->portType)
52768 + {
52769 + case (e_FM_PORT_TYPE_RX_10G):
52770 + case (e_FM_PORT_TYPE_RX):
52771 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
52772 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
52773 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
52774 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
52775 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
52776 + break;
52777 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52778 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
52779 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
52780 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
52781 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
52782 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
52783 + break;
52784 + default:
52785 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
52786 + }
52787 +
52788 + /* set PCD port parameter */
52789 + if (p_FmPort->pcdEngines & FM_PCD_CC)
52790 + {
52791 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
52792 + p_PcdParams->p_CcParams->h_CcTree,
52793 + &ccTreePhysOffset, p_FmPort);
52794 + if (err)
52795 + RETURN_ERROR(MAJOR, err, NO_MSG);
52796 +
52797 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
52798 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
52799 + }
52800 +
52801 + if (p_FmPort->pcdEngines & FM_PCD_KG)
52802 + {
52803 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
52804 + RETURN_ERROR(
52805 + MAJOR,
52806 + E_INVALID_VALUE,
52807 + ("For ports using Keygen, at least one scheme must be bound. "));
52808 +
52809 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
52810 + p_FmPort->hardwarePortId,
52811 + p_FmPort->netEnvId,
52812 + p_FmPort->optArray,
52813 + &p_FmPort->clsPlanGrpId,
52814 + &isEmptyClsPlanGrp);
52815 + if (err)
52816 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52817 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
52818 +
52819 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
52820 +
52821 + schemeBind.netEnvId = p_FmPort->netEnvId;
52822 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
52823 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
52824 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
52825 +
52826 + /* for each scheme */
52827 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
52828 + {
52829 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
52830 + physicalSchemeId = FmPcdKgGetSchemeId(
52831 + p_PcdParams->p_KgParams->h_Schemes[i]);
52832 + schemeBind.schemesIds[i] = physicalSchemeId;
52833 + /* build vector */
52834 + p_FmPort->schemesPerPortVector |= 1
52835 + << (31 - (uint32_t)physicalSchemeId);
52836 +#if (DPAA_VERSION >= 11)
52837 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
52838 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
52839 + if (!p_FmPort->vspe
52840 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
52841 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
52842 + ("VSPE is not at port level"));
52843 +#endif /* (DPAA_VERSION >= 11) */
52844 + }
52845 +
52846 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
52847 + if (err)
52848 + RETURN_ERROR(MAJOR, err, NO_MSG);
52849 + }
52850 +
52851 + /***************************/
52852 + /* configure NIA after BMI */
52853 + /***************************/
52854 + /* rfne may contain FDCS bits, so first we read them. */
52855 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
52856 +
52857 + /* If policer is used directly after BMI or PRS */
52858 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
52859 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
52860 + || (p_PcdParams->pcdSupport
52861 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
52862 + {
52863 + if (!p_PcdParams->p_PlcrParams->h_Profile)
52864 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
52865 + ("Profile should be initialized"));
52866 +
52867 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
52868 + p_PcdParams->p_PlcrParams->h_Profile);
52869 +
52870 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
52871 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
52872 + ("Private port profile not valid."));
52873 +
52874 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
52875 +
52876 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
52877 + /* update BMI HPNIA */
52878 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
52879 + else
52880 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
52881 + /* update BMI NIA */
52882 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
52883 + }
52884 +
52885 + /* if CC is used directly after BMI */
52886 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
52887 +#ifdef FM_CAPWAP_SUPPORT
52888 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
52889 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
52890 +#endif /* FM_CAPWAP_SUPPORT */
52891 + )
52892 + {
52893 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52894 + RETURN_ERROR(
52895 + MAJOR,
52896 + E_INVALID_OPERATION,
52897 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
52898 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
52899 + /* check that prs start offset == RIM[FOF] */
52900 + }
52901 +
52902 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
52903 + {
52904 + ASSERT_COND(p_PcdParams->p_PrsParams);
52905 +#if (DPAA_VERSION >= 11)
52906 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
52907 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
52908 + else
52909 + {
52910 +#endif /* (DPAA_VERSION >= 11) */
52911 + /* if PRS is used it is always first */
52912 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
52913 + if (hdrNum == ILLEGAL_HDR_NUM)
52914 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
52915 +#if (DPAA_VERSION >= 11)
52916 + }
52917 +#endif /* (DPAA_VERSION >= 11) */
52918 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
52919 + /* set after parser NIA */
52920 + tmpReg = 0;
52921 + switch (p_PcdParams->pcdSupport)
52922 + {
52923 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
52924 + WRITE_UINT32(*p_BmiPrsNia,
52925 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
52926 + break;
52927 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
52928 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
52929 + tmpReg = NIA_KG_CC_EN;
52930 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
52931 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
52932 + if (p_PcdParams->p_KgParams->directScheme)
52933 + {
52934 + physicalSchemeId = FmPcdKgGetSchemeId(
52935 + p_PcdParams->p_KgParams->h_DirectScheme);
52936 + /* check that this scheme was bound to this port */
52937 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
52938 + if (p_PcdParams->p_KgParams->h_DirectScheme
52939 + == p_PcdParams->p_KgParams->h_Schemes[i])
52940 + break;
52941 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
52942 + RETURN_ERROR(
52943 + MAJOR,
52944 + E_INVALID_VALUE,
52945 + ("Direct scheme is not one of the port selected schemes."));
52946 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
52947 + }
52948 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
52949 + break;
52950 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
52951 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
52952 + WRITE_UINT32(*p_BmiPrsNia,
52953 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
52954 + break;
52955 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
52956 + break;
52957 + default:
52958 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
52959 + }
52960 +
52961 + /* set start parsing offset */
52962 + WRITE_UINT32(*p_BmiPrsStartOffset,
52963 + p_PcdParams->p_PrsParams->parsingOffset);
52964 +
52965 + /************************************/
52966 + /* Parser port parameters */
52967 + /************************************/
52968 + /* stop before configuring */
52969 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
52970 + /* wait for parser to be in idle state */
52971 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
52972 + ;
52973 +
52974 + /* set soft seq attachment register */
52975 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
52976 +
52977 + /* set protocol options */
52978 + for (i = 0; p_FmPort->optArray[i]; i++)
52979 + switch (p_FmPort->optArray[i])
52980 + {
52981 + case (ETH_BROADCAST):
52982 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
52983 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
52984 + break;
52985 + case (ETH_MULTICAST):
52986 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
52987 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
52988 + break;
52989 + case (VLAN_STACKED):
52990 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
52991 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
52992 + break;
52993 + case (MPLS_STACKED):
52994 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
52995 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
52996 + break;
52997 + case (IPV4_BROADCAST_1):
52998 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52999 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
53000 + break;
53001 + case (IPV4_MULTICAST_1):
53002 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53003 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
53004 + break;
53005 + case (IPV4_UNICAST_2):
53006 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53007 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
53008 + break;
53009 + case (IPV4_MULTICAST_BROADCAST_2):
53010 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53011 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
53012 + break;
53013 + case (IPV6_MULTICAST_1):
53014 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53015 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
53016 + break;
53017 + case (IPV6_UNICAST_2):
53018 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53019 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
53020 + break;
53021 + case (IPV6_MULTICAST_2):
53022 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53023 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
53024 + break;
53025 + }
53026 +
53027 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53028 + HEADER_TYPE_UDP_ENCAP_ESP))
53029 + {
53030 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
53031 + RETURN_ERROR(
53032 + MINOR, E_INVALID_VALUE,
53033 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
53034 +
53035 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
53036 + HEADER_TYPE_UDP;
53037 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
53038 + TRUE;
53039 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
53040 + }
53041 +
53042 + /* set MPLS default next header - HW reset workaround */
53043 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53044 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
53045 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
53046 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
53047 +
53048 + /* for GRE, disable errors */
53049 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
53050 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
53051 +
53052 + /* For UDP remove PAD from L4 checksum calculation */
53053 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
53054 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
53055 + /* For TCP remove PAD from L4 checksum calculation */
53056 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
53057 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
53058 +
53059 + /* config additional params for specific headers */
53060 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
53061 + i++)
53062 + {
53063 + /* case for using sw parser as the initial NIA address, before
53064 + * HW parsing
53065 + */
53066 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
53067 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
53068 + {
53069 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
53070 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
53071 + if (initialSwPrs == ILLEGAL_BASE)
53072 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53073 +
53074 + /* clear parser first HXS */
53075 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
53076 + /* rewrite with soft parser start */
53077 + p_FmPort->savedBmiNia |= initialSwPrs;
53078 + continue;
53079 + }
53080 +
53081 + hdrNum =
53082 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
53083 + if (hdrNum == ILLEGAL_HDR_NUM)
53084 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53085 + if (hdrNum == NO_HDR_NUM)
53086 + RETURN_ERROR(
53087 + MAJOR, E_INVALID_VALUE,
53088 + ("Private headers may not use additional parameters"));
53089 +
53090 + err = AdditionalPrsParams(
53091 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
53092 + &tmpHxs[hdrNum]);
53093 + if (err)
53094 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53095 + }
53096 +
53097 + /* Check if ip-reassembly port - need to link sw-parser code */
53098 + if (p_FmPort->h_IpReassemblyManip)
53099 + {
53100 + /* link to sw parser code for IP Frag - only if no other code is applied. */
53101 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53102 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53103 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
53104 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53105 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53106 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
53107 + } else {
53108 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
53109 + {
53110 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53111 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53112 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53113 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53114 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
53115 + {
53116 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53117 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53118 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53119 + }
53120 + }
53121 +
53122 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
53123 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53124 + HEADER_TYPE_UDP_LITE))
53125 + {
53126 + /* link to sw parser code for udp lite - only if no other code is applied. */
53127 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53128 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53129 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
53130 + }
53131 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
53132 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
53133 + {
53134 + /* For all header set LCV as taken from netEnv*/
53135 + WRITE_UINT32(
53136 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
53137 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
53138 + /* set HXS register according to default+Additional params+protocol options */
53139 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
53140 + tmpHxs[i]);
53141 + }
53142 +
53143 + /* set tpid. */
53144 + tmpReg = PRS_TPID_DFLT;
53145 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
53146 + {
53147 + tmpReg &= PRS_TPID2_MASK;
53148 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
53149 + << PRS_PCTPID_SHIFT;
53150 + }
53151 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
53152 + {
53153 + tmpReg &= PRS_TPID1_MASK;
53154 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
53155 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
53156 +
53157 + /* enable parser */
53158 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
53159 +
53160 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
53161 + p_FmPort->privateInfo =
53162 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
53163 +
53164 + } /* end parser */
53165 + else {
53166 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53167 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53168 + {
53169 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53170 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
53171 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
53172 + }
53173 +
53174 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53175 +
53176 + p_FmPort->privateInfo = 0;
53177 + }
53178 +
53179 + FmPortCheckNApplyMacsec(p_FmPort);
53180 +
53181 + WRITE_UINT32(
53182 + *p_BmiPrsStartOffset,
53183 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
53184 +
53185 + /* set initial parser result - used for all engines */
53186 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
53187 + {
53188 + if (!i)
53189 + WRITE_UINT32(
53190 + *(p_BmiInitPrsResult),
53191 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
53192 + else
53193 + {
53194 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
53195 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
53196 + else
53197 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
53198 + }
53199 + }
53200 +
53201 + return E_OK;
53202 +}
53203 +
53204 +static t_Error DeletePcd(t_FmPort *p_FmPort)
53205 +{
53206 + t_Error err = E_OK;
53207 + volatile uint32_t *p_BmiNia = NULL;
53208 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53209 +
53210 + ASSERT_COND(p_FmPort);
53211 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53212 +
53213 + if (p_FmPort->imEn)
53214 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53215 + ("available for non-independant mode ports only"));
53216 +
53217 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53218 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53219 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53220 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53221 + ("available for Rx and offline parsing ports only"));
53222 +
53223 + if (!p_FmPort->pcdEngines)
53224 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
53225 +
53226 + /* get PCD registers pointers */
53227 + switch (p_FmPort->portType)
53228 + {
53229 + case (e_FM_PORT_TYPE_RX_10G):
53230 + case (e_FM_PORT_TYPE_RX):
53231 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53232 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53233 + break;
53234 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53235 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53236 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53237 + break;
53238 + default:
53239 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53240 + }
53241 +
53242 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53243 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53244 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53245 + ("port has to be detached previousely"));
53246 +
53247 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53248 +
53249 + /* "cut" PCD out of the port's flow - go to BMI */
53250 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
53251 +
53252 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53253 + {
53254 + /* stop parser */
53255 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53256 + /* wait for parser to be in idle state */
53257 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53258 + ;
53259 + }
53260 +
53261 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53262 + {
53263 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53264 +
53265 + /* unbind all schemes */
53266 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
53267 + &schemeBind);
53268 +
53269 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53270 + if (err)
53271 + RETURN_ERROR(MAJOR, err, NO_MSG);
53272 +
53273 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
53274 + p_FmPort->hardwarePortId,
53275 + p_FmPort->clsPlanGrpId);
53276 + if (err)
53277 + RETURN_ERROR(MAJOR, err, NO_MSG);
53278 + p_FmPort->useClsPlan = FALSE;
53279 + }
53280 +
53281 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53282 + {
53283 + /* unbind - we need to get the treeId too */
53284 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
53285 + if (err)
53286 + RETURN_ERROR(MAJOR, err, NO_MSG);
53287 + }
53288 +
53289 + p_FmPort->pcdEngines = 0;
53290 +
53291 + return E_OK;
53292 +}
53293 +
53294 +static t_Error AttachPCD(t_FmPort *p_FmPort)
53295 +{
53296 + volatile uint32_t *p_BmiNia = NULL;
53297 +
53298 + ASSERT_COND(p_FmPort);
53299 +
53300 + /* get PCD registers pointers */
53301 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53302 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53303 + else
53304 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53305 +
53306 + /* check that current NIA is BMI to BMI */
53307 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
53308 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53309 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53310 + ("may be called only for ports in BMI-to-BMI state."));
53311 +
53312 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53313 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
53314 + p_FmPort->orFmanCtrl) != E_OK)
53315 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53316 +
53317 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
53318 + {
53319 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53320 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
53321 + p_FmPort->savedBmiCmne);
53322 + else
53323 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
53324 + p_FmPort->savedBmiCmne);
53325 + }
53326 +
53327 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53328 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
53329 + p_FmPort->savedQmiPnen);
53330 +
53331 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53332 + {
53333 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53334 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53335 + p_FmPort->savedBmiFene);
53336 + else
53337 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53338 + p_FmPort->savedBmiFene);
53339 + }
53340 +
53341 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
53342 + {
53343 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53344 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
53345 + p_FmPort->savedBmiFpne);
53346 + else
53347 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
53348 + p_FmPort->savedBmiFpne);
53349 + }
53350 +
53351 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
53352 + {
53353 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
53354 +
53355 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
53356 + p_FmPort->savedBmiOfp);
53357 + }
53358 +
53359 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
53360 +
53361 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53362 + {
53363 + p_FmPort->origNonRxQmiRegsPndn =
53364 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
53365 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53366 + p_FmPort->savedNonRxQmiRegsPndn);
53367 + }
53368 +
53369 + return E_OK;
53370 +}
53371 +
53372 +static t_Error DetachPCD(t_FmPort *p_FmPort)
53373 +{
53374 + volatile uint32_t *p_BmiNia = NULL;
53375 +
53376 + ASSERT_COND(p_FmPort);
53377 +
53378 + /* get PCD registers pointers */
53379 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53380 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53381 + p_FmPort->origNonRxQmiRegsPndn);
53382 +
53383 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53384 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53385 + else
53386 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53387 +
53388 + WRITE_UINT32(
53389 + *p_BmiNia,
53390 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
53391 +
53392 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
53393 + FmPcdHcSync(p_FmPort->h_FmPcd);
53394 +
53395 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53396 + {
53397 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53398 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53399 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53400 + else
53401 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53402 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53403 + }
53404 +
53405 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53406 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
53407 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
53408 +
53409 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53410 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
53411 + p_FmPort->orFmanCtrl) != E_OK)
53412 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53413 +
53414 + p_FmPort->requiredAction = 0;
53415 +
53416 + return E_OK;
53417 +}
53418 +
53419 +/*****************************************************************************/
53420 +/* Inter-module API routines */
53421 +/*****************************************************************************/
53422 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
53423 +{
53424 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53425 + volatile uint32_t *p_BmiCfgReg = NULL;
53426 + uint32_t tmpReg;
53427 +
53428 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
53429 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53430 +
53431 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
53432 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
53433 + {
53434 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
53435 + return;
53436 + }
53437 +
53438 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
53439 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
53440 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
53441 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
53442 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
53443 +
53444 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
53445 +}
53446 +
53447 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
53448 +{
53449 + return ((t_FmPort*)h_FmPort)->netEnvId;
53450 +}
53451 +
53452 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
53453 +{
53454 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
53455 +}
53456 +
53457 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
53458 +{
53459 + return ((t_FmPort*)h_FmPort)->pcdEngines;
53460 +}
53461 +
53462 +#if (DPAA_VERSION >= 11)
53463 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
53464 + void **p_Value)
53465 +{
53466 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53467 + uint32_t muramPageOffset;
53468 +
53469 + ASSERT_COND(p_FmPort);
53470 + ASSERT_COND(p_Value);
53471 +
53472 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
53473 + {
53474 + if (p_FmPort->gprFunc != gprFunc)
53475 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53476 + ("gpr was assigned with different func"));
53477 + }
53478 + else
53479 + {
53480 + switch (gprFunc)
53481 + {
53482 + case (e_FM_PORT_GPR_MURAM_PAGE):
53483 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
53484 + 256, 8);
53485 + if (!p_FmPort->p_ParamsPage)
53486 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
53487 +
53488 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
53489 + muramPageOffset =
53490 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
53491 + - p_FmPort->fmMuramPhysBaseAddr);
53492 + switch (p_FmPort->portType)
53493 + {
53494 + case (e_FM_PORT_TYPE_RX_10G):
53495 + case (e_FM_PORT_TYPE_RX):
53496 + WRITE_UINT32(
53497 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
53498 + muramPageOffset);
53499 + break;
53500 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53501 + WRITE_UINT32(
53502 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
53503 + muramPageOffset);
53504 + break;
53505 + default:
53506 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53507 + ("Invalid port type"));
53508 + }
53509 + break;
53510 + default:
53511 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53512 + }
53513 + p_FmPort->gprFunc = gprFunc;
53514 + }
53515 +
53516 + switch (p_FmPort->gprFunc)
53517 + {
53518 + case (e_FM_PORT_GPR_MURAM_PAGE):
53519 + *p_Value = p_FmPort->p_ParamsPage;
53520 + break;
53521 + default:
53522 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53523 + }
53524 +
53525 + return E_OK;
53526 +}
53527 +#endif /* (DPAA_VERSION >= 11) */
53528 +
53529 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
53530 + t_FmPortGetSetCcParams *p_CcParams)
53531 +{
53532 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53533 + int tmpInt;
53534 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53535 +
53536 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
53537 +
53538 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
53539 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
53540 + {
53541 + p_CcParams->getCcParams.prOffset =
53542 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
53543 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
53544 + }
53545 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
53546 + {
53547 + p_CcParams->getCcParams.hardwarePortId =
53548 + (uint8_t)p_FmPort->hardwarePortId;
53549 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
53550 + }
53551 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
53552 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
53553 + {
53554 + p_CcParams->getCcParams.dataOffset =
53555 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
53556 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
53557 + }
53558 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
53559 + {
53560 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
53561 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
53562 + }
53563 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
53564 + {
53565 + p_CcParams->getCcParams.numOfExtraTasks =
53566 + (uint8_t)p_FmPort->tasks.extra;
53567 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
53568 + }
53569 + if (p_CcParams->getCcParams.type & FM_REV)
53570 + {
53571 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
53572 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
53573 + p_CcParams->getCcParams.type &= ~FM_REV;
53574 + }
53575 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
53576 + {
53577 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53578 + p_CcParams->getCcParams.discardMask =
53579 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
53580 + else
53581 + p_CcParams->getCcParams.discardMask =
53582 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
53583 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
53584 + }
53585 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
53586 + {
53587 + p_CcParams->getCcParams.internalBufferOffset =
53588 + p_FmPort->internalBufferOffset;
53589 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
53590 + }
53591 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
53592 + {
53593 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53594 + p_CcParams->getCcParams.nia =
53595 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
53596 + else
53597 + p_CcParams->getCcParams.nia =
53598 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
53599 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
53600 + }
53601 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
53602 + {
53603 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53604 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53605 + p_CcParams->getCcParams.nia =
53606 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
53607 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
53608 + }
53609 +
53610 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53611 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
53612 + {
53613 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
53614 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
53615 + }
53616 +
53617 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53618 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
53619 + {
53620 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
53621 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
53622 + }
53623 + else
53624 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53625 + {
53626 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
53627 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53628 + ("PNEN was defined previously different"));
53629 + }
53630 +
53631 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53632 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
53633 + {
53634 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
53635 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
53636 + }
53637 + else
53638 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53639 + {
53640 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
53641 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53642 + ("PNDN was defined previously different"));
53643 + }
53644 +
53645 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53646 + && (p_CcParams->setCcParams.overwrite
53647 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
53648 + {
53649 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
53650 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
53651 + }
53652 + else
53653 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
53654 + {
53655 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
53656 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53657 + ("xFENE was defined previously different"));
53658 + }
53659 +
53660 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53661 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
53662 + {
53663 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
53664 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
53665 + }
53666 + else
53667 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
53668 + {
53669 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
53670 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53671 + ("xFPNE was defined previously different"));
53672 + }
53673 +
53674 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53675 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
53676 + {
53677 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
53678 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
53679 + }
53680 + else
53681 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
53682 + {
53683 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
53684 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
53685 + ("xCMNE was defined previously different"));
53686 + }
53687 +
53688 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
53689 + && !(p_FmPort->requiredAction & UPDATE_PSO))
53690 + {
53691 + /* get PCD registers pointers */
53692 + switch (p_FmPort->portType)
53693 + {
53694 + case (e_FM_PORT_TYPE_RX_10G):
53695 + case (e_FM_PORT_TYPE_RX):
53696 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53697 + break;
53698 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53699 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53700 + break;
53701 + default:
53702 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53703 + }
53704 +
53705 + /* set start parsing offset */
53706 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
53707 + + p_CcParams->setCcParams.psoSize;
53708 + if (tmpInt > 0)
53709 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
53710 +
53711 + p_FmPort->requiredAction |= UPDATE_PSO;
53712 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
53713 + }
53714 + else
53715 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
53716 + {
53717 + if (p_FmPort->savedPrsStartOffset
53718 + != p_CcParams->setCcParams.psoSize)
53719 + RETURN_ERROR(
53720 + MAJOR,
53721 + E_INVALID_STATE,
53722 + ("parser start offset was defoned previousley different"));
53723 + }
53724 +
53725 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
53726 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
53727 + {
53728 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53729 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53730 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
53731 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
53732 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
53733 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
53734 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
53735 + }
53736 +
53737 + return E_OK;
53738 +}
53739 +/*********************** End of inter-module routines ************************/
53740 +
53741 +/****************************************/
53742 +/* API Init unit functions */
53743 +/****************************************/
53744 +
53745 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
53746 +{
53747 + t_FmPort *p_FmPort;
53748 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
53749 + uint32_t tmpReg;
53750 +
53751 + /* Allocate FM structure */
53752 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
53753 + if (!p_FmPort)
53754 + {
53755 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
53756 + return NULL;
53757 + }
53758 + memset(p_FmPort, 0, sizeof(t_FmPort));
53759 +
53760 + /* Allocate the FM driver's parameters structure */
53761 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
53762 + sizeof(t_FmPortDriverParam));
53763 + if (!p_FmPort->p_FmPortDriverParam)
53764 + {
53765 + XX_Free(p_FmPort);
53766 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
53767 + return NULL;
53768 + }
53769 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
53770 +
53771 + /* Initialize FM port parameters which will be kept by the driver */
53772 + p_FmPort->portType = p_FmPortParams->portType;
53773 + p_FmPort->portId = p_FmPortParams->portId;
53774 + p_FmPort->pcdEngines = FM_PCD_NONE;
53775 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
53776 + p_FmPort->h_App = p_FmPortParams->h_App;
53777 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
53778 +
53779 + /* get FM revision */
53780 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
53781 +
53782 + /* calculate global portId number */
53783 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
53784 + p_FmPortParams->portId,
53785 + p_FmPort->fmRevInfo.majorRev,
53786 + p_FmPort->fmRevInfo.minorRev);
53787 +
53788 + if (p_FmPort->fmRevInfo.majorRev >= 6)
53789 + {
53790 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
53791 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
53792 + DBG(WARNING,
53793 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
53794 + FM_OH_PORT_ID));
53795 +
53796 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53797 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
53798 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
53799 + }
53800 +
53801 + /* Set up FM port parameters for initialization phase only */
53802 +
53803 + /* First, fill in flibs struct */
53804 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
53805 + (enum fman_port_type)p_FmPort->portType);
53806 + /* Overwrite some integration specific parameters */
53807 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
53808 + DEFAULT_PORT_rxFifoPriElevationLevel;
53809 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
53810 + DEFAULT_PORT_rxFifoThreshold;
53811 +
53812 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
53813 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
53814 +#else
53815 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
53816 +#endif
53817 + if ((p_FmPort->fmRevInfo.majorRev == 6)
53818 + && (p_FmPort->fmRevInfo.minorRev == 0))
53819 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
53820 + else
53821 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
53822 +
53823 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
53824 + if (p_FmPort->fmRevInfo.majorRev < 6)
53825 + {
53826 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
53827 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
53828 + TRUE;
53829 +#endif
53830 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
53831 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
53832 + }
53833 + else
53834 + {
53835 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
53836 + FALSE;
53837 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
53838 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
53839 + }
53840 + if (p_FmPort->fmRevInfo.majorRev == 4)
53841 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
53842 + else
53843 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
53844 +
53845 + /* Continue with other parameters */
53846 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
53847 + /* set memory map pointers */
53848 + p_FmPort->p_FmPortQmiRegs =
53849 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
53850 + p_FmPort->p_FmPortBmiRegs =
53851 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
53852 + p_FmPort->p_FmPortPrsRegs =
53853 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
53854 +
53855 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
53856 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
53857 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
53858 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
53859 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
53860 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
53861 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
53862 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
53863 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
53864 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
53865 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
53866 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
53867 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
53868 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
53869 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
53870 + */
53871 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
53872 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
53873 + DEFAULT_PORT_cheksumLastBytesIgnore;
53874 +
53875 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
53876 + /* resource distribution. */
53877 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
53878 + * BMI_FIFO_UNITS;
53879 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
53880 + * BMI_FIFO_UNITS;
53881 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
53882 + p_FmPort->openDmas.extra =
53883 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
53884 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
53885 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
53886 +
53887 +
53888 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
53889 + if ((p_FmPort->fmRevInfo.majorRev == 6)
53890 + && (p_FmPort->fmRevInfo.minorRev == 0)
53891 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53892 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
53893 + {
53894 + p_FmPort->openDmas.num = 16;
53895 + p_FmPort->openDmas.extra = 0;
53896 + }
53897 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
53898 +
53899 + /* Port type specific initialization: */
53900 + switch (p_FmPort->portType)
53901 + {
53902 + case (e_FM_PORT_TYPE_RX):
53903 + case (e_FM_PORT_TYPE_RX_10G):
53904 + /* Initialize FM port parameters for initialization phase only */
53905 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
53906 + DEFAULT_PORT_cutBytesFromEnd;
53907 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
53908 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
53909 + DEFAULT_PORT_frmDiscardOverride;
53910 +
53911 + tmpReg =
53912 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
53913 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
53914 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
53915 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
53916 + * BMI_FIFO_UNITS;
53917 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
53918 + & BMI_RX_FIFO_THRESHOLD_MASK)
53919 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
53920 +
53921 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
53922 + DEFAULT_PORT_BufMargins_endMargins;
53923 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
53924 + DEFAULT_PORT_errorsToDiscard;
53925 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
53926 + DEFAULT_PORT_forwardIntContextReuse;
53927 +#if (DPAA_VERSION >= 11)
53928 + p_FmPort->p_FmPortDriverParam->noScatherGather =
53929 + DEFAULT_PORT_noScatherGather;
53930 +#endif /* (DPAA_VERSION >= 11) */
53931 + break;
53932 +
53933 + case (e_FM_PORT_TYPE_TX):
53934 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
53935 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
53936 + tmpReg = 0x00001013;
53937 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
53938 + tmpReg);
53939 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
53940 + case (e_FM_PORT_TYPE_TX_10G):
53941 + tmpReg =
53942 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
53943 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
53944 + & BMI_TX_FIFO_MIN_FILL_MASK)
53945 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
53946 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
53947 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
53948 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
53949 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
53950 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
53951 + * BMI_FIFO_UNITS;
53952 +
53953 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
53954 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
53955 + DEFAULT_PORT_deqPrefetchOption;
53956 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
53957 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
53958 + DEFAULT_PORT_deqHighPriority_10G);
53959 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
53960 + (uint16_t)(
53961 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
53962 + DEFAULT_PORT_deqByteCnt_10G);
53963 + break;
53964 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53965 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
53966 + DEFAULT_PORT_errorsToDiscard;
53967 +#if (DPAA_VERSION >= 11)
53968 + p_FmPort->p_FmPortDriverParam->noScatherGather =
53969 + DEFAULT_PORT_noScatherGather;
53970 +#endif /* (DPAA_VERSION >= 11) */
53971 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
53972 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
53973 + DEFAULT_PORT_deqPrefetchOption_HC;
53974 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
53975 + DEFAULT_PORT_deqHighPriority_1G;
53976 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
53977 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
53978 + DEFAULT_PORT_deqByteCnt_1G;
53979 +
53980 + tmpReg =
53981 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
53982 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
53983 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
53984 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
53985 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
53986 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
53987 + {
53988 + /* Overwrite HC defaults */
53989 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
53990 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
53991 + }
53992 +
53993 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
53994 + if (p_FmPort->fmRevInfo.majorRev < 6)
53995 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
53996 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
53997 +
53998 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
53999 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54000 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54001 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
54002 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54003 + break;
54004 +
54005 + default:
54006 + XX_Free(p_FmPort->p_FmPortDriverParam);
54007 + XX_Free(p_FmPort);
54008 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54009 + return NULL;
54010 + }
54011 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
54012 + if (p_FmPort->fmRevInfo.majorRev == 4)
54013 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
54014 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
54015 +
54016 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
54017 +
54018 + if (p_FmPort->imEn)
54019 + {
54020 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
54021 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
54022 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54023 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
54024 + FmPortConfigIM(p_FmPort, p_FmPortParams);
54025 + }
54026 + else
54027 + {
54028 + switch (p_FmPort->portType)
54029 + {
54030 + case (e_FM_PORT_TYPE_RX):
54031 + case (e_FM_PORT_TYPE_RX_10G):
54032 + /* Initialize FM port parameters for initialization phase only */
54033 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54034 + &p_FmPortParams->specificParams.rxParams.extBufPools,
54035 + sizeof(t_FmExtPools));
54036 + p_FmPort->p_FmPortDriverParam->errFqid =
54037 + p_FmPortParams->specificParams.rxParams.errFqid;
54038 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54039 + p_FmPortParams->specificParams.rxParams.dfltFqid;
54040 + p_FmPort->p_FmPortDriverParam->liodnOffset =
54041 + p_FmPortParams->specificParams.rxParams.liodnOffset;
54042 + break;
54043 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54044 + case (e_FM_PORT_TYPE_TX):
54045 + case (e_FM_PORT_TYPE_TX_10G):
54046 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54047 + p_FmPort->p_FmPortDriverParam->errFqid =
54048 + p_FmPortParams->specificParams.nonRxParams.errFqid;
54049 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
54050 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
54051 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
54052 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54053 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
54054 + break;
54055 + default:
54056 + XX_Free(p_FmPort->p_FmPortDriverParam);
54057 + XX_Free(p_FmPort);
54058 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54059 + return NULL;
54060 + }
54061 + }
54062 +
54063 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
54064 + if (Sprint(
54065 + p_FmPort->name,
54066 + "FM-%d-port-%s-%d",
54067 + FmGetId(p_FmPort->h_Fm),
54068 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
54069 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
54070 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
54071 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
54072 + (p_FmPort->portType
54073 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
54074 + "10g-TX")))),
54075 + p_FmPort->portId) == 0)
54076 + {
54077 + XX_Free(p_FmPort->p_FmPortDriverParam);
54078 + XX_Free(p_FmPort);
54079 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54080 + return NULL;
54081 + }
54082 +
54083 + p_FmPort->h_Spinlock = XX_InitSpinlock();
54084 + if (!p_FmPort->h_Spinlock)
54085 + {
54086 + XX_Free(p_FmPort->p_FmPortDriverParam);
54087 + XX_Free(p_FmPort);
54088 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54089 + return NULL;
54090 + }
54091 +
54092 + return p_FmPort;
54093 +}
54094 +
54095 +t_FmPort *rx_port = 0;
54096 +t_FmPort *tx_port = 0;
54097 +
54098 +/**************************************************************************//**
54099 + @Function FM_PORT_Init
54100 +
54101 + @Description Initializes the FM module
54102 +
54103 + @Param[in] h_FmPort - FM module descriptor
54104 +
54105 + @Return E_OK on success; Error code otherwise.
54106 + *//***************************************************************************/
54107 +t_Error FM_PORT_Init(t_Handle h_FmPort)
54108 +{
54109 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54110 + t_FmPortDriverParam *p_DriverParams;
54111 + t_Error errCode;
54112 + t_FmInterModulePortInitParams fmParams;
54113 + t_FmRevisionInfo revInfo;
54114 +
54115 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
54116 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54117 +
54118 + errCode = FmSpBuildBufferStructure(
54119 + &p_FmPort->p_FmPortDriverParam->intContext,
54120 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54121 + &p_FmPort->p_FmPortDriverParam->bufMargins,
54122 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
54123 + if (errCode != E_OK)
54124 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54125 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54126 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
54127 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54128 + {
54129 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
54130 + if (!p_FmPort->fifoBufs.num)
54131 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
54132 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
54133 + }
54134 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54135 +
54136 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
54137 +
54138 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
54139 +
54140 + /* Set up flibs port structure */
54141 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
54142 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
54143 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54144 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
54145 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
54146 + p_FmPort->port.bmi_regs =
54147 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
54148 + p_FmPort->port.qmi_regs =
54149 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
54150 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
54151 + p_FmPort->port.im_en = p_FmPort->imEn;
54152 + p_FmPort->p_FmPortPrsRegs =
54153 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
54154 +
54155 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54156 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
54157 + {
54158 + /* Call the external Buffer routine which also checks fifo
54159 + size and updates it if necessary */
54160 + /* define external buffer pools and pool depletion*/
54161 + errCode = SetExtBufferPools(p_FmPort);
54162 + if (errCode)
54163 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54164 + /* check if the largest external buffer pool is large enough */
54165 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
54166 + + p_DriverParams->bufMargins.endMargins
54167 + > p_FmPort->rxPoolsParams.largestBufSize)
54168 + RETURN_ERROR(
54169 + MAJOR,
54170 + E_INVALID_VALUE,
54171 + ("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));
54172 + }
54173 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54174 + {
54175 + {
54176 +#ifdef FM_NO_OP_OBSERVED_POOLS
54177 + t_FmRevisionInfo revInfo;
54178 +
54179 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54180 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
54181 +#endif /* FM_NO_OP_OBSERVED_POOLS */
54182 + {
54183 + /* define external buffer pools */
54184 + errCode = SetExtBufferPools(p_FmPort);
54185 + if (errCode)
54186 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54187 + }
54188 + }
54189 + }
54190 +
54191 + /************************************************************/
54192 + /* Call FM module routine for communicating parameters */
54193 + /************************************************************/
54194 + memset(&fmParams, 0, sizeof(fmParams));
54195 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54196 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54197 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
54198 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
54199 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
54200 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
54201 +
54202 + if (p_FmPort->fifoBufs.num)
54203 + {
54204 + errCode = VerifySizeOfFifo(p_FmPort);
54205 + if (errCode != E_OK)
54206 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54207 + }
54208 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
54209 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
54210 + fmParams.independentMode = p_FmPort->imEn;
54211 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
54212 + fmParams.liodnBase = p_DriverParams->liodnBase;
54213 + fmParams.deqPipelineDepth =
54214 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54215 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
54216 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54217 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
54218 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54219 + {
54220 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54221 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54222 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
54223 + * for deq threshold calculation.
54224 + */
54225 + fmParams.deqPipelineDepth = 2;
54226 + }
54227 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54228 +
54229 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
54230 + if (errCode)
54231 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54232 +
54233 + /* get params for use in init */
54234 + p_FmPort->fmMuramPhysBaseAddr =
54235 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
54236 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
54237 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
54238 +
54239 + errCode = InitLowLevelDriver(p_FmPort);
54240 + if (errCode != E_OK)
54241 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54242 +
54243 + FmPortDriverParamFree(p_FmPort);
54244 +
54245 +#if (DPAA_VERSION >= 11)
54246 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54247 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
54248 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54249 + {
54250 + t_FmPcdCtrlParamsPage *p_ParamsPage;
54251 +
54252 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
54253 + (void**)&p_ParamsPage);
54254 + ASSERT_COND(p_ParamsPage);
54255 +
54256 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
54257 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
54258 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54259 + {
54260 + WRITE_UINT32(
54261 + p_ParamsPage->misc,
54262 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
54263 + WRITE_UINT32(
54264 + p_ParamsPage->discardMask,
54265 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
54266 + }
54267 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
54268 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
54269 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54270 + WRITE_UINT32(
54271 + p_ParamsPage->errorsDiscardMask,
54272 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
54273 + else
54274 + WRITE_UINT32(
54275 + p_ParamsPage->errorsDiscardMask,
54276 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
54277 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
54278 + }
54279 +#endif /* (DPAA_VERSION >= 11) */
54280 +
54281 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
54282 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
54283 + return E_OK;
54284 +}
54285 +
54286 +/**************************************************************************//**
54287 + @Function FM_PORT_Free
54288 +
54289 + @Description Frees all resources that were assigned to FM module.
54290 +
54291 + Calling this routine invalidates the descriptor.
54292 +
54293 + @Param[in] h_FmPort - FM module descriptor
54294 +
54295 + @Return E_OK on success; Error code otherwise.
54296 + *//***************************************************************************/
54297 +t_Error FM_PORT_Free(t_Handle h_FmPort)
54298 +{
54299 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54300 + t_FmInterModulePortFreeParams fmParams;
54301 +
54302 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54303 +
54304 + if (p_FmPort->pcdEngines)
54305 + RETURN_ERROR(
54306 + MAJOR,
54307 + E_INVALID_STATE,
54308 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
54309 +
54310 + if (p_FmPort->enabled)
54311 + {
54312 + if (FM_PORT_Disable(p_FmPort) != E_OK)
54313 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
54314 + }
54315 +
54316 + if (p_FmPort->imEn)
54317 + FmPortImFree(p_FmPort);
54318 +
54319 + FmPortDriverParamFree(p_FmPort);
54320 +
54321 + memset(&fmParams, 0, sizeof(fmParams));
54322 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54323 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54324 + fmParams.deqPipelineDepth =
54325 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54326 +
54327 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
54328 +
54329 +#if (DPAA_VERSION >= 11)
54330 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
54331 + != E_OK)
54332 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
54333 +
54334 + if (p_FmPort->p_ParamsPage)
54335 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
54336 +#endif /* (DPAA_VERSION >= 11) */
54337 +
54338 + if (p_FmPort->h_Spinlock)
54339 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
54340 +
54341 + XX_Free(p_FmPort);
54342 +
54343 + return E_OK;
54344 +}
54345 +
54346 +/*************************************************/
54347 +/* API Advanced Init unit functions */
54348 +/*************************************************/
54349 +
54350 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
54351 +{
54352 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54353 +
54354 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54355 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54356 +
54357 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
54358 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
54359 +
54360 + return E_OK;
54361 +}
54362 +
54363 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
54364 +{
54365 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54366 +
54367 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54368 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54369 +
54370 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54371 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
54372 + return E_OK;
54373 +}
54374 +
54375 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54376 +{
54377 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54378 +
54379 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54380 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54381 +
54382 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
54383 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54384 +
54385 + return E_OK;
54386 +}
54387 +
54388 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
54389 +{
54390 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54391 +
54392 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54393 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54394 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54395 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54396 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
54397 +
54398 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
54399 +
54400 + return E_OK;
54401 +}
54402 +
54403 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
54404 +{
54405 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54406 +
54407 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54408 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54409 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54410 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54411 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54412 + ("not available for Rx ports"));
54413 +
54414 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
54415 + (enum fman_port_deq_type)deqType;
54416 +
54417 + return E_OK;
54418 +}
54419 +
54420 +t_Error FM_PORT_ConfigDeqPrefetchOption(
54421 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
54422 +{
54423 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54424 +
54425 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54426 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54427 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54428 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54429 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54430 + ("not available for Rx ports"));
54431 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
54432 + (enum fman_port_deq_prefetch)deqPrefetchOption;
54433 +
54434 + return E_OK;
54435 +}
54436 +
54437 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
54438 + t_FmBackupBmPools *p_BackupBmPools)
54439 +{
54440 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54441 +
54442 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54443 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54444 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54445 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54446 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54447 + ("available for Rx ports only"));
54448 +
54449 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
54450 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
54451 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54452 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
54453 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
54454 + sizeof(t_FmBackupBmPools));
54455 +
54456 + return E_OK;
54457 +}
54458 +
54459 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
54460 +{
54461 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54462 +
54463 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54464 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54465 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54466 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54467 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54468 + ("not available for Rx ports"));
54469 +
54470 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
54471 +
54472 + return E_OK;
54473 +}
54474 +
54475 +t_Error FM_PORT_ConfigBufferPrefixContent(
54476 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
54477 +{
54478 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54479 +
54480 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54481 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54482 +
54483 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54484 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
54485 + /* if dataAlign was not initialized by user, we return to driver's default */
54486 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
54487 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54488 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54489 +
54490 + return E_OK;
54491 +}
54492 +
54493 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
54494 + uint8_t checksumLastBytesIgnore)
54495 +{
54496 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54497 +
54498 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54499 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54500 +
54501 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
54502 + checksumLastBytesIgnore;
54503 +
54504 + return E_OK;
54505 +}
54506 +
54507 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
54508 + uint8_t cutBytesFromEnd)
54509 +{
54510 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54511 +
54512 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54513 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54514 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54515 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54516 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54517 + ("available for Rx ports only"));
54518 +
54519 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
54520 +
54521 + return E_OK;
54522 +}
54523 +
54524 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
54525 + t_FmBufPoolDepletion *p_BufPoolDepletion)
54526 +{
54527 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54528 +
54529 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54530 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54531 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54532 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54533 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54534 + ("available for Rx ports only"));
54535 +
54536 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54537 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
54538 + sizeof(t_FmBufPoolDepletion));
54539 +
54540 + return E_OK;
54541 +}
54542 +
54543 +t_Error FM_PORT_ConfigObservedPoolDepletion(
54544 + t_Handle h_FmPort,
54545 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
54546 +{
54547 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54548 +
54549 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54550 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54551 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54552 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54553 + ("available for OP ports only"));
54554 +
54555 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54556 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
54557 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
54558 + sizeof(t_FmBufPoolDepletion));
54559 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54560 + &p_FmPortObservedBufPoolDepletion->poolsParams,
54561 + sizeof(t_FmExtPools));
54562 +
54563 + return E_OK;
54564 +}
54565 +
54566 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
54567 +{
54568 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54569 +
54570 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54571 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54572 +
54573 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54574 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54575 + ("available for OP ports only"));
54576 +
54577 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
54578 + sizeof(t_FmExtPools));
54579 +
54580 + return E_OK;
54581 +}
54582 +
54583 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
54584 +{
54585 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54586 +
54587 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54588 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54589 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54590 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54591 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54592 + ("available for Tx ports only"));
54593 +
54594 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
54595 +
54596 + return E_OK;
54597 +}
54598 +
54599 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
54600 +{
54601 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54602 +
54603 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54604 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54605 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
54606 +
54607 + return E_OK;
54608 +}
54609 +
54610 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
54611 +{
54612 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54613 +
54614 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54615 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54616 +
54617 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54618 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54619 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54620 + ("Not available for Tx ports"));
54621 +
54622 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
54623 +
54624 + return E_OK;
54625 +}
54626 +
54627 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
54628 +{
54629 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54630 +
54631 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54632 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54633 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54634 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54635 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54636 + ("Not available for Tx ports"));
54637 +
54638 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
54639 +
54640 + return E_OK;
54641 +}
54642 +
54643 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
54644 + fmPortFrameErrSelect_t errs)
54645 +{
54646 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54647 +
54648 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54649 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54650 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54651 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54652 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54653 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
54654 + ("available for Rx and offline parsing ports only"));
54655 +
54656 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
54657 +
54658 + return E_OK;
54659 +}
54660 +
54661 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
54662 +{
54663 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54664 +
54665 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54666 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54667 +
54668 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
54669 + (enum fman_port_dma_swap)swapData;
54670 +
54671 + return E_OK;
54672 +}
54673 +
54674 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
54675 + e_FmDmaCacheOption intContextCacheAttr)
54676 +{
54677 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54678 +
54679 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54680 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54681 +
54682 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
54683 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
54684 +
54685 + return E_OK;
54686 +}
54687 +
54688 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
54689 + e_FmDmaCacheOption headerCacheAttr)
54690 +{
54691 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54692 +
54693 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54694 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54695 +
54696 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
54697 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
54698 +
54699 + return E_OK;
54700 +}
54701 +
54702 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
54703 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
54704 +{
54705 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54706 +
54707 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54708 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54709 +
54710 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
54711 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
54712 +
54713 + return E_OK;
54714 +}
54715 +
54716 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
54717 +{
54718 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54719 +
54720 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54721 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54722 +
54723 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54724 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54725 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54726 + ("Not available for Tx ports"));
54727 +
54728 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
54729 +
54730 + return E_OK;
54731 +}
54732 +
54733 +#if (DPAA_VERSION >= 11)
54734 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
54735 +{
54736 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54737 +
54738 + UNUSED(noScatherGather);
54739 + UNUSED(p_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->noScatherGather = noScatherGather;
54745 +
54746 + return E_OK;
54747 +}
54748 +#endif /* (DPAA_VERSION >= 11) */
54749 +
54750 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
54751 + bool forwardReuse)
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 +
54758 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54759 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54760 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54761 + ("available for Rx ports only"));
54762 +
54763 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
54764 +
54765 + return E_OK;
54766 +}
54767 +
54768 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
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 +
54775 + p_FmPort->maxFrameLength = length;
54776 +
54777 + return E_OK;
54778 +}
54779 +
54780 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54781 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
54782 +{
54783 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54784 +
54785 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54786 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54787 +
54788 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
54789 +
54790 + return E_OK;
54791 +}
54792 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54793 +
54794 +/****************************************************/
54795 +/* Hidden-DEBUG Only API */
54796 +/****************************************************/
54797 +
54798 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
54799 + uint32_t minFillLevel)
54800 +{
54801 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54802 +
54803 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54804 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54805 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54806 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54807 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54808 + ("available for Tx ports only"));
54809 +
54810 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
54811 +
54812 + return E_OK;
54813 +}
54814 +
54815 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
54816 + uint8_t deqPipelineDepth)
54817 +{
54818 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54819 +
54820 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54821 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54822 +
54823 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54824 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54825 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54826 + ("Not available for Rx ports"));
54827 +
54828 + if (p_FmPort->imEn)
54829 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54830 + ("Not available for IM ports!"));
54831 +
54832 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54833 + deqPipelineDepth;
54834 +
54835 + return E_OK;
54836 +}
54837 +
54838 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
54839 + uint32_t fifoLowComfLevel)
54840 +{
54841 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54842 +
54843 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54844 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54845 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54846 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54847 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54848 + ("available for Tx ports only"));
54849 +
54850 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
54851 + fifoLowComfLevel;
54852 +
54853 + return E_OK;
54854 +}
54855 +
54856 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
54857 +{
54858 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54859 +
54860 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54861 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54862 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54863 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54864 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54865 + ("available for Rx ports only"));
54866 +
54867 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
54868 +
54869 + return E_OK;
54870 +}
54871 +
54872 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
54873 + uint32_t priElevationLevel)
54874 +{
54875 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54876 +
54877 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54878 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54879 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54880 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54881 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54882 + ("available for Rx ports only"));
54883 +
54884 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
54885 +
54886 + return E_OK;
54887 +}
54888 +/****************************************************/
54889 +/* API Run-time Control unit functions */
54890 +/****************************************************/
54891 +
54892 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
54893 + t_FmPortRsrc *p_NumOfOpenDmas)
54894 +{
54895 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54896 + t_Error err;
54897 +
54898 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54899 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54900 +
54901 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
54902 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
54903 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
54904 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
54905 + RETURN_ERROR(
54906 + MAJOR,
54907 + E_INVALID_VALUE,
54908 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
54909 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
54910 + (uint8_t*)&p_NumOfOpenDmas->num,
54911 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
54912 + if (err)
54913 + RETURN_ERROR(MAJOR, err, NO_MSG);
54914 +
54915 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
54916 +
54917 + return E_OK;
54918 +}
54919 +
54920 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
54921 +{
54922 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54923 + t_Error err;
54924 +
54925 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54926 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54927 +
54928 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
54929 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
54930 +
54931 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
54932 + RETURN_ERROR(
54933 + MAJOR, E_INVALID_VALUE,
54934 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
54935 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
54936 + RETURN_ERROR(
54937 + MAJOR,
54938 + E_INVALID_VALUE,
54939 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
54940 +
54941 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
54942 + (uint8_t*)&p_NumOfTasks->num,
54943 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
54944 + if (err)
54945 + RETURN_ERROR(MAJOR, err, NO_MSG);
54946 +
54947 + /* update driver's struct */
54948 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54949 + return E_OK;
54950 +}
54951 +
54952 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54953 +{
54954 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54955 + t_Error err;
54956 +
54957 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54958 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54959 +
54960 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
54961 + RETURN_ERROR(
54962 + MAJOR,
54963 + E_INVALID_VALUE,
54964 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
54965 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
54966 + RETURN_ERROR(
54967 + MAJOR, E_INVALID_VALUE,
54968 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
54969 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
54970 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
54971 + {
54972 + /* extra FIFO size (allowed only to Rx ports) */
54973 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
54974 + RETURN_ERROR(
54975 + MAJOR,
54976 + E_INVALID_VALUE,
54977 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
54978 + }
54979 + else
54980 + if (p_SizeOfFifo->extra)
54981 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
54982 + (" No SizeOfFifo-extra for non Rx ports"));
54983 +
54984 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54985 +
54986 + /* we do not change user's parameter */
54987 + err = VerifySizeOfFifo(p_FmPort);
54988 + if (err)
54989 + RETURN_ERROR(MAJOR, err, NO_MSG);
54990 +
54991 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
54992 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
54993 + if (err)
54994 + RETURN_ERROR(MAJOR, err, NO_MSG);
54995 +
54996 + return E_OK;
54997 +}
54998 +
54999 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
55000 +{
55001 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55002 +
55003 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55004 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55005 + 0);
55006 +
55007 + return p_FmPort->bufferOffsets.dataOffset;
55008 +}
55009 +
55010 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
55011 +{
55012 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55013 +
55014 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55015 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55016 + NULL);
55017 +
55018 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
55019 + return NULL;
55020 +
55021 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
55022 +}
55023 +
55024 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
55025 +{
55026 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55027 +
55028 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55029 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55030 + NULL);
55031 +
55032 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
55033 + return NULL;
55034 +
55035 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
55036 +}
55037 +
55038 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
55039 +{
55040 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55041 +
55042 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55043 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55044 + NULL);
55045 +
55046 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
55047 + return NULL;
55048 +
55049 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
55050 +}
55051 +
55052 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
55053 +{
55054 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55055 +
55056 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55057 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55058 + NULL);
55059 +
55060 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
55061 + return NULL;
55062 +
55063 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
55064 +}
55065 +
55066 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
55067 +{
55068 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55069 + int err;
55070 +
55071 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55072 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55073 +
55074 + if (p_FmPort->imEn)
55075 + FmPortImDisable(p_FmPort);
55076 +
55077 + err = fman_port_disable(&p_FmPort->port);
55078 + if (err == -EBUSY)
55079 + {
55080 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
55081 + p_FmPort->name));
55082 + }
55083 + else
55084 + if (err != 0)
55085 + {
55086 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
55087 + }
55088 +
55089 + p_FmPort->enabled = FALSE;
55090 +
55091 + return E_OK;
55092 +}
55093 +
55094 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
55095 +{
55096 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55097 + int err;
55098 +
55099 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55100 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55101 +
55102 + /* Used by FM_PORT_Free routine as indication
55103 + if to disable port. Thus set it to TRUE prior
55104 + to enabling itself. This way if part of enable
55105 + process fails there will be still things
55106 + to disable during Free. For example, if BMI
55107 + enable succeeded but QMI failed, still BMI
55108 + needs to be disabled by Free. */
55109 + p_FmPort->enabled = TRUE;
55110 +
55111 + if (p_FmPort->imEn)
55112 + FmPortImEnable(p_FmPort);
55113 +
55114 + err = fman_port_enable(&p_FmPort->port);
55115 + if (err != 0)
55116 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
55117 +
55118 + return E_OK;
55119 +}
55120 +
55121 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
55122 +{
55123 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55124 + uint8_t factor, countUnitBit;
55125 + uint16_t baseGran;
55126 + struct fman_port_rate_limiter params;
55127 + int err;
55128 +
55129 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55130 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55131 +
55132 + switch (p_FmPort->portType)
55133 + {
55134 + case (e_FM_PORT_TYPE_TX_10G):
55135 + case (e_FM_PORT_TYPE_TX):
55136 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
55137 + break;
55138 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55139 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
55140 + break;
55141 + default:
55142 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55143 + ("available for Tx and Offline parsing ports only"));
55144 + }
55145 +
55146 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
55147 + /* normally, we use 1 usec as the reference count */
55148 + factor = 1;
55149 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
55150 + while (p_RateLimit->rateLimit < baseGran / factor)
55151 + {
55152 + if (countUnitBit == 31)
55153 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
55154 +
55155 + countUnitBit++;
55156 + factor <<= 1;
55157 + }
55158 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
55159 + if (p_RateLimit->rateLimit
55160 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
55161 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
55162 +
55163 + if (!p_RateLimit->maxBurstSize
55164 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
55165 + RETURN_ERROR(
55166 + MAJOR,
55167 + E_INVALID_VALUE,
55168 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
55169 +
55170 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
55171 + params.high_burst_size_gran = FALSE;
55172 + params.burst_size = p_RateLimit->maxBurstSize;
55173 + params.rate = p_RateLimit->rateLimit;
55174 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
55175 +
55176 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55177 + {
55178 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
55179 +
55180 + if ((p_FmPort->fmRevInfo.majorRev == 4)
55181 + || (p_FmPort->fmRevInfo.majorRev >= 6))
55182 + {
55183 + params.high_burst_size_gran = TRUE;
55184 + }
55185 + else
55186 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
55187 + {
55188 + if (p_RateLimit->rateLimitDivider
55189 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
55190 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
55191 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
55192 +
55193 + if (p_RateLimit->maxBurstSize % 1000)
55194 + {
55195 + p_RateLimit->maxBurstSize =
55196 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
55197 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
55198 + }
55199 + else
55200 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
55201 + / 1000);
55202 + }
55203 + params.rate_factor =
55204 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
55205 + params.burst_size = p_RateLimit->maxBurstSize;
55206 + }
55207 +
55208 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
55209 + if (err != 0)
55210 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55211 +
55212 + return E_OK;
55213 +}
55214 +
55215 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
55216 +{
55217 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55218 + int err;
55219 +
55220 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55221 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55222 +
55223 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55224 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55225 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55226 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55227 + ("available for Tx and Offline parsing ports only"));
55228 +
55229 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
55230 + if (err != 0)
55231 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55232 + return E_OK;
55233 +}
55234 +
55235 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
55236 + uint8_t wq)
55237 +{
55238 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55239 + uint32_t tmpReg;
55240 + uint32_t wqTmpReg;
55241 +
55242 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55243 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55244 +
55245 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
55246 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
55247 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55248 + ("PFC mapping is available for Tx ports only"));
55249 +
55250 + if (prio > 7)
55251 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55252 + ("PFC priority (%d) is out of range (0-7)", prio));
55253 + if (wq > 7)
55254 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55255 + ("WQ (%d) is out of range (0-7)", wq));
55256 +
55257 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
55258 + tmpReg &= ~(0xf << ((7 - prio) * 4));
55259 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
55260 + tmpReg |= wqTmpReg;
55261 +
55262 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
55263 + tmpReg);
55264 +
55265 + return E_OK;
55266 +}
55267 +
55268 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
55269 +{
55270 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55271 +
55272 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55273 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55274 +
55275 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
55276 +
55277 + return E_OK;
55278 +}
55279 +
55280 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
55281 +{
55282 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55283 + int err;
55284 +
55285 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55286 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55287 +
55288 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
55289 + if (err != 0)
55290 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
55291 + return E_OK;
55292 +}
55293 +
55294 +t_Error FM_PORT_SetPerformanceCountersParams(
55295 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
55296 +{
55297 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55298 + struct fman_port_perf_cnt_params params;
55299 + int err;
55300 +
55301 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55302 +
55303 + /* check parameters */
55304 + if (!p_FmPortPerformanceCnt->taskCompVal
55305 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
55306 + RETURN_ERROR(
55307 + MAJOR,
55308 + E_INVALID_VALUE,
55309 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
55310 + if (!p_FmPortPerformanceCnt->dmaCompVal
55311 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
55312 + RETURN_ERROR(
55313 + MAJOR,
55314 + E_INVALID_VALUE,
55315 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
55316 + if (!p_FmPortPerformanceCnt->fifoCompVal
55317 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
55318 + RETURN_ERROR(
55319 + MAJOR,
55320 + E_INVALID_VALUE,
55321 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
55322 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
55323 + RETURN_ERROR(
55324 + MAJOR,
55325 + E_INVALID_VALUE,
55326 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
55327 +
55328 + switch (p_FmPort->portType)
55329 + {
55330 + case (e_FM_PORT_TYPE_RX_10G):
55331 + case (e_FM_PORT_TYPE_RX):
55332 + if (!p_FmPortPerformanceCnt->queueCompVal
55333 + || (p_FmPortPerformanceCnt->queueCompVal
55334 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
55335 + RETURN_ERROR(
55336 + MAJOR,
55337 + E_INVALID_VALUE,
55338 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
55339 + break;
55340 + case (e_FM_PORT_TYPE_TX_10G):
55341 + case (e_FM_PORT_TYPE_TX):
55342 + if (!p_FmPortPerformanceCnt->queueCompVal
55343 + || (p_FmPortPerformanceCnt->queueCompVal
55344 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
55345 + RETURN_ERROR(
55346 + MAJOR,
55347 + E_INVALID_VALUE,
55348 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
55349 + break;
55350 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55351 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55352 + if (p_FmPortPerformanceCnt->queueCompVal)
55353 + RETURN_ERROR(
55354 + MAJOR,
55355 + E_INVALID_VALUE,
55356 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
55357 + break;
55358 + default:
55359 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55360 + }
55361 +
55362 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
55363 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
55364 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
55365 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
55366 +
55367 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
55368 + if (err != 0)
55369 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
55370 +
55371 + return E_OK;
55372 +}
55373 +
55374 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
55375 +{
55376 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55377 + t_FmPortPerformanceCnt currParams, savedParams;
55378 + t_Error err;
55379 + bool underTest, failed = FALSE;
55380 +
55381 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55382 +
55383 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
55384 + p_FmPort->portType, p_FmPort->portId);
55385 +
55386 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
55387 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55388 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55389 + currParams.queueCompVal = 0;
55390 + else
55391 + currParams.queueCompVal = 1;
55392 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
55393 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
55394 +
55395 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55396 + ClearPerfCnts(p_FmPort);
55397 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55398 + != E_OK)
55399 + RETURN_ERROR(MAJOR, err, NO_MSG);
55400 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55401 + XX_UDelay(1000000);
55402 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55403 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55404 + {
55405 + XX_Print(
55406 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
55407 + p_FmPort->tasks.num);
55408 + failed = TRUE;
55409 + }
55410 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55411 + {
55412 + XX_Print(
55413 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
55414 + p_FmPort->openDmas.num);
55415 + failed = TRUE;
55416 + }
55417 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55418 + {
55419 + XX_Print(
55420 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
55421 + p_FmPort->fifoBufs.num);
55422 + failed = TRUE;
55423 + }
55424 + if (failed)
55425 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55426 +
55427 + memset(&savedParams, 0, sizeof(savedParams));
55428 + while (TRUE)
55429 + {
55430 + underTest = FALSE;
55431 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
55432 + {
55433 + currParams.taskCompVal--;
55434 + underTest = TRUE;
55435 + }
55436 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
55437 + {
55438 + currParams.dmaCompVal--;
55439 + underTest = TRUE;
55440 + }
55441 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
55442 + && !savedParams.fifoCompVal)
55443 + {
55444 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
55445 + underTest = TRUE;
55446 + }
55447 + if (!underTest)
55448 + break;
55449 +
55450 + ClearPerfCnts(p_FmPort);
55451 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55452 + != E_OK)
55453 + RETURN_ERROR(MAJOR, err, NO_MSG);
55454 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55455 + XX_UDelay(1000000);
55456 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55457 +
55458 + if (!savedParams.taskCompVal
55459 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55460 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
55461 + if (!savedParams.dmaCompVal
55462 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55463 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
55464 + if (!savedParams.fifoCompVal
55465 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55466 + savedParams.fifoCompVal = currParams.fifoCompVal
55467 + + (2 * BMI_FIFO_UNITS);
55468 + }
55469 +
55470 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
55471 + savedParams.taskCompVal, savedParams.dmaCompVal,
55472 + savedParams.fifoCompVal);
55473 + return E_OK;
55474 +}
55475 +
55476 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
55477 +{
55478 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55479 + int err;
55480 +
55481 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55482 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55483 +
55484 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
55485 + if (err != 0)
55486 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
55487 + return E_OK;
55488 +}
55489 +
55490 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
55491 +{
55492 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55493 + volatile uint32_t *p_ErrDiscard = NULL;
55494 + int err;
55495 +
55496 + UNUSED(p_ErrDiscard);
55497 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
55498 + if (err != 0)
55499 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
55500 +
55501 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55502 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55503 + {
55504 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55505 +
55506 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55507 + (void**)&p_ParamsPage);
55508 + ASSERT_COND(p_ParamsPage);
55509 + switch (p_FmPort->portType)
55510 + {
55511 + case (e_FM_PORT_TYPE_RX_10G):
55512 + case (e_FM_PORT_TYPE_RX):
55513 + p_ErrDiscard =
55514 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
55515 + break;
55516 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55517 + p_ErrDiscard =
55518 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
55519 + break;
55520 + default:
55521 + RETURN_ERROR(
55522 + MAJOR, E_INVALID_OPERATION,
55523 + ("available for Rx and offline parsing ports only"));
55524 + }
55525 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
55526 + GET_UINT32(*p_ErrDiscard) | errs);
55527 + }
55528 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55529 +
55530 + return E_OK;
55531 +}
55532 +
55533 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55534 + bool enable)
55535 +{
55536 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55537 + int err;
55538 +
55539 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55540 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
55541 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55542 +
55543 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55544 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55545 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55546 + ("available for Rx ports only"));
55547 +
55548 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
55549 + if (err != 0)
55550 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
55551 + return E_OK;
55552 +}
55553 +
55554 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
55555 +{
55556 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55557 +
55558 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55559 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
55560 + p_BmiStats->cntCycle =
55561 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55562 + /* fmbm_rccn */
55563 + p_BmiStats->cntTaskUtil =
55564 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55565 + /* fmbm_rtuc */
55566 + p_BmiStats->cntQueueUtil =
55567 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55568 + /* fmbm_rrquc */
55569 + p_BmiStats->cntDmaUtil =
55570 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55571 + /* fmbm_rduc */
55572 + p_BmiStats->cntFifoUtil =
55573 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55574 + /* fmbm_rfuc */
55575 + p_BmiStats->cntRxPauseActivation =
55576 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
55577 + /* fmbm_rpac */
55578 + p_BmiStats->cntFrame =
55579 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55580 + /* fmbm_rfrc */
55581 + p_BmiStats->cntDiscardFrame =
55582 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55583 + /* fmbm_rfdc */
55584 + p_BmiStats->cntDeallocBuf =
55585 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55586 + /* fmbm_rbdc */
55587 + p_BmiStats->cntRxBadFrame =
55588 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
55589 + /* fmbm_rfbc */
55590 + p_BmiStats->cntRxLargeFrame =
55591 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
55592 + /* fmbm_rlfc */
55593 + p_BmiStats->cntRxFilterFrame =
55594 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55595 + /* fmbm_rffc */
55596 + p_BmiStats->cntRxListDmaErr =
55597 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55598 + /* fmbm_rfldec */
55599 + p_BmiStats->cntRxOutOfBuffersDiscard =
55600 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55601 + /* fmbm_rodc */
55602 + p_BmiStats->cntWredDiscard = 0;
55603 + p_BmiStats->cntLengthErr = 0;
55604 + p_BmiStats->cntUnsupportedFormat = 0;
55605 + }
55606 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55607 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
55608 + p_BmiStats->cntCycle =
55609 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55610 + /* fmbm_tccn */
55611 + p_BmiStats->cntTaskUtil =
55612 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55613 + /* fmbm_ttuc */
55614 + p_BmiStats->cntQueueUtil =
55615 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55616 + /* fmbm_ttcquc */
55617 + p_BmiStats->cntDmaUtil =
55618 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55619 + /* fmbm_tduc */
55620 + p_BmiStats->cntFifoUtil =
55621 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55622 + /* fmbm_tfuc */
55623 + p_BmiStats->cntRxPauseActivation = 0;
55624 + p_BmiStats->cntFrame =
55625 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55626 + /* fmbm_tfrc */
55627 + p_BmiStats->cntDiscardFrame =
55628 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55629 + /* fmbm_tfdc */
55630 + p_BmiStats->cntDeallocBuf =
55631 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55632 + /* fmbm_tbdc */
55633 + p_BmiStats->cntRxBadFrame = 0;
55634 + p_BmiStats->cntRxLargeFrame = 0;
55635 + p_BmiStats->cntRxFilterFrame = 0;
55636 + p_BmiStats->cntRxListDmaErr = 0;
55637 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
55638 + p_BmiStats->cntWredDiscard = 0;
55639 + p_BmiStats->cntLengthErr =
55640 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55641 + /* fmbm_tfledc */
55642 + p_BmiStats->cntUnsupportedFormat =
55643 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55644 + /* fmbm_tfufdc */
55645 + }
55646 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
55647 + p_BmiStats->cntCycle =
55648 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55649 + /* fmbm_occn */
55650 + p_BmiStats->cntTaskUtil =
55651 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55652 + /* fmbm_otuc */
55653 + p_BmiStats->cntQueueUtil = 0;
55654 + p_BmiStats->cntDmaUtil =
55655 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55656 + /* fmbm_oduc */
55657 + p_BmiStats->cntFifoUtil =
55658 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55659 + /* fmbm_ofuc*/
55660 + p_BmiStats->cntRxPauseActivation = 0;
55661 + p_BmiStats->cntFrame =
55662 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55663 + /* fmbm_ofrc */
55664 + p_BmiStats->cntDiscardFrame =
55665 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55666 + /* fmbm_ofdc */
55667 + p_BmiStats->cntDeallocBuf =
55668 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55669 + /* fmbm_obdc*/
55670 + p_BmiStats->cntRxBadFrame = 0;
55671 + p_BmiStats->cntRxLargeFrame = 0;
55672 + p_BmiStats->cntRxFilterFrame =
55673 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55674 + /* fmbm_offc */
55675 + p_BmiStats->cntRxListDmaErr =
55676 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55677 + /* fmbm_ofldec */
55678 + p_BmiStats->cntRxOutOfBuffersDiscard =
55679 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55680 + /* fmbm_rodc */
55681 + p_BmiStats->cntWredDiscard =
55682 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
55683 + /* fmbm_ofwdc */
55684 + p_BmiStats->cntLengthErr =
55685 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55686 + /* fmbm_ofledc */
55687 + p_BmiStats->cntUnsupportedFormat =
55688 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
55689 + /* fmbm_ofufdc */
55690 + }
55691 + return E_OK;
55692 +}
55693 +
55694 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
55695 +{
55696 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55697 + bool bmiCounter = FALSE;
55698 + enum fman_port_stats_counters statsType;
55699 + enum fman_port_perf_counters perfType;
55700 + enum fman_port_qmi_counters queueType;
55701 + bool isStats;
55702 + t_Error errCode;
55703 +
55704 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55705 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55706 +
55707 + switch (counter)
55708 + {
55709 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55710 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55711 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55712 + /* check that counter is available for the port type */
55713 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55714 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55715 + {
55716 + REPORT_ERROR(MINOR, E_INVALID_STATE,
55717 + ("Requested counter is not available for Rx ports"));
55718 + return 0;
55719 + }
55720 + bmiCounter = FALSE;
55721 + break;
55722 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55723 + bmiCounter = FALSE;
55724 + break;
55725 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55726 + bmiCounter = TRUE;
55727 + break;
55728 + }
55729 +
55730 + if (bmiCounter)
55731 + {
55732 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55733 + &perfType, &isStats);
55734 + if (errCode != E_OK)
55735 + {
55736 + REPORT_ERROR(MINOR, errCode, NO_MSG);
55737 + return 0;
55738 + }
55739 + if (isStats)
55740 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
55741 + else
55742 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
55743 + }
55744 + else /* QMI counter */
55745 + {
55746 + /* check that counters are enabled */
55747 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55748 + & QMI_PORT_CFG_EN_COUNTERS))
55749 +
55750 + {
55751 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
55752 + return 0;
55753 + }
55754 +
55755 + /* Set counter */
55756 + switch (counter)
55757 + {
55758 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55759 + queueType = E_FMAN_PORT_ENQ_TOTAL;
55760 + break;
55761 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55762 + queueType = E_FMAN_PORT_DEQ_TOTAL;
55763 + break;
55764 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55765 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
55766 + break;
55767 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55768 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
55769 + break;
55770 + default:
55771 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
55772 + return 0;
55773 + }
55774 +
55775 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
55776 + }
55777 +
55778 + return 0;
55779 +}
55780 +
55781 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
55782 + uint32_t value)
55783 +{
55784 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55785 + bool bmiCounter = FALSE;
55786 + enum fman_port_stats_counters statsType;
55787 + enum fman_port_perf_counters perfType;
55788 + enum fman_port_qmi_counters queueType;
55789 + bool isStats;
55790 + t_Error errCode;
55791 +
55792 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55793 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55794 +
55795 + switch (counter)
55796 + {
55797 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55798 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55799 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55800 + /* check that counter is available for the port type */
55801 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55802 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55803 + RETURN_ERROR(
55804 + MINOR, E_INVALID_STATE,
55805 + ("Requested counter is not available for Rx ports"));
55806 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55807 + bmiCounter = FALSE;
55808 + break;
55809 + default: /* BMI counters (or error - will be checked in BMI routine )*/
55810 + bmiCounter = TRUE;
55811 + break;
55812 + }
55813 +
55814 + if (bmiCounter)
55815 + {
55816 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
55817 + &perfType, &isStats);
55818 + if (errCode != E_OK)
55819 + {
55820 + RETURN_ERROR(MINOR, errCode, NO_MSG);
55821 + }
55822 + if (isStats)
55823 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
55824 + else
55825 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
55826 + }
55827 + else /* QMI counter */
55828 + {
55829 + /* check that counters are enabled */
55830 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
55831 + & QMI_PORT_CFG_EN_COUNTERS))
55832 + {
55833 + RETURN_ERROR(MINOR, E_INVALID_STATE,
55834 + ("Requested counter was not enabled"));
55835 + }
55836 +
55837 + /* Set counter */
55838 + switch (counter)
55839 + {
55840 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
55841 + queueType = E_FMAN_PORT_ENQ_TOTAL;
55842 + break;
55843 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
55844 + queueType = E_FMAN_PORT_DEQ_TOTAL;
55845 + break;
55846 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
55847 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
55848 + break;
55849 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
55850 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
55851 + break;
55852 + default:
55853 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55854 + ("Requested counter is not available"));
55855 + }
55856 +
55857 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
55858 + }
55859 +
55860 + return E_OK;
55861 +}
55862 +
55863 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
55864 +{
55865 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55866 +
55867 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55868 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55869 +
55870 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
55871 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55872 + {
55873 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
55874 + return 0;
55875 + }
55876 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
55877 +}
55878 +
55879 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55880 + uint32_t value)
55881 +{
55882 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
55883 +
55884 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55885 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55886 +
55887 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
55888 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55889 + RETURN_ERROR( MINOR, E_INVALID_STATE,
55890 + ("Requested counter is not available for non-Rx ports"));
55891 +
55892 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
55893 + return E_OK;
55894 +}
55895 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
55896 +{
55897 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55898 + t_Error err;
55899 + bool isStalled;
55900 +
55901 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
55902 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55903 + FALSE);
55904 +
55905 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
55906 + if (err != E_OK)
55907 + {
55908 + REPORT_ERROR(MAJOR, err, NO_MSG);
55909 + return TRUE;
55910 + }
55911 + return isStalled;
55912 +}
55913 +
55914 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
55915 +{
55916 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55917 +
55918 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55919 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55920 +
55921 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
55922 +}
55923 +
55924 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
55925 +{
55926 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55927 + int err;
55928 +
55929 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55930 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55931 +
55932 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55933 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55934 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55935 + ("available for Rx ports only"));
55936 +
55937 + if (l4Checksum)
55938 + err = fman_port_modify_rx_fd_bits(
55939 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
55940 + TRUE);
55941 + else
55942 + err = fman_port_modify_rx_fd_bits(
55943 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
55944 + FALSE);
55945 + if (err != 0)
55946 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
55947 +
55948 + return E_OK;
55949 +}
55950 +
55951 +/*****************************************************************************/
55952 +/* API Run-time PCD Control unit functions */
55953 +/*****************************************************************************/
55954 +
55955 +#if (DPAA_VERSION >= 11)
55956 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
55957 +{
55958 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55959 + t_Error err = E_OK;
55960 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
55961 + uint32_t tmpReg = 0, tmp = 0;
55962 + uint16_t hwStoragePrflId;
55963 +
55964 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55965 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
55966 + /*for numOfProfiles = 0 don't call this function*/
55967 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
55968 + /*dfltRelativeId should be in the range of numOfProfiles*/
55969 + SANITY_CHECK_RETURN_ERROR(
55970 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
55971 + E_INVALID_VALUE);
55972 + /*p_FmPort should be from Rx type or OP*/
55973 + SANITY_CHECK_RETURN_ERROR(
55974 + ((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)),
55975 + E_INVALID_VALUE);
55976 + /*port should be disabled*/
55977 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
55978 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
55979 + SANITY_CHECK_RETURN_ERROR(
55980 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
55981 + E_INVALID_VALUE);
55982 + /*should be called before SetPCD - this port should be without PCD*/
55983 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
55984 +
55985 + /*alloc window of VSPs for this port*/
55986 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
55987 + p_FmPort->portId, p_VSPParams->numOfProfiles);
55988 + if (err != E_OK)
55989 + RETURN_ERROR(MAJOR, err, NO_MSG);
55990 +
55991 + /*get absolute VSP ID for dfltRelative*/
55992 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
55993 + p_FmPort->portId,
55994 + p_VSPParams->dfltRelativeId,
55995 + &hwStoragePrflId);
55996 + if (err != E_OK)
55997 + RETURN_ERROR(MAJOR, err, NO_MSG);
55998 +
55999 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
56000 + switch (p_FmPort->portType)
56001 + {
56002 + case (e_FM_PORT_TYPE_RX_10G):
56003 + case (e_FM_PORT_TYPE_RX):
56004 + p_BmiStorageProfileId =
56005 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
56006 + p_BmiVspe =
56007 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
56008 +
56009 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56010 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56011 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56012 +
56013 + tmpReg = GET_UINT32(*p_BmiVspe);
56014 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
56015 +
56016 + p_BmiStorageProfileId =
56017 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
56018 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
56019 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
56020 + break;
56021 +
56022 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56023 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
56024 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
56025 + tmpReg);
56026 +
56027 + p_BmiStorageProfileId =
56028 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
56029 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
56030 + tmp |= BMI_EBD_EN;
56031 + break;
56032 +
56033 + default:
56034 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56035 + ("available for Rx and offline parsing ports only"));
56036 + }
56037 +
56038 + p_FmPort->vspe = TRUE;
56039 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
56040 +
56041 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56042 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56043 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56044 +
56045 + tmpReg = GET_UINT32(*p_BmiVspe);
56046 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
56047 + return E_OK;
56048 +}
56049 +#endif /* (DPAA_VERSION >= 11) */
56050 +
56051 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
56052 +{
56053 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56054 + t_Error err = E_OK;
56055 +
56056 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56057 + ASSERT_COND(p_FmPort->h_FmPcd);
56058 +
56059 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56060 + {
56061 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56062 + return ERROR_CODE(E_BUSY);
56063 + }
56064 +
56065 + if (numOfProfiles)
56066 + {
56067 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
56068 + p_FmPort->hardwarePortId, numOfProfiles);
56069 + if (err)
56070 + RETURN_ERROR(MAJOR, err, NO_MSG);
56071 + }
56072 + /* set the port handle within the PCD policer, even if no profiles defined */
56073 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
56074 +
56075 + RELEASE_LOCK(p_FmPort->lock);
56076 +
56077 + return E_OK;
56078 +}
56079 +
56080 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
56081 +{
56082 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56083 + t_Error err = E_OK;
56084 +
56085 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56086 + {
56087 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56088 + return ERROR_CODE(E_BUSY);
56089 + }
56090 +
56091 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
56092 +
56093 + RELEASE_LOCK(p_FmPort->lock);
56094 +
56095 + if (err)
56096 + RETURN_ERROR(MAJOR, err, NO_MSG);
56097 +
56098 + return E_OK;
56099 +}
56100 +
56101 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
56102 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
56103 +{
56104 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56105 + volatile uint32_t *p_BmiHpnia = NULL;
56106 + uint32_t tmpReg;
56107 + uint8_t relativeSchemeId;
56108 + uint8_t physicalSchemeId;
56109 +
56110 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56111 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56112 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56113 + E_INVALID_STATE);
56114 +
56115 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
56116 + switch (p_FmPort->portType)
56117 + {
56118 + case (e_FM_PORT_TYPE_RX_10G):
56119 + case (e_FM_PORT_TYPE_RX):
56120 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56121 + break;
56122 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56123 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56124 + break;
56125 + default:
56126 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56127 + ("available for Rx and offline parsing ports only"));
56128 + }
56129 +
56130 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56131 + {
56132 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56133 + return ERROR_CODE(E_BUSY);
56134 + }
56135 +
56136 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
56137 + if (p_FmPcdKgScheme->direct)
56138 + {
56139 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
56140 + /* check that this scheme is bound to this port */
56141 + if (!(p_FmPort->schemesPerPortVector
56142 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
56143 + {
56144 + RELEASE_LOCK(p_FmPort->lock);
56145 + RETURN_ERROR(
56146 + MAJOR, E_INVALID_STATE,
56147 + ("called with a scheme that is not bound to this port"));
56148 + }
56149 +
56150 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
56151 + physicalSchemeId);
56152 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
56153 + {
56154 + RELEASE_LOCK(p_FmPort->lock);
56155 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56156 + ("called with invalid Scheme "));
56157 + }
56158 +
56159 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
56160 + {
56161 + RELEASE_LOCK(p_FmPort->lock);
56162 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56163 + ("called with uninitialized Scheme "));
56164 + }
56165 +
56166 + WRITE_UINT32(
56167 + *p_BmiHpnia,
56168 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
56169 + }
56170 + else
56171 + /* change to indirect scheme */
56172 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
56173 + RELEASE_LOCK(p_FmPort->lock);
56174 +
56175 + return E_OK;
56176 +}
56177 +
56178 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
56179 + t_Handle h_Profile)
56180 +{
56181 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56182 + volatile uint32_t *p_BmiNia;
56183 + volatile uint32_t *p_BmiHpnia;
56184 + uint32_t tmpReg;
56185 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
56186 +
56187 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56188 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56189 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
56190 + E_INVALID_STATE);
56191 +
56192 + /* check relevance of this routine - only when policer is used
56193 + directly after BMI or Parser */
56194 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
56195 + || (p_FmPort->pcdEngines & FM_PCD_CC))
56196 + RETURN_ERROR(
56197 + MAJOR,
56198 + E_INVALID_STATE,
56199 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
56200 +
56201 + switch (p_FmPort->portType)
56202 + {
56203 + case (e_FM_PORT_TYPE_RX_10G):
56204 + case (e_FM_PORT_TYPE_RX):
56205 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56206 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56207 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
56208 + break;
56209 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56210 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56211 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56212 + tmpReg = 0;
56213 + break;
56214 + default:
56215 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56216 + ("available for Rx and offline parsing ports only"));
56217 + }
56218 +
56219 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56220 + {
56221 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56222 + return ERROR_CODE(E_BUSY);
56223 + }
56224 +
56225 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
56226 + {
56227 + RELEASE_LOCK(p_FmPort->lock);
56228 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
56229 + }
56230 +
56231 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
56232 +
56233 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
56234 + {
56235 + /* update BMI HPNIA */
56236 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
56237 + }
56238 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
56239 + {
56240 + /* rfne may contain FDCS bits, so first we read them. */
56241 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
56242 + /* update BMI NIA */
56243 + WRITE_UINT32(*p_BmiNia, tmpReg);
56244 + }RELEASE_LOCK(p_FmPort->lock);
56245 +
56246 + return E_OK;
56247 +}
56248 +
56249 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
56250 +{
56251 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56252 + t_Error err = E_OK;
56253 + volatile uint32_t *p_BmiCcBase = NULL;
56254 + volatile uint32_t *p_BmiNia = NULL;
56255 + uint32_t ccTreePhysOffset;
56256 +
56257 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56258 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
56259 +
56260 + if (p_FmPort->imEn)
56261 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56262 + ("available for non-independent mode ports only"));
56263 +
56264 + /* get PCD registers pointers */
56265 + switch (p_FmPort->portType)
56266 + {
56267 + case (e_FM_PORT_TYPE_RX_10G):
56268 + case (e_FM_PORT_TYPE_RX):
56269 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56270 + break;
56271 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56272 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56273 + break;
56274 + default:
56275 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56276 + ("available for Rx and offline parsing ports only"));
56277 + }
56278 +
56279 + /* check that current NIA is BMI to BMI */
56280 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
56281 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
56282 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56283 + ("may be called only for ports in BMI-to-BMI state."));
56284 +
56285 + if (p_FmPort->pcdEngines & FM_PCD_CC)
56286 + {
56287 + if (p_FmPort->h_IpReassemblyManip)
56288 + {
56289 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56290 + p_FmPort->h_IpReassemblyManip, FALSE);
56291 + if (err != E_OK)
56292 + {
56293 + RETURN_ERROR(MAJOR, err, NO_MSG);
56294 + }
56295 + }
56296 + else
56297 + if (p_FmPort->h_CapwapReassemblyManip)
56298 + {
56299 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56300 + p_FmPort->h_CapwapReassemblyManip,
56301 + FALSE);
56302 + if (err != E_OK)
56303 + {
56304 + RETURN_ERROR(MAJOR, err, NO_MSG);
56305 + }
56306 + }
56307 + switch (p_FmPort->portType)
56308 + {
56309 + case (e_FM_PORT_TYPE_RX_10G):
56310 + case (e_FM_PORT_TYPE_RX):
56311 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
56312 + break;
56313 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56314 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
56315 + break;
56316 + default:
56317 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56318 + }
56319 +
56320 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56321 + {
56322 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56323 + return ERROR_CODE(E_BUSY);
56324 + }
56325 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
56326 + &ccTreePhysOffset, h_FmPort);
56327 + if (err)
56328 + {
56329 + RELEASE_LOCK(p_FmPort->lock);
56330 + RETURN_ERROR(MAJOR, err, NO_MSG);
56331 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
56332 +
56333 + p_FmPort->ccTreeId = h_CcTree;
56334 + RELEASE_LOCK(p_FmPort->lock);
56335 + }
56336 + else
56337 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56338 + ("Coarse Classification not defined for this port."));
56339 +
56340 + return E_OK;
56341 +}
56342 +
56343 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
56344 +{
56345 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56346 + t_Error err = E_OK;
56347 +
56348 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56349 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56350 +
56351 + if (p_FmPort->imEn)
56352 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56353 + ("available for non-independent mode ports only"));
56354 +
56355 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56356 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56357 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56358 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56359 + ("available for Rx and offline parsing ports only"));
56360 +
56361 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56362 + {
56363 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56364 + return ERROR_CODE(E_BUSY);
56365 + }
56366 +
56367 + if (p_FmPort->h_ReassemblyTree)
56368 + p_FmPort->pcdEngines |= FM_PCD_CC;
56369 +
56370 + err = AttachPCD(h_FmPort);
56371 + RELEASE_LOCK(p_FmPort->lock);
56372 +
56373 + return err;
56374 +}
56375 +
56376 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
56377 +{
56378 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56379 + t_Error err = E_OK;
56380 +
56381 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56382 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56383 +
56384 + if (p_FmPort->imEn)
56385 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56386 + ("available for non-independent mode ports only"));
56387 +
56388 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56389 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56390 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56391 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56392 + ("available for Rx and offline parsing ports only"));
56393 +
56394 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56395 + {
56396 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56397 + return ERROR_CODE(E_BUSY);
56398 + }
56399 +
56400 + err = DetachPCD(h_FmPort);
56401 + if (err != E_OK)
56402 + {
56403 + RELEASE_LOCK(p_FmPort->lock);
56404 + RETURN_ERROR(MAJOR, err, NO_MSG);
56405 + }
56406 +
56407 + if (p_FmPort->h_ReassemblyTree)
56408 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
56409 + RELEASE_LOCK(p_FmPort->lock);
56410 +
56411 + return E_OK;
56412 +}
56413 +
56414 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
56415 +{
56416 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56417 + t_Error err = E_OK;
56418 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
56419 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
56420 + t_FmPortPcdCcParams fmPortPcdCcParams;
56421 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
56422 +
56423 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56424 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
56425 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56426 +
56427 + if (p_FmPort->imEn)
56428 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56429 + ("available for non-independent mode ports only"));
56430 +
56431 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56432 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56433 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56434 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56435 + ("available for Rx and offline parsing ports only"));
56436 +
56437 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56438 + {
56439 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56440 + return ERROR_CODE(E_BUSY);
56441 + }
56442 +
56443 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56444 + ASSERT_COND(p_FmPort->h_FmPcd);
56445 +
56446 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
56447 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
56448 + ("Tree handle must be given if CC is required"));
56449 +
56450 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
56451 + p_PcdParams = &modifiedPcdParams;
56452 + if ((p_PcdParams->h_IpReassemblyManip)
56453 +#if (DPAA_VERSION >= 11)
56454 + || (p_PcdParams->h_CapwapReassemblyManip)
56455 +#endif /* (DPAA_VERSION >= 11) */
56456 + )
56457 + {
56458 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56459 + && (p_PcdParams->pcdSupport
56460 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
56461 + && (p_PcdParams->pcdSupport
56462 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
56463 + && (p_PcdParams->pcdSupport
56464 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
56465 + {
56466 + RELEASE_LOCK(p_FmPort->lock);
56467 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56468 + ("pcdSupport must have KG for supporting Reassembly"));
56469 + }
56470 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
56471 +#if (DPAA_VERSION >= 11)
56472 + if ((p_PcdParams->h_IpReassemblyManip)
56473 + && (p_PcdParams->h_CapwapReassemblyManip))
56474 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56475 + ("Either IP-R or CAPWAP-R is allowed"));
56476 + if ((p_PcdParams->h_CapwapReassemblyManip)
56477 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56478 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56479 + ("CAPWAP-R is allowed only on offline-port"));
56480 + if (p_PcdParams->h_CapwapReassemblyManip)
56481 + p_FmPort->h_CapwapReassemblyManip =
56482 + p_PcdParams->h_CapwapReassemblyManip;
56483 +#endif /* (DPAA_VERSION >= 11) */
56484 +
56485 + if (!p_PcdParams->p_CcParams)
56486 + {
56487 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56488 + || (p_PcdParams->pcdSupport
56489 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
56490 + {
56491 + RELEASE_LOCK(p_FmPort->lock);
56492 + RETURN_ERROR(
56493 + MAJOR,
56494 + E_INVALID_STATE,
56495 + ("PCD initialization structure is not consistent with pcdSupport"));
56496 + }
56497 +
56498 + /* No user-tree, need to build internal tree */
56499 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
56500 + sizeof(t_FmPcdCcTreeParams));
56501 + if (!p_FmPcdCcTreeParams)
56502 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
56503 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
56504 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
56505 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
56506 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
56507 +
56508 + if (!p_FmPort->h_ReassemblyTree)
56509 + {
56510 + RELEASE_LOCK(p_FmPort->lock);
56511 + XX_Free(p_FmPcdCcTreeParams);
56512 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
56513 + ("FM_PCD_CcBuildTree for Reassembly failed"));
56514 + }
56515 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56516 + p_PcdParams->pcdSupport =
56517 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
56518 + else
56519 + p_PcdParams->pcdSupport =
56520 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
56521 +
56522 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
56523 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
56524 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
56525 + XX_Free(p_FmPcdCcTreeParams);
56526 + }
56527 +
56528 + if (p_FmPort->h_IpReassemblyManip)
56529 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
56530 + p_PcdParams->p_CcParams->h_CcTree,
56531 + p_PcdParams->h_NetEnv,
56532 + p_FmPort->h_IpReassemblyManip, TRUE);
56533 +#if (DPAA_VERSION >= 11)
56534 + else
56535 + if (p_FmPort->h_CapwapReassemblyManip)
56536 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
56537 + p_PcdParams->p_CcParams->h_CcTree,
56538 + p_PcdParams->h_NetEnv,
56539 + p_FmPort->h_CapwapReassemblyManip,
56540 + TRUE);
56541 +#endif /* (DPAA_VERSION >= 11) */
56542 +
56543 + if (err != E_OK)
56544 + {
56545 + if (p_FmPort->h_ReassemblyTree)
56546 + {
56547 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56548 + p_FmPort->h_ReassemblyTree = NULL;
56549 + }RELEASE_LOCK(p_FmPort->lock);
56550 + RETURN_ERROR(MAJOR, err, NO_MSG);
56551 + }
56552 + }
56553 +
56554 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56555 + {
56556 + if (p_FmPort->h_ReassemblyTree)
56557 + {
56558 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56559 + p_FmPort->h_ReassemblyTree = NULL;
56560 + }RELEASE_LOCK(p_FmPort->lock);
56561 + DBG(TRACE, ("Try LockAll - BUSY"));
56562 + return ERROR_CODE(E_BUSY);
56563 + }
56564 +
56565 + err = SetPcd(h_FmPort, p_PcdParams);
56566 + if (err)
56567 + {
56568 + if (p_FmPort->h_ReassemblyTree)
56569 + {
56570 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56571 + p_FmPort->h_ReassemblyTree = NULL;
56572 + }
56573 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56574 + RELEASE_LOCK(p_FmPort->lock);
56575 + RETURN_ERROR(MAJOR, err, NO_MSG);
56576 + }
56577 +
56578 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
56579 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
56580 + {
56581 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56582 + p_FmPort->hardwarePortId, TRUE);
56583 + if (err)
56584 + {
56585 + DeletePcd(p_FmPort);
56586 + if (p_FmPort->h_ReassemblyTree)
56587 + {
56588 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56589 + p_FmPort->h_ReassemblyTree = NULL;
56590 + }
56591 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56592 + RELEASE_LOCK(p_FmPort->lock);
56593 + RETURN_ERROR(MAJOR, err, NO_MSG);
56594 + }
56595 + p_FmPort->includeInPrsStatistics = TRUE;
56596 + }
56597 +
56598 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56599 +
56600 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56601 + {
56602 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56603 +
56604 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56605 + {
56606 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56607 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
56608 + (p_FmPort->pcdEngines & FM_PCD_KG))
56609 + {
56610 + int i;
56611 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
56612 + /* The following function must be locked */
56613 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
56614 + p_PcdParams->p_KgParams->h_Schemes[i],
56615 + UPDATE_KG_NIA_CC_WA,
56616 + 0);
56617 + }
56618 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56619 +
56620 +#if (DPAA_VERSION >= 11)
56621 + {
56622 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56623 +
56624 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56625 + (void**)&p_ParamsPage);
56626 + ASSERT_COND(p_ParamsPage);
56627 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
56628 + p_FmPort->savedBmiNia);
56629 + }
56630 +#endif /* (DPAA_VERSION >= 11) */
56631 +
56632 + /* Set post-bmi-fetch nia */
56633 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
56634 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
56635 + | NIA_ENG_FM_CTL);
56636 +
56637 + /* Set pre-bmi-fetch nia */
56638 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
56639 +#if (DPAA_VERSION >= 11)
56640 + fmPortGetSetCcParams.setCcParams.nia =
56641 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
56642 +#else
56643 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
56644 +#endif /* (DPAA_VERSION >= 11) */
56645 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
56646 + != E_OK)
56647 + {
56648 + DeletePcd(p_FmPort);
56649 + if (p_FmPort->h_ReassemblyTree)
56650 + {
56651 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56652 + p_FmPort->h_ReassemblyTree = NULL;
56653 + }
56654 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56655 + RELEASE_LOCK(p_FmPort->lock);
56656 + RETURN_ERROR(MAJOR, err, NO_MSG);
56657 + }
56658 + }
56659 +
56660 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56661 +
56662 + /* Set pop-to-next-step nia */
56663 +#if (DPAA_VERSION == 10)
56664 + if (p_FmPort->fmRevInfo.majorRev < 6)
56665 + {
56666 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
56667 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56668 + }
56669 + else
56670 + {
56671 +#endif /* (DPAA_VERSION == 10) */
56672 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
56673 +#if (DPAA_VERSION == 10)
56674 + }
56675 +#endif /* (DPAA_VERSION == 10) */
56676 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56677 + != E_OK)
56678 + {
56679 + DeletePcd(p_FmPort);
56680 + if (p_FmPort->h_ReassemblyTree)
56681 + {
56682 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56683 + p_FmPort->h_ReassemblyTree = NULL;
56684 + }RELEASE_LOCK(p_FmPort->lock);
56685 + RETURN_ERROR(MAJOR, err, NO_MSG);
56686 + }
56687 +
56688 + /* Set post-bmi-prepare-to-enq nia */
56689 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56690 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
56691 + | NIA_ENG_FM_CTL);
56692 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56693 + != E_OK)
56694 + {
56695 + DeletePcd(p_FmPort);
56696 + if (p_FmPort->h_ReassemblyTree)
56697 + {
56698 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56699 + p_FmPort->h_ReassemblyTree = NULL;
56700 + }RELEASE_LOCK(p_FmPort->lock);
56701 + RETURN_ERROR(MAJOR, err, NO_MSG);
56702 + }
56703 +
56704 + if ((p_FmPort->h_IpReassemblyManip)
56705 + || (p_FmPort->h_CapwapReassemblyManip))
56706 + {
56707 +#if (DPAA_VERSION == 10)
56708 + if (p_FmPort->fmRevInfo.majorRev < 6)
56709 + {
56710 + /* Overwrite post-bmi-prepare-to-enq nia */
56711 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
56712 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
56713 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
56714 + }
56715 + else
56716 + {
56717 +#endif /* (DPAA_VERSION == 10) */
56718 + /* Set the ORR bit (for order-restoration) */
56719 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
56720 + fmPortGetSetCcParams.setCcParams.nia =
56721 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
56722 +#if (DPAA_VERSION == 10)
56723 + }
56724 +#endif /* (DPAA_VERSION == 10) */
56725 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56726 + != E_OK)
56727 + {
56728 + DeletePcd(p_FmPort);
56729 + if (p_FmPort->h_ReassemblyTree)
56730 + {
56731 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56732 + p_FmPort->h_ReassemblyTree = NULL;
56733 + }RELEASE_LOCK(p_FmPort->lock);
56734 + RETURN_ERROR(MAJOR, err, NO_MSG);
56735 + }
56736 + }
56737 + }
56738 + else
56739 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56740 +
56741 +#if (DPAA_VERSION >= 11)
56742 + {
56743 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56744 +
56745 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56746 +
56747 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
56748 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56749 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
56750 + | NIA_ENG_FM_CTL;
56751 + else
56752 + fmPortGetSetCcParams.setCcParams.nia =
56753 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
56754 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
56755 + != E_OK)
56756 + {
56757 + DeletePcd(p_FmPort);
56758 + if (p_FmPort->h_ReassemblyTree)
56759 + {
56760 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56761 + p_FmPort->h_ReassemblyTree = NULL;
56762 + }RELEASE_LOCK(p_FmPort->lock);
56763 + RETURN_ERROR(MAJOR, err, NO_MSG);
56764 + }
56765 +
56766 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56767 + (void**)&p_ParamsPage);
56768 + ASSERT_COND(p_ParamsPage);
56769 +
56770 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56771 + WRITE_UINT32(
56772 + p_ParamsPage->misc,
56773 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
56774 +
56775 + if ((p_FmPort->h_IpReassemblyManip)
56776 + || (p_FmPort->h_CapwapReassemblyManip))
56777 + {
56778 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56779 + WRITE_UINT32(
56780 + p_ParamsPage->discardMask,
56781 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
56782 + else
56783 + WRITE_UINT32(
56784 + p_ParamsPage->discardMask,
56785 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
56786 + }
56787 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
56788 + if (p_FmPort->vspe)
56789 + WRITE_UINT32(
56790 + p_ParamsPage->misc,
56791 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
56792 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
56793 + }
56794 +#endif /* (DPAA_VERSION >= 11) */
56795 +
56796 + err = AttachPCD(h_FmPort);
56797 + if (err)
56798 + {
56799 + DeletePcd(p_FmPort);
56800 + if (p_FmPort->h_ReassemblyTree)
56801 + {
56802 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56803 + p_FmPort->h_ReassemblyTree = NULL;
56804 + }RELEASE_LOCK(p_FmPort->lock);
56805 + RETURN_ERROR(MAJOR, err, NO_MSG);
56806 + }
56807 +
56808 + RELEASE_LOCK(p_FmPort->lock);
56809 +
56810 + return err;
56811 +}
56812 +
56813 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
56814 +{
56815 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56816 + t_Error err = E_OK;
56817 +
56818 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56819 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56820 +
56821 + if (p_FmPort->imEn)
56822 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56823 + ("available for non-independant mode ports only"));
56824 +
56825 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56826 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56827 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56828 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56829 + ("available for Rx and offline parsing ports only"));
56830 +
56831 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56832 + {
56833 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56834 + return ERROR_CODE(E_BUSY);
56835 + }
56836 +
56837 + err = DetachPCD(h_FmPort);
56838 + if (err)
56839 + {
56840 + RELEASE_LOCK(p_FmPort->lock);
56841 + RETURN_ERROR(MAJOR, err, NO_MSG);
56842 + }
56843 +
56844 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56845 +
56846 + /* we do it anyway, instead of checking if included */
56847 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
56848 + {
56849 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56850 + p_FmPort->hardwarePortId, FALSE);
56851 + p_FmPort->includeInPrsStatistics = FALSE;
56852 + }
56853 +
56854 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56855 + {
56856 + RELEASE_LOCK(p_FmPort->lock);
56857 + DBG(TRACE, ("Try LockAll - BUSY"));
56858 + return ERROR_CODE(E_BUSY);
56859 + }
56860 +
56861 + err = DeletePcd(h_FmPort);
56862 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56863 + if (err)
56864 + {
56865 + RELEASE_LOCK(p_FmPort->lock);
56866 + RETURN_ERROR(MAJOR, err, NO_MSG);
56867 + }
56868 +
56869 + if (p_FmPort->h_ReassemblyTree)
56870 + {
56871 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56872 + if (err)
56873 + {
56874 + RELEASE_LOCK(p_FmPort->lock);
56875 + RETURN_ERROR(MAJOR, err, NO_MSG);
56876 + }
56877 + p_FmPort->h_ReassemblyTree = NULL;
56878 + }RELEASE_LOCK(p_FmPort->lock);
56879 +
56880 + return err;
56881 +}
56882 +
56883 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
56884 + t_FmPcdPortSchemesParams *p_PortScheme)
56885 +{
56886 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56887 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
56888 + t_Error err = E_OK;
56889 + uint32_t tmpScmVec = 0;
56890 + int i;
56891 +
56892 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56893 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56894 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56895 + E_INVALID_STATE);
56896 +
56897 + schemeBind.netEnvId = p_FmPort->netEnvId;
56898 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
56899 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
56900 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
56901 + for (i = 0; i < schemeBind.numOfSchemes; i++)
56902 + {
56903 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
56904 + p_PortScheme->h_Schemes[i]);
56905 + /* build vector */
56906 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
56907 + }
56908 +
56909 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56910 + {
56911 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56912 + return ERROR_CODE(E_BUSY);
56913 + }
56914 +
56915 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
56916 + if (err == E_OK)
56917 + p_FmPort->schemesPerPortVector |= tmpScmVec;
56918 +
56919 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56920 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
56921 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
56922 + (p_FmPort->fmRevInfo.majorRev < 6))
56923 + {
56924 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
56925 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
56926 + }
56927 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56928 +
56929 + RELEASE_LOCK(p_FmPort->lock);
56930 +
56931 + return err;
56932 +}
56933 +
56934 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
56935 + t_FmPcdPortSchemesParams *p_PortScheme)
56936 +{
56937 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56938 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
56939 + t_Error err = E_OK;
56940 + uint32_t tmpScmVec = 0;
56941 + int i;
56942 +
56943 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56944 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56945 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56946 + E_INVALID_STATE);
56947 +
56948 + schemeBind.netEnvId = p_FmPort->netEnvId;
56949 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
56950 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
56951 + for (i = 0; i < schemeBind.numOfSchemes; i++)
56952 + {
56953 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
56954 + p_PortScheme->h_Schemes[i]);
56955 + /* build vector */
56956 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
56957 + }
56958 +
56959 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56960 + {
56961 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56962 + return ERROR_CODE(E_BUSY);
56963 + }
56964 +
56965 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
56966 + if (err == E_OK)
56967 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
56968 + RELEASE_LOCK(p_FmPort->lock);
56969 +
56970 + return err;
56971 +}
56972 +
56973 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
56974 + t_FmPortCongestionGrps *p_CongestionGrps)
56975 +{
56976 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56977 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
56978 + uint8_t mod, index;
56979 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
56980 + int err;
56981 +#if (DPAA_VERSION >= 11)
56982 + int j;
56983 +#endif /* (DPAA_VERSION >= 11) */
56984 +
56985 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56986 +
56987 + /* un-necessary check of the indexes; probably will be needed in the future when there
56988 + will be more CGs available ....
56989 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
56990 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
56991 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
56992 + */
56993 +
56994 +#ifdef FM_NO_OP_OBSERVED_CGS
56995 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
56996 + (p_FmPort->fmRevInfo.majorRev < 6))
56997 + {
56998 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
56999 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57000 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57001 + }
57002 + else
57003 +#endif /* FM_NO_OP_OBSERVED_CGS */
57004 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57005 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57006 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57007 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57008 + ("Available for Rx & OP ports only"));
57009 +
57010 + /* Prepare groups map array */
57011 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57012 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57013 + {
57014 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57015 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57016 + if (p_FmPort->fmRevInfo.majorRev != 4)
57017 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57018 + else
57019 + grpsMap[0] |= (uint32_t)(1 << mod);
57020 + }
57021 +
57022 + memset(&priorityTmpArray, 0,
57023 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
57024 +
57025 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57026 + {
57027 +#if (DPAA_VERSION >= 11)
57028 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
57029 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
57030 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
57031 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
57032 +#endif /* (DPAA_VERSION >= 11) */
57033 + }
57034 +
57035 +#if (DPAA_VERSION >= 11)
57036 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
57037 + {
57038 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
57039 + priorityTmpArray[i]);
57040 + if (err)
57041 + return err;
57042 + }
57043 +#endif /* (DPAA_VERSION >= 11) */
57044 +
57045 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
57046 + if (err != 0)
57047 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
57048 +
57049 + return E_OK;
57050 +}
57051 +
57052 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
57053 + t_FmPortCongestionGrps *p_CongestionGrps)
57054 +{
57055 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57056 + uint8_t mod, index;
57057 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57058 + int err;
57059 +
57060 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57061 +
57062 + {
57063 +#ifdef FM_NO_OP_OBSERVED_CGS
57064 + t_FmRevisionInfo revInfo;
57065 +
57066 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
57067 + if (revInfo.majorRev != 4)
57068 + {
57069 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57070 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57071 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57072 + }
57073 + else
57074 +#endif /* FM_NO_OP_OBSERVED_CGS */
57075 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57076 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57077 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57078 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57079 + ("Available for Rx & OP ports only"));
57080 + }
57081 +
57082 + /* Prepare groups map array */
57083 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57084 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57085 + {
57086 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57087 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57088 + if (p_FmPort->fmRevInfo.majorRev != 4)
57089 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57090 + else
57091 + grpsMap[0] |= (uint32_t)(1 << mod);
57092 + }
57093 +
57094 +#if (DPAA_VERSION >= 11)
57095 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57096 + {
57097 + t_Error err = FmSetCongestionGroupPFCpriority(
57098 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
57099 + 0);
57100 + if (err)
57101 + return err;
57102 + }
57103 +#endif /* (DPAA_VERSION >= 11) */
57104 +
57105 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
57106 + if (err != 0)
57107 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57108 + ("fman_port_remove_congestion_grps"));
57109 + return E_OK;
57110 +}
57111 +
57112 +#if (DPAA_VERSION >= 11)
57113 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
57114 + uint32_t *p_Ipv4OptionsCount)
57115 +{
57116 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57117 +
57118 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57119 + SANITY_CHECK_RETURN_ERROR(
57120 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
57121 + E_INVALID_VALUE);
57122 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
57123 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
57124 +
57125 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
57126 +
57127 + return E_OK;
57128 +}
57129 +#endif /* (DPAA_VERSION >= 11) */
57130 +
57131 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
57132 + t_FmPortDsarTablesSizes *params)
57133 +{
57134 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57135 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
57136 + sizeof(struct t_FmPortDsarTablesSizes));
57137 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
57138 + sizeof(struct t_FmPortDsarTablesSizes));
57139 + return E_OK;
57140 +}
57141 +
57142 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
57143 +{
57144 + uint32_t *param_page;
57145 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
57146 + t_ArCommonDesc *ArCommonDescPtr;
57147 + uint32_t size = sizeof(t_ArCommonDesc);
57148 + // ARP
57149 + // should put here if (params->max_num_of_arp_entries)?
57150 + size = ROUND_UP(size,4);
57151 + size += sizeof(t_DsarArpDescriptor);
57152 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
57153 + size += sizeof(t_DsarArpStatistics);
57154 + //ICMPV4
57155 + size = ROUND_UP(size,4);
57156 + size += sizeof(t_DsarIcmpV4Descriptor);
57157 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
57158 + size += sizeof(t_DsarIcmpV4Statistics);
57159 + //ICMPV6
57160 + size = ROUND_UP(size,4);
57161 + size += sizeof(t_DsarIcmpV6Descriptor);
57162 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
57163 + size += sizeof(t_DsarIcmpV6Statistics);
57164 + //ND
57165 + size = ROUND_UP(size,4);
57166 + size += sizeof(t_DsarNdDescriptor);
57167 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
57168 + size += sizeof(t_DsarIcmpV6Statistics);
57169 + //SNMP
57170 + size = ROUND_UP(size,4);
57171 + size += sizeof(t_DsarSnmpDescriptor);
57172 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57173 + * params->maxNumOfSnmpIPV4Entries;
57174 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57175 + * params->maxNumOfSnmpIPV6Entries;
57176 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
57177 + size += params->maxNumOfSnmpOidChar;
57178 + size += sizeof(t_DsarIcmpV6Statistics);
57179 + //filters
57180 + size = ROUND_UP(size,4);
57181 + size += params->maxNumOfIpProtFiltering;
57182 + size = ROUND_UP(size,4);
57183 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
57184 + size = ROUND_UP(size,4);
57185 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
57186 +
57187 + // add here for more protocols
57188 +
57189 + // statistics
57190 + size = ROUND_UP(size,4);
57191 + size += sizeof(t_ArStatistics);
57192 +
57193 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
57194 +
57195 + param_page =
57196 + XX_PhysToVirt(
57197 + p_FmPort->fmMuramPhysBaseAddr
57198 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57199 + WRITE_UINT32(
57200 + *param_page,
57201 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
57202 + return E_OK;
57203 +}
57204 +
57205 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
57206 +{
57207 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57208 + return p_FmPort->deepSleepVars.autoResMaxSizes;
57209 +}
57210 +
57211 +struct arOffsets
57212 +{
57213 + uint32_t arp;
57214 + uint32_t nd;
57215 + uint32_t icmpv4;
57216 + uint32_t icmpv6;
57217 + uint32_t snmp;
57218 + uint32_t stats;
57219 + uint32_t filtIp;
57220 + uint32_t filtUdp;
57221 + uint32_t filtTcp;
57222 +};
57223 +
57224 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
57225 + struct t_FmPortDsarParams *params,
57226 + t_FmPort *p_FmPort)
57227 +{
57228 + uint32_t size = sizeof(t_ArCommonDesc);
57229 + // ARP
57230 + if (params->p_AutoResArpInfo)
57231 + {
57232 + size = ROUND_UP(size,4);
57233 + of->arp = size;
57234 + size += sizeof(t_DsarArpDescriptor);
57235 + size += sizeof(t_DsarArpBindingEntry)
57236 + * params->p_AutoResArpInfo->tableSize;
57237 + size += sizeof(t_DsarArpStatistics);
57238 + }
57239 + // ICMPV4
57240 + if (params->p_AutoResEchoIpv4Info)
57241 + {
57242 + size = ROUND_UP(size,4);
57243 + of->icmpv4 = size;
57244 + size += sizeof(t_DsarIcmpV4Descriptor);
57245 + size += sizeof(t_DsarIcmpV4BindingEntry)
57246 + * params->p_AutoResEchoIpv4Info->tableSize;
57247 + size += sizeof(t_DsarIcmpV4Statistics);
57248 + }
57249 + // ICMPV6
57250 + if (params->p_AutoResEchoIpv6Info)
57251 + {
57252 + size = ROUND_UP(size,4);
57253 + of->icmpv6 = size;
57254 + size += sizeof(t_DsarIcmpV6Descriptor);
57255 + size += sizeof(t_DsarIcmpV6BindingEntry)
57256 + * params->p_AutoResEchoIpv6Info->tableSize;
57257 + size += sizeof(t_DsarIcmpV6Statistics);
57258 + }
57259 + // ND
57260 + if (params->p_AutoResNdpInfo)
57261 + {
57262 + size = ROUND_UP(size,4);
57263 + of->nd = size;
57264 + size += sizeof(t_DsarNdDescriptor);
57265 + size += sizeof(t_DsarIcmpV6BindingEntry)
57266 + * (params->p_AutoResNdpInfo->tableSizeAssigned
57267 + + params->p_AutoResNdpInfo->tableSizeTmp);
57268 + size += sizeof(t_DsarIcmpV6Statistics);
57269 + }
57270 + // SNMP
57271 + if (params->p_AutoResSnmpInfo)
57272 + {
57273 + size = ROUND_UP(size,4);
57274 + of->snmp = size;
57275 + size += sizeof(t_DsarSnmpDescriptor);
57276 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57277 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
57278 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57279 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
57280 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
57281 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
57282 + size += sizeof(t_DsarIcmpV6Statistics);
57283 + }
57284 + //filters
57285 + size = ROUND_UP(size,4);
57286 + if (params->p_AutoResFilteringInfo)
57287 + {
57288 + of->filtIp = size;
57289 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
57290 + size = ROUND_UP(size,4);
57291 + of->filtUdp = size;
57292 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
57293 + * sizeof(t_PortTblEntry);
57294 + size = ROUND_UP(size,4);
57295 + of->filtTcp = size;
57296 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
57297 + * sizeof(t_PortTblEntry);
57298 + }
57299 + // add here for more protocols
57300 + // statistics
57301 + size = ROUND_UP(size,4);
57302 + of->stats = size;
57303 + size += sizeof(t_ArStatistics);
57304 + return size;
57305 +}
57306 +
57307 +uint32_t* ARDesc;
57308 +void PrsEnable(t_Handle p_FmPcd);
57309 +void PrsDisable(t_Handle p_FmPcd);
57310 +int PrsIsEnabled(t_Handle p_FmPcd);
57311 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
57312 +
57313 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
57314 + t_FmPortDsarTablesSizes *sizes)
57315 +{
57316 + bool macInit = FALSE;
57317 + uint8_t mac[6];
57318 + int i = 0;
57319 +
57320 + // check table sizes
57321 + if (params->p_AutoResArpInfo
57322 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
57323 + RETURN_ERROR(
57324 + MAJOR, E_INVALID_VALUE,
57325 + ("DSAR: Arp table size exceeds the configured maximum size."));
57326 + if (params->p_AutoResEchoIpv4Info
57327 + && sizes->maxNumOfEchoIpv4Entries
57328 + < params->p_AutoResEchoIpv4Info->tableSize)
57329 + RETURN_ERROR(
57330 + MAJOR,
57331 + E_INVALID_VALUE,
57332 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
57333 + if (params->p_AutoResNdpInfo
57334 + && sizes->maxNumOfNdpEntries
57335 + < params->p_AutoResNdpInfo->tableSizeAssigned
57336 + + params->p_AutoResNdpInfo->tableSizeTmp)
57337 + RETURN_ERROR(
57338 + MAJOR, E_INVALID_VALUE,
57339 + ("DSAR: NDP table size exceeds the configured maximum size."));
57340 + if (params->p_AutoResEchoIpv6Info
57341 + && sizes->maxNumOfEchoIpv6Entries
57342 + < params->p_AutoResEchoIpv6Info->tableSize)
57343 + RETURN_ERROR(
57344 + MAJOR,
57345 + E_INVALID_VALUE,
57346 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
57347 + if (params->p_AutoResSnmpInfo
57348 + && sizes->maxNumOfSnmpOidEntries
57349 + < params->p_AutoResSnmpInfo->oidsTblSize)
57350 + RETURN_ERROR(
57351 + MAJOR,
57352 + E_INVALID_VALUE,
57353 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
57354 + if (params->p_AutoResSnmpInfo
57355 + && sizes->maxNumOfSnmpIPV4Entries
57356 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
57357 + RETURN_ERROR(
57358 + MAJOR,
57359 + E_INVALID_VALUE,
57360 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
57361 + if (params->p_AutoResSnmpInfo
57362 + && sizes->maxNumOfSnmpIPV6Entries
57363 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
57364 + RETURN_ERROR(
57365 + MAJOR,
57366 + E_INVALID_VALUE,
57367 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
57368 + if (params->p_AutoResFilteringInfo)
57369 + {
57370 + if (sizes->maxNumOfIpProtFiltering
57371 + < params->p_AutoResFilteringInfo->ipProtTableSize)
57372 + RETURN_ERROR(
57373 + MAJOR,
57374 + E_INVALID_VALUE,
57375 + ("DSAR: ip filter table size exceeds the configured maximum size."));
57376 + if (sizes->maxNumOfTcpPortFiltering
57377 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
57378 + RETURN_ERROR(
57379 + MAJOR,
57380 + E_INVALID_VALUE,
57381 + ("DSAR: udp filter table size exceeds the configured maximum size."));
57382 + if (sizes->maxNumOfUdpPortFiltering
57383 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
57384 + RETURN_ERROR(
57385 + MAJOR,
57386 + E_INVALID_VALUE,
57387 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
57388 + }
57389 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
57390 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
57391 + {
57392 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
57393 + i = 1;
57394 + macInit = TRUE;
57395 +
57396 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
57397 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
57398 + RETURN_ERROR(
57399 + MAJOR, E_INVALID_VALUE,
57400 + ("DSAR: Only 1 mac address is currently supported."));
57401 + }
57402 + if (params->p_AutoResEchoIpv4Info
57403 + && params->p_AutoResEchoIpv4Info->tableSize)
57404 + {
57405 + i = 0;
57406 + if (!macInit)
57407 + {
57408 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
57409 + 6);
57410 + i = 1;
57411 + macInit = TRUE;
57412 + }
57413 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57414 + if (memcmp(mac,
57415 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
57416 + RETURN_ERROR(
57417 + MAJOR, E_INVALID_VALUE,
57418 + ("DSAR: Only 1 mac address is currently supported."));
57419 + }
57420 + if (params->p_AutoResEchoIpv6Info
57421 + && params->p_AutoResEchoIpv6Info->tableSize)
57422 + {
57423 + i = 0;
57424 + if (!macInit)
57425 + {
57426 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
57427 + 6);
57428 + i = 1;
57429 + macInit = TRUE;
57430 + }
57431 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57432 + if (memcmp(mac,
57433 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
57434 + RETURN_ERROR(
57435 + MAJOR, E_INVALID_VALUE,
57436 + ("DSAR: Only 1 mac address is currently supported."));
57437 + }
57438 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
57439 + {
57440 + i = 0;
57441 + if (!macInit)
57442 + {
57443 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
57444 + 6);
57445 + i = 1;
57446 + macInit = TRUE;
57447 + }
57448 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57449 + if (memcmp(mac,
57450 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
57451 + 6))
57452 + RETURN_ERROR(
57453 + MAJOR, E_INVALID_VALUE,
57454 + ("DSAR: Only 1 mac address is currently supported."));
57455 + }
57456 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
57457 + {
57458 + i = 0;
57459 + if (!macInit)
57460 + {
57461 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
57462 + i = 1;
57463 + }
57464 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57465 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
57466 + 6))
57467 + RETURN_ERROR(
57468 + MAJOR, E_INVALID_VALUE,
57469 + ("DSAR: Only 1 mac address is currently supported."));
57470 + }
57471 + return E_OK;
57472 +}
57473 +
57474 +static int GetBERLen(uint8_t* buf)
57475 +{
57476 + if (*buf & 0x80)
57477 + {
57478 + if ((*buf & 0x7F) == 1)
57479 + return buf[1];
57480 + else
57481 + return *(uint16_t*)&buf[1]; // assuming max len is 2
57482 + }
57483 + else
57484 + return buf[0];
57485 +}
57486 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
57487 +
57488 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
57489 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
57490 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
57491 +static int fm_soc_suspend(void)
57492 +{
57493 + uint32_t *fmclk, tmp32;
57494 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57495 + tmp32 = GET_UINT32(*fmclk);
57496 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
57497 + tmp32 = GET_UINT32(*fmclk);
57498 + iounmap(fmclk);
57499 + return 0;
57500 +}
57501 +
57502 +void fm_clk_down(void)
57503 +{
57504 + uint32_t *fmclk, tmp32;
57505 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57506 + tmp32 = GET_UINT32(*fmclk);
57507 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
57508 + tmp32 = GET_UINT32(*fmclk);
57509 + iounmap(fmclk);
57510 +}
57511 +
57512 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
57513 +{
57514 + int i, j;
57515 + t_Error err;
57516 + uint32_t nia;
57517 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57518 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
57519 + t_DsarArpDescriptor *ArpDescriptor;
57520 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
57521 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
57522 + t_DsarNdDescriptor* NDDescriptor;
57523 +
57524 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
57525 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57526 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57527 + struct arOffsets* of;
57528 + uint8_t tmp = 0;
57529 + t_FmGetSetParams fmGetSetParams;
57530 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57531 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57532 + fmGetSetParams.setParams.sleep = 1;
57533 +
57534 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
57535 + if (err != E_OK)
57536 + return err;
57537 +
57538 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
57539 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
57540 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
57541 +
57542 + // common
57543 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
57544 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
57545 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
57546 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
57547 + else
57548 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
57549 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
57550 +
57551 + // ARP
57552 + if (params->p_AutoResArpInfo)
57553 + {
57554 + t_DsarArpBindingEntry* arp_bindings;
57555 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57556 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
57557 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
57558 + if (params->p_AutoResArpInfo->enableConflictDetection)
57559 + WRITE_UINT16(ArpDescriptor->control, 1);
57560 + else
57561 + WRITE_UINT16(ArpDescriptor->control, 0);
57562 + if (params->p_AutoResArpInfo->tableSize)
57563 + {
57564 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
57565 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57566 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57567 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
57568 +
57569 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
57570 + {
57571 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57572 + if (arp_entry[i].isVlan)
57573 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57574 + }
57575 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
57576 + }
57577 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
57578 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
57579 + }
57580 +
57581 + // ICMPV4
57582 + if (params->p_AutoResEchoIpv4Info)
57583 + {
57584 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
57585 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57586 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
57587 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
57588 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
57589 + if (params->p_AutoResEchoIpv4Info->tableSize)
57590 + {
57591 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
57592 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57593 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57594 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
57595 +
57596 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57597 + {
57598 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57599 + if (arp_entry[i].isVlan)
57600 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57601 + }
57602 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
57603 + }
57604 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
57605 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
57606 + }
57607 +
57608 + // ICMPV6
57609 + if (params->p_AutoResEchoIpv6Info)
57610 + {
57611 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57612 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57613 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
57614 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
57615 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
57616 + if (params->p_AutoResEchoIpv6Info->tableSize)
57617 + {
57618 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
57619 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57620 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57621 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
57622 +
57623 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57624 + {
57625 + for (j = 0; j < 4; j++)
57626 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57627 + if (ndp_entry[i].isVlan)
57628 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57629 + }
57630 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57631 + }
57632 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
57633 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
57634 + }
57635 +
57636 + // ND
57637 + if (params->p_AutoResNdpInfo)
57638 + {
57639 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57640 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
57641 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
57642 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
57643 + if (params->p_AutoResNdpInfo->enableConflictDetection)
57644 + WRITE_UINT16(NDDescriptor->control, 1);
57645 + else
57646 + WRITE_UINT16(NDDescriptor->control, 0);
57647 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57648 + {
57649 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
57650 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57651 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57652 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
57653 + + params->p_AutoResNdpInfo->tableSizeTmp);
57654 +
57655 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57656 + {
57657 + for (j = 0; j < 4; j++)
57658 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57659 + if (ndp_entry[i].isVlan)
57660 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57661 + }
57662 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
57663 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57664 + {
57665 + for (j = 0; j < 4; j++)
57666 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57667 + if (ndp_entry[i].isVlan)
57668 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57669 + }
57670 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57671 + }
57672 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
57673 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
57674 + - fmMuramVirtBaseAddr);
57675 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
57676 + }
57677 +
57678 + // SNMP
57679 + if (params->p_AutoResSnmpInfo)
57680 + {
57681 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
57682 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
57683 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
57684 + t_OidsTblEntry* snmpOid;
57685 + uint8_t *charPointer;
57686 + int len;
57687 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
57688 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
57689 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
57690 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
57691 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
57692 + if (snmpSrc->numOfIpv4Addresses)
57693 + {
57694 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
57695 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
57696 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
57697 + {
57698 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
57699 + if (snmpIpv4AddrSrc[i].isVlan)
57700 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
57701 + }
57702 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
57703 + }
57704 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
57705 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
57706 + if (snmpSrc->numOfIpv6Addresses)
57707 + {
57708 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
57709 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
57710 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
57711 + {
57712 + for (j = 0; j < 4; j++)
57713 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
57714 + if (snmpIpv6AddrSrc[i].isVlan)
57715 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
57716 + }
57717 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
57718 + }
57719 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
57720 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
57721 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
57722 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
57723 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
57724 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
57725 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57726 + charPointer += len;
57727 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
57728 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
57729 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57730 + charPointer += len;
57731 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
57732 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
57733 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
57734 + {
57735 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
57736 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
57737 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
57738 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57739 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
57740 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
57741 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
57742 + else
57743 + {
57744 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
57745 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57746 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
57747 + }
57748 + snmpOid++;
57749 + }
57750 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
57751 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
57752 + }
57753 +
57754 + // filtering
57755 + if (params->p_AutoResFilteringInfo)
57756 + {
57757 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
57758 + tmp |= IP_PROT_TBL_PASS_MASK;
57759 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
57760 + tmp |= UDP_PORT_TBL_PASS_MASK;
57761 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
57762 + tmp |= TCP_PORT_TBL_PASS_MASK;
57763 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
57764 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
57765 +
57766 + // ip filtering
57767 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
57768 + {
57769 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
57770 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
57771 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
57772 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
57773 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
57774 + }
57775 +
57776 + // udp filtering
57777 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
57778 + {
57779 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
57780 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
57781 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
57782 + {
57783 + WRITE_UINT32(udp_tbl[i].Ports,
57784 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
57785 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
57786 + WRITE_UINT32(udp_tbl[i].PortsMask,
57787 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
57788 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
57789 + }
57790 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
57791 + }
57792 +
57793 + // tcp filtering
57794 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
57795 + {
57796 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
57797 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
57798 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
57799 + {
57800 + WRITE_UINT32(tcp_tbl[i].Ports,
57801 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
57802 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
57803 + WRITE_UINT32(tcp_tbl[i].PortsMask,
57804 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
57805 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
57806 + }
57807 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
57808 + }
57809 + }
57810 + // common stats
57811 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
57812 +
57813 + // get into Deep Sleep sequence:
57814 +
57815 + // Ensures that FMan do not enter the idle state. This is done by programing
57816 + // FMDPSLPCR[FM_STOP] to one.
57817 + fm_soc_suspend();
57818 +
57819 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
57820 + return E_OK;
57821 +
57822 +}
57823 +
57824 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
57825 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
57826 +{
57827 + t_FmGetSetParams fmGetSetParams;
57828 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
57829 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
57830 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
57831 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
57832 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57833 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
57834 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57835 +
57836 + /* Issue graceful stop to HC port */
57837 + FM_PORT_Disable(p_FmPortHc);
57838 +
57839 + // config tx port
57840 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
57841 + 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);
57842 + // ????
57843 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
57844 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
57845 + // Stage 7:echo
57846 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
57847 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
57848 + if (!PrsIsEnabled(h_FmPcd))
57849 + {
57850 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
57851 + PrsEnable(h_FmPcd);
57852 + }
57853 + else
57854 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
57855 +
57856 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
57857 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
57858 +
57859 + // save rcfg for restoring: accumulate mode is changed by ucode
57860 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
57861 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
57862 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57863 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57864 + fmGetSetParams.setParams.sleep = 1;
57865 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57866 +
57867 +// ***** issue external request sync command
57868 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57869 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
57870 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57871 + // get
57872 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57873 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
57874 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57875 + if (fmGetSetParams.getParams.fmfp_extc != 0)
57876 + {
57877 + // clear
57878 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57879 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
57880 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57881 +}
57882 +
57883 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57884 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
57885 + do
57886 + {
57887 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57888 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
57889 + if (fmGetSetParams.getParams.fm_npi != 0)
57890 + XX_Print("FM: Sync did not finish\n");
57891 +
57892 + // check that all stoped
57893 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57894 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
57895 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57896 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
57897 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57898 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
57899 + XX_Print("FM: Sleeping\n");
57900 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
57901 +
57902 + return E_OK;
57903 +}
57904 +
57905 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
57906 +
57907 +void FM_PORT_Dsar_DumpRegs()
57908 +{
57909 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
57910 + DUMP_MEMORY(hh, 0x220);
57911 +}
57912 +
57913 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
57914 +{
57915 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57916 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
57917 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
57918 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
57919 + t_FmGetSetParams fmGetSetParams;
57920 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57921 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57922 + fmGetSetParams.setParams.sleep = 0;
57923 + if (p_FmPort->deepSleepVars.autoResOffsets)
57924 + {
57925 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
57926 + p_FmPort->deepSleepVars.autoResOffsets = 0;
57927 + }
57928 +
57929 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
57930 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
57931 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
57932 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
57933 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
57934 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
57935 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
57936 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
57937 + FM_PORT_Enable(p_FmPortHc);
57938 +}
57939 +
57940 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
57941 +{
57942 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
57943 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
57944 +}
57945 +
57946 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
57947 +{
57948 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57949 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
57950 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
57951 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57952 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57953 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57954 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
57955 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57956 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
57957 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
57958 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
57959 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57960 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
57961 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
57962 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
57963 + stats->arpArCnt = arp_stats->arCnt;
57964 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
57965 + stats->ndpArCnt = nd_stats->arCnt;
57966 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
57967 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
57968 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
57969 + return E_OK;
57970 +}
57971 --- /dev/null
57972 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
57973 @@ -0,0 +1,999 @@
57974 +/*
57975 + * Copyright 2008-2012 Freescale Semiconductor Inc.
57976 + *
57977 + * Redistribution and use in source and binary forms, with or without
57978 + * modification, are permitted provided that the following conditions are met:
57979 + * * Redistributions of source code must retain the above copyright
57980 + * notice, this list of conditions and the following disclaimer.
57981 + * * Redistributions in binary form must reproduce the above copyright
57982 + * notice, this list of conditions and the following disclaimer in the
57983 + * documentation and/or other materials provided with the distribution.
57984 + * * Neither the name of Freescale Semiconductor nor the
57985 + * names of its contributors may be used to endorse or promote products
57986 + * derived from this software without specific prior written permission.
57987 + *
57988 + *
57989 + * ALTERNATIVELY, this software may be distributed under the terms of the
57990 + * GNU General Public License ("GPL") as published by the Free Software
57991 + * Foundation, either version 2 of that License or (at your option) any
57992 + * later version.
57993 + *
57994 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
57995 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
57996 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57997 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
57998 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57999 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58000 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58001 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58002 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58003 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58004 + */
58005 +
58006 +
58007 +/******************************************************************************
58008 + @File fm_port.h
58009 +
58010 + @Description FM Port internal structures and definitions.
58011 +*//***************************************************************************/
58012 +#ifndef __FM_PORT_H
58013 +#define __FM_PORT_H
58014 +
58015 +#include "error_ext.h"
58016 +#include "std_ext.h"
58017 +#include "fm_port_ext.h"
58018 +
58019 +#include "fm_common.h"
58020 +#include "fm_sp_common.h"
58021 +#include "fsl_fman_sp.h"
58022 +#include "fm_port_ext.h"
58023 +#include "fsl_fman_port.h"
58024 +
58025 +#define __ERR_MODULE__ MODULE_FM_PORT
58026 +
58027 +
58028 +#define MIN_EXT_BUF_SIZE 64
58029 +#define DATA_ALIGNMENT 64
58030 +#define MAX_LIODN_OFFSET 64
58031 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
58032 +
58033 +/**************************************************************************//**
58034 + @Description Memory Map defines
58035 +*//***************************************************************************/
58036 +#define BMI_PORT_REGS_OFFSET 0
58037 +#define QMI_PORT_REGS_OFFSET 0x400
58038 +#define PRS_PORT_REGS_OFFSET 0x800
58039 +
58040 +/**************************************************************************//**
58041 + @Description defaults
58042 +*//***************************************************************************/
58043 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
58044 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
58045 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
58046 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
58047 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
58048 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
58049 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
58050 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
58051 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
58052 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
58053 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
58054 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
58055 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
58056 +#define DEFAULT_PORT_cutBytesFromEnd 4
58057 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
58058 +
58059 +#define DEFAULT_PORT_frmDiscardOverride FALSE
58060 +
58061 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
58062 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
58063 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
58064 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
58065 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
58066 +
58067 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
58068 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
58069 +#define DEFAULT_PORT_BufMargins_startMargins 32
58070 +#define DEFAULT_PORT_BufMargins_endMargins 0
58071 +#define DEFAULT_PORT_syncReq TRUE
58072 +#define DEFAULT_PORT_syncReqForHc FALSE
58073 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
58074 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
58075 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
58076 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
58077 +#define DEFAULT_PORT_exception IM_EV_BSY
58078 +#define DEFAULT_PORT_maxFrameLength 9600
58079 +
58080 +#define DEFAULT_notSupported 0xff
58081 +
58082 +#if (DPAA_VERSION < 11)
58083 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58084 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
58085 +
58086 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58087 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
58088 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
58089 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58090 +
58091 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58092 +
58093 +/* Host command port MUST NOT be changed to more than 1 !!! */
58094 +#define DEFAULT_PORT_numOfTasks(type) \
58095 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58096 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
58097 + ((((type) == e_FM_PORT_TYPE_RX) || \
58098 + ((type) == e_FM_PORT_TYPE_TX) || \
58099 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
58100 +
58101 +#define DEFAULT_PORT_extraNumOfTasks(type) \
58102 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58103 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
58104 +
58105 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58106 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
58107 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
58108 +
58109 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
58110 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58111 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
58112 +
58113 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58114 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58115 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
58116 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
58117 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
58118 +
58119 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58120 +
58121 +#else /* (DPAA_VERSION < 11) */
58122 +/* Defaults are registers' reset values */
58123 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58124 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
58125 +
58126 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58127 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
58128 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
58129 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58130 +
58131 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58132 +
58133 +#define DEFAULT_PORT_numOfTasks(type) \
58134 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58135 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
58136 + (((type) == e_FM_PORT_TYPE_RX) || \
58137 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
58138 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
58139 +
58140 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
58141 +
58142 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58143 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58144 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
58145 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
58146 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
58147 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
58148 +
58149 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
58150 +
58151 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58152 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
58153 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
58154 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
58155 +
58156 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58157 +
58158 +#endif /* (DPAA_VERSION < 11) */
58159 +
58160 +#define DEFAULT_PORT_txBdRingLength 16
58161 +#define DEFAULT_PORT_rxBdRingLength 128
58162 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
58163 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
58164 +
58165 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58166 +
58167 +/**************************************************************************//**
58168 + @Collection PCD Engines
58169 +*//***************************************************************************/
58170 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
58171 +
58172 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
58173 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
58174 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
58175 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
58176 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
58177 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
58178 +/* @} */
58179 +
58180 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
58181 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
58182 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58183 +
58184 +#define FM_OH_PORT_ID 0
58185 +
58186 +/***********************************************************************/
58187 +/* SW parser OFFLOAD labels (offsets) */
58188 +/***********************************************************************/
58189 +#if (DPAA_VERSION == 10)
58190 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
58191 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
58192 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
58193 +#else
58194 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
58195 +/* Will be used for:
58196 + * 1. identify fragments
58197 + * 2. udp-lite
58198 + */
58199 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
58200 +/* Will be used for:
58201 + * 1. will identify the fragmentable area
58202 + * 2. udp-lite
58203 + */
58204 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
58205 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
58206 +#endif /* (DPAA_VERSION == 10) */
58207 +
58208 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
58209 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
58210 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
58211 +
58212 +
58213 +/**************************************************************************//**
58214 + @Description Memory Mapped Registers
58215 +*//***************************************************************************/
58216 +
58217 +#if defined(__MWERKS__) && !defined(__GNUC__)
58218 +#pragma pack(push,1)
58219 +#endif /* defined(__MWERKS__) && ... */
58220 +
58221 +typedef struct
58222 +{
58223 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
58224 + volatile uint32_t fmbm_rst; /**< Rx Status */
58225 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
58226 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
58227 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
58228 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
58229 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
58230 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
58231 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
58232 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
58233 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
58234 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
58235 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
58236 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
58237 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
58238 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
58239 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58240 + /**< Rx Parse Results Array Initialization*/
58241 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
58242 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
58243 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
58244 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
58245 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
58246 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
58247 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
58248 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
58249 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58250 + /**< Buffer Manager pool Information-*/
58251 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58252 + /**< Allocate Counter-*/
58253 + volatile uint32_t reserved4[0x08];
58254 + /**< 0x130/0x140 - 0x15F reserved -*/
58255 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
58256 + /**< Congestion Group Map*/
58257 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
58258 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
58259 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
58260 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
58261 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
58262 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
58263 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
58264 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
58265 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
58266 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
58267 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
58268 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
58269 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
58270 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
58271 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
58272 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
58273 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
58274 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
58275 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
58276 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
58277 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
58278 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
58279 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
58280 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
58281 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
58282 +} t_FmPortRxBmiRegs;
58283 +
58284 +typedef struct
58285 +{
58286 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
58287 + volatile uint32_t fmbm_tst; /**< Tx Status */
58288 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
58289 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
58290 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
58291 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
58292 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
58293 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
58294 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
58295 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
58296 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
58297 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
58298 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
58299 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
58300 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
58301 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
58302 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
58303 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
58304 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
58305 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
58306 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
58307 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
58308 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
58309 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
58310 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
58311 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
58312 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
58313 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
58314 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
58315 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
58316 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
58317 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
58318 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
58319 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
58320 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
58321 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
58322 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
58323 +} t_FmPortTxBmiRegs;
58324 +
58325 +typedef struct
58326 +{
58327 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
58328 + volatile uint32_t fmbm_ost; /**< O/H Status */
58329 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
58330 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
58331 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
58332 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
58333 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
58334 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
58335 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
58336 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
58337 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
58338 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
58339 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
58340 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
58341 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
58342 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58343 + /**< O/H Parse Results Array Initialization */
58344 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
58345 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
58346 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
58347 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
58348 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
58349 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
58350 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
58351 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
58352 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
58353 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
58354 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
58355 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
58356 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
58357 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
58358 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
58359 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
58360 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
58361 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
58362 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
58363 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
58364 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
58365 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
58366 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
58367 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
58368 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
58369 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
58370 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
58371 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
58372 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
58373 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
58374 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
58375 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
58376 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
58377 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
58378 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
58379 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
58380 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
58381 +} t_FmPortOhBmiRegs;
58382 +
58383 +typedef union
58384 +{
58385 + t_FmPortRxBmiRegs rxPortBmiRegs;
58386 + t_FmPortTxBmiRegs txPortBmiRegs;
58387 + t_FmPortOhBmiRegs ohPortBmiRegs;
58388 +} u_FmPortBmiRegs;
58389 +
58390 +typedef struct
58391 +{
58392 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
58393 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
58394 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
58395 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
58396 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
58397 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
58398 +} t_FmPortNonRxQmiRegs;
58399 +
58400 +typedef struct
58401 +{
58402 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
58403 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
58404 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
58405 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
58406 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
58407 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
58408 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
58409 +} t_FmPortQmiRegs;
58410 +
58411 +typedef struct
58412 +{
58413 + struct
58414 + {
58415 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
58416 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
58417 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
58418 + volatile uint32_t reserved0[0xde];
58419 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
58420 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
58421 +} t_FmPortPrsRegs;
58422 +
58423 +/**************************************************************************//*
58424 + @Description Basic buffer descriptor (BD) structure
58425 +*//***************************************************************************/
58426 +typedef _Packed struct
58427 +{
58428 + volatile uint16_t status;
58429 + volatile uint16_t length;
58430 + volatile uint8_t reserved0[0x6];
58431 + volatile uint8_t reserved1[0x1];
58432 + volatile t_FmPhysAddr buff;
58433 +} _PackedType t_FmImBd;
58434 +
58435 +typedef _Packed struct
58436 +{
58437 + volatile uint16_t gen; /**< tbd */
58438 + volatile uint8_t reserved0[0x1];
58439 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
58440 + volatile uint16_t bdRingSize; /**< tbd */
58441 + volatile uint16_t offsetIn; /**< tbd */
58442 + volatile uint16_t offsetOut; /**< tbd */
58443 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
58444 +} _PackedType t_FmPortImQd;
58445 +
58446 +typedef _Packed struct
58447 +{
58448 + volatile uint32_t mode; /**< Mode register */
58449 + volatile uint32_t rxQdPtr; /**< tbd */
58450 + volatile uint32_t txQdPtr; /**< tbd */
58451 + volatile uint16_t mrblr; /**< tbd */
58452 + volatile uint16_t rxQdBsyCnt; /**< tbd */
58453 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
58454 + t_FmPortImQd rxQd;
58455 + t_FmPortImQd txQd;
58456 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
58457 +} _PackedType t_FmPortImPram;
58458 +
58459 +#if defined(__MWERKS__) && !defined(__GNUC__)
58460 +#pragma pack(pop)
58461 +#endif /* defined(__MWERKS__) && ... */
58462 +
58463 +
58464 +/**************************************************************************//**
58465 + @Description Registers bit fields
58466 +*//***************************************************************************/
58467 +
58468 +/**************************************************************************//**
58469 + @Description BMI defines
58470 +*//***************************************************************************/
58471 +#if (DPAA_VERSION >= 11)
58472 +#define BMI_SP_ID_MASK 0xff000000
58473 +#define BMI_SP_ID_SHIFT 24
58474 +#define BMI_SP_EN 0x01000000
58475 +#endif /* (DPAA_VERSION >= 11) */
58476 +
58477 +#define BMI_PORT_CFG_EN 0x80000000
58478 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
58479 +#define BMI_PORT_CFG_FDOVR 0x02000000
58480 +#define BMI_PORT_CFG_IM 0x01000000
58481 +#define BMI_PORT_CFG_AM 0x00000040
58482 +#define BMI_PORT_STATUS_BSY 0x80000000
58483 +#define BMI_COUNTERS_EN 0x80000000
58484 +
58485 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
58486 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
58487 +#define BMI_RFNE_FDCS_MASK 0xFF000000
58488 +#define BMI_RFNE_HXS_MASK 0x000000FF
58489 +
58490 +#define BMI_CMD_MR_LEAC 0x00200000
58491 +#define BMI_CMD_MR_SLEAC 0x00100000
58492 +#define BMI_CMD_MR_MA 0x00080000
58493 +#define BMI_CMD_MR_DEAS 0x00040000
58494 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
58495 + BMI_CMD_MR_SLEAC | \
58496 + BMI_CMD_MR_MA | \
58497 + BMI_CMD_MR_DEAS)
58498 +#define BMI_CMD_ATTR_ORDER 0x80000000
58499 +#define BMI_CMD_ATTR_SYNC 0x02000000
58500 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
58501 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
58502 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
58503 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
58504 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
58505 +
58506 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
58507 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
58508 + FM_PORT_FRM_ERR_PHYSICAL | \
58509 + FM_PORT_FRM_ERR_SIZE | \
58510 + FM_PORT_FRM_ERR_CLS_DISCARD | \
58511 + FM_PORT_FRM_ERR_EXTRACTION | \
58512 + FM_PORT_FRM_ERR_NO_SCHEME | \
58513 + FM_PORT_FRM_ERR_COLOR_RED | \
58514 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
58515 + FM_PORT_FRM_ERR_ILL_PLCR | \
58516 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58517 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58518 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58519 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58520 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58521 + FM_PORT_FRM_ERR_IPRE | \
58522 + FM_PORT_FRM_ERR_IPR_NCSP | \
58523 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
58524 +
58525 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
58526 + ~(FM_PORT_FRM_ERR_LENGTH | \
58527 + FM_PORT_FRM_ERR_NON_FM | \
58528 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
58529 +
58530 +#define BMI_RATE_LIMIT_EN 0x80000000
58531 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
58532 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
58533 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
58534 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
58535 +
58536 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
58537 +
58538 +#define BMI_PRS_RESULT_HIGH 0x00000000
58539 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
58540 +
58541 +
58542 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
58543 + FM_PORT_FRM_ERR_PHYSICAL | \
58544 + FM_PORT_FRM_ERR_SIZE | \
58545 + FM_PORT_FRM_ERR_EXTRACTION | \
58546 + FM_PORT_FRM_ERR_NO_SCHEME | \
58547 + FM_PORT_FRM_ERR_ILL_PLCR | \
58548 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58549 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58550 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58551 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58552 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58553 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
58554 + FM_PORT_FRM_ERR_IPRE)
58555 +
58556 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
58557 + FM_PORT_FRM_ERR_LENGTH | \
58558 + FM_PORT_FRM_ERR_NON_FM | \
58559 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
58560 +
58561 +
58562 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
58563 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
58564 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
58565 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
58566 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
58567 +
58568 +/* shifts */
58569 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
58570 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
58571 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
58572 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
58573 +
58574 +#define BMI_IM_FOF_SHIFT 28
58575 +#define BMI_PR_PORTID_SHIFT 24
58576 +
58577 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
58578 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
58579 +
58580 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
58581 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
58582 +
58583 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
58584 +
58585 +#define BMI_INT_BUF_MARG_SHIFT 28
58586 +
58587 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
58588 +
58589 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
58590 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
58591 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
58592 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
58593 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
58594 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
58595 +
58596 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
58597 +
58598 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
58599 +#define BMI_TX_LOW_COMF_SHIFT 0
58600 +
58601 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
58602 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
58603 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
58604 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
58605 +
58606 +#define BMI_MAX_BURST_SHIFT 16
58607 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
58608 +
58609 +/* sizes */
58610 +#define FRAME_END_DATA_SIZE 16
58611 +#define FRAME_OFFSET_UNITS 16
58612 +#define MIN_TX_INT_OFFSET 16
58613 +#define MAX_FRAME_OFFSET 64
58614 +#define MAX_FIFO_PIPELINE_DEPTH 8
58615 +#define MAX_PERFORMANCE_TASK_COMP 64
58616 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
58617 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
58618 +#define MAX_PERFORMANCE_DMA_COMP 16
58619 +#define MAX_NUM_OF_TASKS 64
58620 +#define MAX_NUM_OF_EXTRA_TASKS 8
58621 +#define MAX_NUM_OF_DMAS 16
58622 +#define MAX_NUM_OF_EXTRA_DMAS 8
58623 +#define MAX_BURST_SIZE 1024
58624 +#define MIN_NUM_OF_OP_DMAS 2
58625 +
58626 +
58627 +/**************************************************************************//**
58628 + @Description QMI defines
58629 +*//***************************************************************************/
58630 +/* masks */
58631 +#define QMI_PORT_CFG_EN 0x80000000
58632 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
58633 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
58634 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
58635 +
58636 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
58637 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
58638 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
58639 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
58640 +
58641 +#define QMI_DEQ_CFG_PRI 0x80000000
58642 +#define QMI_DEQ_CFG_TYPE1 0x10000000
58643 +#define QMI_DEQ_CFG_TYPE2 0x20000000
58644 +#define QMI_DEQ_CFG_TYPE3 0x30000000
58645 +
58646 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
58647 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
58648 +
58649 +/**************************************************************************//**
58650 + @Description PARSER defines
58651 +*//***************************************************************************/
58652 +/* masks */
58653 +#define PRS_HDR_ERROR_DIS 0x00000800
58654 +#define PRS_HDR_SW_PRS_EN 0x00000400
58655 +#define PRS_CP_OFFSET_MASK 0x0000000F
58656 +#define PRS_TPID1_MASK 0xFFFF0000
58657 +#define PRS_TPID2_MASK 0x0000FFFF
58658 +#define PRS_TPID_DFLT 0x91009100
58659 +
58660 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
58661 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
58662 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
58663 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
58664 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
58665 +#define PRS_CAC_STOP 0x00000001
58666 +#define PRS_CAC_ACTIVE 0x00000100
58667 +
58668 +/* shifts */
58669 +#define PRS_PCTPID_SHIFT 16
58670 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
58671 +#define PRS_HDR_ETH_BC_SHIFT 28
58672 +#define PRS_HDR_ETH_MC_SHIFT 24
58673 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
58674 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
58675 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
58676 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
58677 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
58678 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
58679 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
58680 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
58681 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
58682 +
58683 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
58684 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
58685 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
58686 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
58687 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
58688 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
58689 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
58690 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
58691 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
58692 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
58693 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
58694 +
58695 +/* others */
58696 +#define PRS_HDR_ENTRY_SIZE 8
58697 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
58698 +
58699 +#define IPSEC_SW_PATCH_START 0x20
58700 +#define SCTP_SW_PATCH_START 0x4D
58701 +#define DCCP_SW_PATCH_START 0x41
58702 +
58703 +/**************************************************************************//**
58704 + @Description IM defines
58705 +*//***************************************************************************/
58706 +#define BD_R_E 0x80000000
58707 +#define BD_L 0x08000000
58708 +
58709 +#define BD_RX_CRE 0x00080000
58710 +#define BD_RX_FTL 0x00040000
58711 +#define BD_RX_FTS 0x00020000
58712 +#define BD_RX_OV 0x00010000
58713 +
58714 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
58715 +
58716 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
58717 +
58718 +#define BD_STATUS_MASK 0xffff0000
58719 +#define BD_LENGTH_MASK 0x0000ffff
58720 +
58721 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
58722 +
58723 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
58724 +
58725 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
58726 +
58727 +#define IM_ILEGAL_BD_ID 0xffff
58728 +
58729 +/* others */
58730 +#define IM_PRAM_ALIGN 0x100
58731 +
58732 +/* masks */
58733 +#define IM_MODE_GBL 0x20000000
58734 +#define IM_MODE_BO_MASK 0x18000000
58735 +#define IM_MODE_BO_SHIFT 3
58736 +#define IM_MODE_GRC_STP 0x00800000
58737 +
58738 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
58739 +
58740 +#define IM_RXQD_BSYINTM 0x0008
58741 +#define IM_RXQD_RXFINTM 0x0010
58742 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
58743 +
58744 +#define IM_EV_BSY 0x40000000
58745 +#define IM_EV_RX 0x80000000
58746 +
58747 +
58748 +/**************************************************************************//**
58749 + @Description Additional defines
58750 +*//***************************************************************************/
58751 +
58752 +typedef struct {
58753 + t_Handle h_FmMuram;
58754 + t_FmPortImPram *p_FmPortImPram;
58755 + uint8_t fwExtStructsMemId;
58756 + uint32_t fwExtStructsMemAttr;
58757 + uint16_t bdRingSize;
58758 + t_FmImBd *p_BdRing;
58759 + t_Handle *p_BdShadow;
58760 + uint16_t currBdId;
58761 + uint16_t firstBdOfFrameId;
58762 +
58763 + /* Rx port parameters */
58764 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
58765 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
58766 + t_BufferPoolInfo rxPool;
58767 + uint16_t mrblr;
58768 + uint16_t rxFrameAccumLength;
58769 + t_FmPortImRxStoreCallback *f_RxStore;
58770 +
58771 + /* Tx port parameters */
58772 + uint32_t txFirstBdStatus;
58773 + t_FmPortImTxConfCallback *f_TxConf;
58774 +} t_FmMacIm;
58775 +
58776 +
58777 +typedef struct {
58778 + struct fman_port_cfg dfltCfg;
58779 + uint32_t dfltFqid;
58780 + uint32_t confFqid;
58781 + uint32_t errFqid;
58782 + uintptr_t baseAddr;
58783 + uint8_t deqSubPortal;
58784 + bool deqHighPriority;
58785 + e_FmPortDeqType deqType;
58786 + e_FmPortDeqPrefetchOption deqPrefetchOption;
58787 + uint16_t deqByteCnt;
58788 + uint8_t cheksumLastBytesIgnore;
58789 + uint8_t cutBytesFromEnd;
58790 + t_FmBufPoolDepletion bufPoolDepletion;
58791 + uint8_t pipelineDepth;
58792 + uint16_t fifoLowComfLevel;
58793 + bool frmDiscardOverride;
58794 + bool enRateLimit;
58795 + t_FmPortRateLimit rateLimit;
58796 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
58797 + bool enBufPoolDepletion;
58798 + uint16_t liodnOffset;
58799 + uint16_t liodnBase;
58800 + t_FmExtPools extBufPools;
58801 + e_FmDmaSwapOption dmaSwapData;
58802 + e_FmDmaCacheOption dmaIntContextCacheAttr;
58803 + e_FmDmaCacheOption dmaHeaderCacheAttr;
58804 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
58805 + bool dmaReadOptimize;
58806 + bool dmaWriteOptimize;
58807 + uint32_t txFifoMinFillLevel;
58808 + uint32_t txFifoLowComfLevel;
58809 + uint32_t rxFifoPriElevationLevel;
58810 + uint32_t rxFifoThreshold;
58811 + t_FmSpBufMargins bufMargins;
58812 + t_FmSpIntContextDataCopy intContext;
58813 + bool syncReq;
58814 + e_FmPortColor color;
58815 + fmPortFrameErrSelect_t errorsToDiscard;
58816 + fmPortFrameErrSelect_t errorsToEnq;
58817 + bool forwardReuseIntContext;
58818 + t_FmBufferPrefixContent bufferPrefixContent;
58819 + t_FmBackupBmPools *p_BackupBmPools;
58820 + bool dontReleaseBuf;
58821 + bool setNumOfTasks;
58822 + bool setNumOfOpenDmas;
58823 + bool setSizeOfFifo;
58824 +#if (DPAA_VERSION >= 11)
58825 + bool noScatherGather;
58826 +#endif /* (DPAA_VERSION >= 11) */
58827 +
58828 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
58829 + bool bcbWorkaround;
58830 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
58831 +} t_FmPortDriverParam;
58832 +
58833 +
58834 +typedef struct t_FmPortRxPoolsParams
58835 +{
58836 + uint8_t numOfPools;
58837 + uint16_t secondLargestBufSize;
58838 + uint16_t largestBufSize;
58839 +} t_FmPortRxPoolsParams;
58840 +
58841 +typedef struct t_FmPortDsarVars {
58842 + t_Handle *autoResOffsets;
58843 + t_FmPortDsarTablesSizes *autoResMaxSizes;
58844 + uint32_t fmbm_tcfg;
58845 + uint32_t fmbm_tcmne;
58846 + uint32_t fmbm_rfne;
58847 + uint32_t fmbm_rfpne;
58848 + uint32_t fmbm_rcfg;
58849 + bool dsarEnabledParser;
58850 +} t_FmPortDsarVars;
58851 +typedef struct {
58852 + struct fman_port port;
58853 + t_Handle h_Fm;
58854 + t_Handle h_FmPcd;
58855 + t_Handle h_FmMuram;
58856 + t_FmRevisionInfo fmRevInfo;
58857 + uint8_t portId;
58858 + e_FmPortType portType;
58859 + int enabled;
58860 + char name[MODULE_NAME_SIZE];
58861 + uint8_t hardwarePortId;
58862 + uint16_t fmClkFreq;
58863 + t_FmPortQmiRegs *p_FmPortQmiRegs;
58864 + u_FmPortBmiRegs *p_FmPortBmiRegs;
58865 + t_FmPortPrsRegs *p_FmPortPrsRegs;
58866 + fmPcdEngines_t pcdEngines;
58867 + uint32_t savedBmiNia;
58868 + uint8_t netEnvId;
58869 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
58870 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
58871 + uint8_t privateInfo;
58872 + uint32_t schemesPerPortVector;
58873 + bool useClsPlan;
58874 + uint8_t clsPlanGrpId;
58875 + t_Handle ccTreeId;
58876 + t_Handle completeArg;
58877 + void (*f_Complete)(t_Handle arg);
58878 + t_FmSpBufferOffsets bufferOffsets;
58879 + /* Independent-Mode parameters support */
58880 + bool imEn;
58881 + t_FmMacIm im;
58882 + volatile bool lock;
58883 + t_Handle h_Spinlock;
58884 + t_FmPortExceptionCallback *f_Exception;
58885 + t_Handle h_App;
58886 + uint8_t internalBufferOffset;
58887 + uint8_t fmanCtrlEventId;
58888 + uint32_t exceptions;
58889 + bool polling;
58890 + t_FmExtPools extBufPools;
58891 + uint32_t requiredAction;
58892 + uint32_t savedQmiPnen;
58893 + uint32_t savedBmiFene;
58894 + uint32_t savedBmiFpne;
58895 + uint32_t savedBmiCmne;
58896 + uint32_t savedBmiOfp;
58897 + uint32_t savedNonRxQmiRegsPndn;
58898 + uint32_t origNonRxQmiRegsPndn;
58899 + int savedPrsStartOffset;
58900 + bool includeInPrsStatistics;
58901 + uint16_t maxFrameLength;
58902 + t_FmFmanCtrl orFmanCtrl;
58903 + t_FmPortRsrc openDmas;
58904 + t_FmPortRsrc tasks;
58905 + t_FmPortRsrc fifoBufs;
58906 + t_FmPortRxPoolsParams rxPoolsParams;
58907 +// bool explicitUserSizeOfFifo;
58908 + t_Handle h_IpReassemblyManip;
58909 + t_Handle h_CapwapReassemblyManip;
58910 + t_Handle h_ReassemblyTree;
58911 + uint64_t fmMuramPhysBaseAddr;
58912 +#if (DPAA_VERSION >= 11)
58913 + bool vspe;
58914 + uint8_t dfltRelativeId;
58915 + e_FmPortGprFuncType gprFunc;
58916 + t_FmPcdCtrlParamsPage *p_ParamsPage;
58917 +#endif /* (DPAA_VERSION >= 11) */
58918 + t_FmPortDsarVars deepSleepVars;
58919 + t_FmPortDriverParam *p_FmPortDriverParam;
58920 +} t_FmPort;
58921 +
58922 +
58923 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
58924 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
58925 +
58926 +t_Error FmPortImInit(t_FmPort *p_FmPort);
58927 +void FmPortImFree(t_FmPort *p_FmPort);
58928 +
58929 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
58930 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
58931 +t_Error FmPortImRx (t_FmPort *p_FmPort);
58932 +
58933 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
58934 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
58935 +
58936 +
58937 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
58938 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
58939 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
58940 +
58941 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
58942 +{
58943 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
58944 + physAddr |= GET_UINT32(p_Bd->buff.low);
58945 +
58946 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
58947 +}
58948 +
58949 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
58950 +{
58951 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
58952 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
58953 +}
58954 +
58955 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
58956 +{
58957 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
58958 + SET_ADDR(&p_Bd->buff, physAddr);
58959 +}
58960 +
58961 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
58962 +{
58963 + if (id < p_FmPort->im.bdRingSize-1)
58964 + return (uint16_t)(id+1);
58965 + else
58966 + return 0;
58967 +}
58968 +
58969 +void FM_PORT_Dsar_DumpRegs(void);
58970 +
58971 +
58972 +#endif /* __FM_PORT_H */
58973 --- /dev/null
58974 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
58975 @@ -0,0 +1,494 @@
58976 +/*
58977 + * Copyright 2008-2012 Freescale Semiconductor Inc.
58978 + *
58979 + * Redistribution and use in source and binary forms, with or without
58980 + * modification, are permitted provided that the following conditions are met:
58981 + * * Redistributions of source code must retain the above copyright
58982 + * notice, this list of conditions and the following disclaimer.
58983 + * * Redistributions in binary form must reproduce the above copyright
58984 + * notice, this list of conditions and the following disclaimer in the
58985 + * documentation and/or other materials provided with the distribution.
58986 + * * Neither the name of Freescale Semiconductor nor the
58987 + * names of its contributors may be used to endorse or promote products
58988 + * derived from this software without specific prior written permission.
58989 + *
58990 + *
58991 + * ALTERNATIVELY, this software may be distributed under the terms of the
58992 + * GNU General Public License ("GPL") as published by the Free Software
58993 + * Foundation, either version 2 of that License or (at your option) any
58994 + * later version.
58995 + *
58996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
58997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59006 + */
59007 +
59008 +/**************************************************************************//**
59009 + @File fm_port_dsar.h
59010 +
59011 + @Description Deep Sleep Auto Response project - common module header file.
59012 +
59013 + Author - Eyal Harari
59014 +
59015 + @Cautions See the FMan Controller spec and design document for more information.
59016 +*//***************************************************************************/
59017 +
59018 +#ifndef __FM_PORT_DSAR_H_
59019 +#define __FM_PORT_DSAR_H_
59020 +
59021 +#define DSAR_GETSER_MASK 0xFF0000FF
59022 +
59023 +#if defined(__MWERKS__) && !defined(__GNUC__)
59024 +#pragma pack(push,1)
59025 +#endif /* defined(__MWERKS__) && ... */
59026 +
59027 +/**************************************************************************//**
59028 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59029 + Refer to the FMan Controller spec for more details.
59030 +*//***************************************************************************/
59031 +typedef _Packed struct
59032 +{
59033 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59034 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59035 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59036 + uint16_t reserved;
59037 +} _PackedType t_DsarArpBindingEntry;
59038 +
59039 +/**************************************************************************//**
59040 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
59041 + Refer to the FMan Controller spec for more details.
59042 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
59043 + 0x04 ECHO_CNT Echo counter
59044 + 0x08 CD_CNT Conflict Detection counter
59045 + 0x0C AR_CNT Auto-Response counter
59046 + 0x10 RATM_CNT Replies Addressed To Me counter
59047 + 0x14 UKOP_CNT Unknown Operation counter
59048 + 0x18 NMTP_CNT Not my TPA counter
59049 + 0x1C NMVLAN_CNT Not My VLAN counter
59050 +*//***************************************************************************/
59051 +typedef _Packed struct
59052 +{
59053 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
59054 + uint32_t echoCnt; /**< Echo counter. */
59055 + uint32_t cdCnt; /**< Conflict Detection counter. */
59056 + uint32_t arCnt; /**< Auto-Response counter. */
59057 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
59058 + uint32_t ukopCnt; /**< Unknown Operation counter. */
59059 + uint32_t nmtpCnt; /**< Not my TPA counter. */
59060 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59061 +} _PackedType t_DsarArpStatistics;
59062 +
59063 +
59064 +/**************************************************************************//**
59065 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
59066 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
59067 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59068 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
59069 + 0x6 0-15
59070 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
59071 + 0xA 0-15
59072 + 0xC 0-15 Reserved Reserved. Must be cleared.
59073 + 0xE 015
59074 +
59075 +*//***************************************************************************/
59076 +typedef _Packed struct
59077 +{
59078 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
59079 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59080 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59081 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59082 + uint32_t reserved1; /**< Reserved. */
59083 +} _PackedType t_DsarArpDescriptor;
59084 +
59085 +
59086 +/**************************************************************************//**
59087 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59088 + Refer to the FMan Controller spec for more details.
59089 +*//***************************************************************************/
59090 +typedef _Packed struct
59091 +{
59092 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59093 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59094 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59095 + uint16_t reserved;
59096 +} _PackedType t_DsarIcmpV4BindingEntry;
59097 +
59098 +/**************************************************************************//**
59099 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59100 + Refer to the FMan Controller spec for more details.
59101 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59102 + 0x04 NMVLAN_CNT Not My VLAN counter
59103 + 0x08 NMIP_CNT Not My IP counter
59104 + 0x0C AR_CNT Auto-Response counter
59105 + 0x10 CSERR_CNT Checksum Error counter
59106 + 0x14 Reserved Reserved
59107 + 0x18 Reserved Reserved
59108 + 0x1C Reserved Reserved
59109 +
59110 +*//***************************************************************************/
59111 +typedef _Packed struct
59112 +{
59113 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59114 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59115 + uint32_t nmIpCnt; /**< Not My IP counter */
59116 + uint32_t arCnt; /**< Auto-Response counter */
59117 + uint32_t cserrCnt; /**< Checksum Error counter */
59118 + uint32_t reserved0; /**< Reserved */
59119 + uint32_t reserved1; /**< Reserved */
59120 + uint32_t reserved2; /**< Reserved */
59121 +} _PackedType t_DsarIcmpV4Statistics;
59122 +
59123 +
59124 +
59125 +/**************************************************************************//**
59126 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
59127 + 0x0 0-15 Control bits [0-15]
59128 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59129 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59130 + 0x6 0-15
59131 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59132 + 0xA 0-15
59133 + 0xC 0-15 Reserved Reserved. Must be cleared.
59134 + 0xE 015
59135 +
59136 +*//***************************************************************************/
59137 +typedef _Packed struct
59138 +{
59139 + uint16_t control; /** Control bits [0-15]. */
59140 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59141 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59142 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59143 + uint32_t reserved1; /**< Reserved. */
59144 +} _PackedType t_DsarIcmpV4Descriptor;
59145 +
59146 +/**************************************************************************//**
59147 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59148 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
59149 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
59150 + Flags[0] (VlanId[12]): Temporary address.
59151 + \95 0 - Assigned IP address.
59152 + \95 1- Temporary (tentative) IP address.
59153 + Refer to the FMan Controller spec for more details.
59154 +*//***************************************************************************/
59155 +typedef _Packed struct
59156 +{
59157 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
59158 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
59159 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
59160 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
59161 + uint16_t reserved;
59162 +} _PackedType t_DsarIcmpV6BindingEntry;
59163 +
59164 +/**************************************************************************//**
59165 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59166 + Refer to the FMan Controller spec for more details.
59167 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59168 + 0x04 NMVLAN_CNT Not My VLAN counter
59169 + 0x08 NMIP_CNT Not My IP counter
59170 + 0x0C AR_CNT Auto-Response counter
59171 + 0x10 CSERR_CNT Checksum Error counter
59172 + 0x14 MCAST_CNT Multicast counter
59173 + 0x18 Reserved Reserved
59174 + 0x1C Reserved Reserved
59175 +
59176 +*//***************************************************************************/
59177 +typedef _Packed struct
59178 +{
59179 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59180 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59181 + uint32_t nmIpCnt; /**< Not My IP counter */
59182 + uint32_t arCnt; /**< Auto-Response counter */
59183 + uint32_t reserved1; /**< Reserved */
59184 + uint32_t reserved2; /**< Reserved */
59185 + uint32_t reserved3; /**< Reserved */
59186 + uint32_t reserved4; /**< Reserved */
59187 +} _PackedType t_DsarIcmpV6Statistics;
59188 +
59189 +/**************************************************************************//**
59190 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
59191 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
59192 + 0x04 NMVLAN_CNT Not My VLAN counter
59193 + 0x08 NMIP_CNT Not My IP counter
59194 + 0x0C AR_CNT Auto-Response counter
59195 + 0x10 CSERR_CNT Checksum Error counter
59196 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
59197 + 0x18 NMMCAST_CNT Not My Multicast group counter
59198 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
59199 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
59200 + Source Link-layer Address option is omitted
59201 +*//***************************************************************************/
59202 +typedef _Packed struct
59203 +{
59204 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59205 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59206 + uint32_t nmIpCnt; /**< Not My IP counter */
59207 + uint32_t arCnt; /**< Auto-Response counter */
59208 + uint32_t reserved1; /**< Reserved */
59209 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
59210 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
59211 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
59212 +} _PackedType t_NdStatistics;
59213 +
59214 +/**************************************************************************//**
59215 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59216 + 0x0 0-15 Control bits [0-15]
59217 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59218 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59219 + 0x6 0-15
59220 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59221 + 0xA 0-15
59222 + 0xC 0-15 Reserved Reserved. Must be cleared.
59223 + 0xE 015
59224 +
59225 +*//***************************************************************************/
59226 +typedef _Packed struct
59227 +{
59228 + uint16_t control; /** Control bits [0-15]. */
59229 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59230 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59231 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59232 + uint32_t reserved1; /**< Reserved. */
59233 +} _PackedType t_DsarIcmpV6Descriptor;
59234 +
59235 +
59236 +/**************************************************************************//**
59237 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
59238 + The fields names are taken from RFC 4443.
59239 +*//***************************************************************************/
59240 +/* 0 1 2 3 */
59241 +/* 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 */
59242 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59243 +/* | Type | Code | Checksum | */
59244 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59245 +/* | Identifier | Sequence Number | */
59246 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59247 +/* | Data ... */
59248 +/* +-+-+-+-+- */
59249 +typedef _Packed struct
59250 +{
59251 + uint8_t type;
59252 + uint8_t code;
59253 + uint16_t checksum;
59254 + uint16_t identifier;
59255 + uint16_t sequenceNumber;
59256 +} _PackedType t_IcmpV6EchoHdr;
59257 +
59258 +/**************************************************************************//**
59259 + @Description Internet Control Message Protocol (ICMPv6)
59260 + Neighbor Solicitation/Advertisement header
59261 + The fields names are taken from RFC 4861.
59262 + The R/S/O fields are valid for Neighbor Advertisement only
59263 +*//***************************************************************************/
59264 +/* 0 1 2 3
59265 + * 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
59266 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59267 + * | Type | Code | Checksum |
59268 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59269 + * |R|S|O| Reserved |
59270 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59271 + * | |
59272 + * + +
59273 + * | |
59274 + * + Target Address +
59275 + * | |
59276 + * + +
59277 + * | |
59278 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59279 + * | Options ...
59280 + * +-+-+-+-+-+-+-+-+-+-+-+-
59281 + *
59282 + * Options Format:
59283 + * 0 1 2 3
59284 + * 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
59285 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59286 + * | Type | Length | Link-Layer Address ... |
59287 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59288 + * | Link-Layer Address |
59289 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59290 +*/
59291 +typedef _Packed struct
59292 +{
59293 + uint8_t type;
59294 + uint8_t code;
59295 + uint16_t checksum;
59296 + uint32_t router:1;
59297 + uint32_t solicited:1;
59298 + uint32_t override:1;
59299 + uint32_t reserved:29;
59300 + uint32_t targetAddr[4];
59301 + uint8_t optionType;
59302 + uint8_t optionLength;
59303 + uint8_t linkLayerAddr[6];
59304 +} _PackedType t_IcmpV6NdHdr;
59305 +
59306 +/**************************************************************************//**
59307 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59308 + 0x0 0-15 Control bits [0-15]
59309 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59310 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59311 + 0x6 0-15
59312 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59313 + 0xA 0-15
59314 + 0xC 0-15 Reserved Reserved. Must be cleared.
59315 + 0xE 015
59316 +
59317 +*//***************************************************************************/
59318 +typedef _Packed struct
59319 +{
59320 + uint16_t control; /** Control bits [0-15]. */
59321 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59322 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59323 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59324 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
59325 +} _PackedType t_DsarNdDescriptor;
59326 +
59327 +/**************************************************************************//**
59328 +@Description Deep Sleep Auto Response SNMP OIDs table entry
59329 +
59330 +*//***************************************************************************/
59331 +typedef struct {
59332 + uint16_t oidSize; /**< Size in octets of the OID. */
59333 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
59334 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
59335 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
59336 + uint32_t reserved;
59337 +} t_OidsTblEntry;
59338 +
59339 +/**************************************************************************//**
59340 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
59341 + Refer to the FMan Controller spec for more details.
59342 +*//***************************************************************************/
59343 +typedef struct
59344 +{
59345 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59346 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59347 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59348 + uint16_t reserved;
59349 +} t_DsarSnmpIpv4AddrTblEntry;
59350 +
59351 +/**************************************************************************//**
59352 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
59353 + Refer to the FMan Controller spec for more details.
59354 +*//***************************************************************************/
59355 +#pragma pack(push,1)
59356 +typedef struct
59357 +{
59358 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
59359 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59360 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59361 + uint16_t reserved;
59362 +} t_DsarSnmpIpv6AddrTblEntry;
59363 +#pragma pack(pop)
59364 +
59365 +/**************************************************************************//**
59366 +@Description Deep Sleep Auto Response SNMP statistics table
59367 +
59368 +*//***************************************************************************/
59369 +typedef struct {
59370 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
59371 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
59372 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
59373 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
59374 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
59375 +} t_DsarSnmpStatistics;
59376 +
59377 +/**************************************************************************//**
59378 + @Description Deep Sleep Auto Response SNMP Descriptor
59379 +
59380 +*//***************************************************************************/
59381 +typedef struct
59382 +{
59383 + uint16_t control; /**< Control bits [0-15]. */
59384 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
59385 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
59386 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
59387 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
59388 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
59389 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
59390 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
59391 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
59392 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
59393 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
59394 +} t_DsarSnmpDescriptor;
59395 +
59396 +/**************************************************************************//**
59397 +@Description Deep Sleep Auto Response (Common) Statistics
59398 +
59399 +*//***************************************************************************/
59400 +typedef _Packed struct {
59401 + uint32_t dsarDiscarded;
59402 + uint32_t dsarErrDiscarded;
59403 + uint32_t dsarFragDiscarded;
59404 + uint32_t dsarTunnelDiscarded;
59405 + uint32_t dsarArpDiscarded;
59406 + uint32_t dsarIpDiscarded;
59407 + uint32_t dsarTcpDiscarded;
59408 + uint32_t dsarUdpDiscarded;
59409 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
59410 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
59411 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
59412 +} _PackedType t_ArStatistics;
59413 +
59414 +
59415 +/**************************************************************************//**
59416 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
59417 +
59418 +*//***************************************************************************/
59419 +typedef _Packed struct {
59420 + uint32_t Ports;
59421 + uint32_t PortsMask;
59422 +} _PackedType t_PortTblEntry;
59423 +
59424 +
59425 +
59426 +/**************************************************************************//**
59427 +@Description Deep Sleep Auto Response Common Parameters Descriptor
59428 +
59429 +*//***************************************************************************/
59430 +typedef _Packed struct {
59431 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
59432 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
59433 + uint16_t res1; /* 0x00 16-31 Reserved */
59434 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
59435 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
59436 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
59437 + uint8_t res2; /* 0x10 0-7 Reserved */
59438 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
59439 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
59440 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
59441 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
59442 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
59443 + uint8_t res3; /* 0x14 24-31 Reserved */
59444 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
59445 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
59446 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
59447 + uint32_t res4; /* 0x24 Reserved */
59448 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
59449 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
59450 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
59451 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
59452 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
59453 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
59454 +} _PackedType t_ArCommonDesc;
59455 +
59456 +#if defined(__MWERKS__) && !defined(__GNUC__)
59457 +#pragma pack(pop)
59458 +#endif /* defined(__MWERKS__) && ... */
59459 +
59460 +/* t_ArCommonDesc.filterControl bits */
59461 +#define IP_PROT_TBL_PASS_MASK 0x08
59462 +#define UDP_PORT_TBL_PASS_MASK 0x04
59463 +#define TCP_PORT_TBL_PASS_MASK 0x02
59464 +
59465 +/* Offset of TCF flags within TCP packet */
59466 +#define TCP_FLAGS_OFFSET 12
59467 +
59468 +
59469 +#endif /* __FM_PORT_DSAR_H_ */
59470 --- /dev/null
59471 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59472 @@ -0,0 +1,753 @@
59473 +/*
59474 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59475 + *
59476 + * Redistribution and use in source and binary forms, with or without
59477 + * modification, are permitted provided that the following conditions are met:
59478 + * * Redistributions of source code must retain the above copyright
59479 + * notice, this list of conditions and the following disclaimer.
59480 + * * Redistributions in binary form must reproduce the above copyright
59481 + * notice, this list of conditions and the following disclaimer in the
59482 + * documentation and/or other materials provided with the distribution.
59483 + * * Neither the name of Freescale Semiconductor nor the
59484 + * names of its contributors may be used to endorse or promote products
59485 + * derived from this software without specific prior written permission.
59486 + *
59487 + *
59488 + * ALTERNATIVELY, this software may be distributed under the terms of the
59489 + * GNU General Public License ("GPL") as published by the Free Software
59490 + * Foundation, either version 2 of that License or (at your option) any
59491 + * later version.
59492 + *
59493 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59494 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59495 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59496 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59497 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59498 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59499 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59500 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59501 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59502 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59503 + */
59504 +
59505 +
59506 +/******************************************************************************
59507 + @File fm_port_im.c
59508 +
59509 + @Description FM Port Independent-Mode ...
59510 +*//***************************************************************************/
59511 +#include "std_ext.h"
59512 +#include "string_ext.h"
59513 +#include "error_ext.h"
59514 +#include "memcpy_ext.h"
59515 +#include "fm_muram_ext.h"
59516 +
59517 +#include "fm_port.h"
59518 +
59519 +
59520 +#define TX_CONF_STATUS_UNSENT 0x1
59521 +
59522 +
59523 +typedef enum e_TxConfType
59524 +{
59525 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
59526 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
59527 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
59528 +} e_TxConfType;
59529 +
59530 +
59531 +static void ImException(t_Handle h_FmPort, uint32_t event)
59532 +{
59533 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59534 +
59535 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
59536 + !FmIsMaster(p_FmPort->h_Fm));
59537 +
59538 + if (event & IM_EV_RX)
59539 + FmPortImRx(p_FmPort);
59540 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
59541 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
59542 +}
59543 +
59544 +
59545 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
59546 +{
59547 + t_Error retVal = E_BUSY;
59548 + uint32_t bdStatus;
59549 + uint16_t savedStartBdId, confBdId;
59550 +
59551 + ASSERT_COND(p_FmPort);
59552 +
59553 + /*
59554 + if (confType==e_TX_CONF_TYPE_CHECK)
59555 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
59556 + */
59557 +
59558 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
59559 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59560 +
59561 + /* If R bit is set, we don't enter, or we break.
59562 + we run till we get to R, or complete the loop */
59563 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
59564 + {
59565 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
59566 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
59567 +
59568 + /* case 1: R bit is 0 and Length is set -> confirm! */
59569 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
59570 + {
59571 + if (p_FmPort->im.f_TxConf)
59572 + {
59573 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
59574 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59575 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59576 + TX_CONF_STATUS_UNSENT,
59577 + p_FmPort->im.p_BdShadow[confBdId]);
59578 + else
59579 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59580 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59581 + 0,
59582 + p_FmPort->im.p_BdShadow[confBdId]);
59583 + }
59584 + }
59585 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
59586 +
59587 + confBdId = GetNextBdId(p_FmPort, confBdId);
59588 + if (confBdId == savedStartBdId)
59589 + retVal = E_OK;
59590 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59591 + }
59592 +
59593 + return retVal;
59594 +}
59595 +
59596 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
59597 +{
59598 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59599 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
59600 + return E_OK;
59601 +}
59602 +
59603 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
59604 +{
59605 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59606 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
59607 + return E_OK;
59608 +}
59609 +
59610 +t_Error FmPortImRx(t_FmPort *p_FmPort)
59611 +{
59612 + t_Handle h_CurrUserPriv, h_NewUserPriv;
59613 + uint32_t bdStatus;
59614 + volatile uint8_t buffPos;
59615 + uint16_t length;
59616 + uint16_t errors;
59617 + uint8_t *p_CurData, *p_Data;
59618 + uint32_t flags;
59619 +
59620 + ASSERT_COND(p_FmPort);
59621 +
59622 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
59623 + if (p_FmPort->lock)
59624 + {
59625 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59626 + return E_OK;
59627 + }
59628 + p_FmPort->lock = TRUE;
59629 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59630 +
59631 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59632 +
59633 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
59634 + {
59635 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
59636 + {
59637 + p_FmPort->lock = FALSE;
59638 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59639 + }
59640 +
59641 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
59642 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
59643 +
59644 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
59645 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
59646 + length = (uint16_t)((bdStatus & BD_L) ?
59647 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
59648 + (bdStatus & BD_LENGTH_MASK));
59649 + p_FmPort->im.rxFrameAccumLength += length;
59650 +
59651 + /* determine whether buffer is first, last, first and last (single */
59652 + /* buffer frame) or middle (not first and not last) */
59653 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
59654 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
59655 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
59656 +
59657 + if (bdStatus & BD_L)
59658 + {
59659 + p_FmPort->im.rxFrameAccumLength = 0;
59660 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
59661 + }
59662 +
59663 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
59664 +
59665 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
59666 +
59667 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
59668 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
59669 +
59670 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
59671 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
59672 + /* Pass the buffer if one of the conditions is true:
59673 + - There are no errors
59674 + - This is a part of a larger frame ( the application has already received some buffers ) */
59675 + if ((buffPos != SINGLE_BUF) || !errors)
59676 + {
59677 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
59678 + p_CurData,
59679 + length,
59680 + errors,
59681 + buffPos,
59682 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
59683 + break;
59684 + }
59685 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
59686 + p_CurData,
59687 + h_CurrUserPriv))
59688 + {
59689 + p_FmPort->lock = FALSE;
59690 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
59691 + }
59692 +
59693 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59694 + }
59695 + p_FmPort->lock = FALSE;
59696 + return E_OK;
59697 +}
59698 +
59699 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
59700 +{
59701 + ASSERT_COND(p_FmPort);
59702 +
59703 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
59704 +
59705 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
59706 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
59707 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
59708 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
59709 +
59710 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
59711 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
59712 +
59713 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59714 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59715 + {
59716 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
59717 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
59718 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
59719 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
59720 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
59721 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
59722 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
59723 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
59724 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
59725 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
59726 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
59727 +
59728 + p_FmPort->im.mrblr = 0x8000;
59729 + while (p_FmPort->im.mrblr)
59730 + {
59731 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
59732 + break;
59733 + p_FmPort->im.mrblr >>= 1;
59734 + }
59735 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
59736 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
59737 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
59738 + p_FmPort->exceptions = DEFAULT_PORT_exception;
59739 + if (FmIsMaster(p_FmPort->h_Fm))
59740 + p_FmPort->polling = FALSE;
59741 + else
59742 + p_FmPort->polling = TRUE;
59743 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
59744 + }
59745 + else
59746 + {
59747 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
59748 +
59749 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
59750 + }
59751 +}
59752 +
59753 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
59754 +{
59755 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
59756 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
59757 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
59758 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
59759 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
59760 +
59761 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59762 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59763 + {
59764 + if (!POWER_OF_2(p_FmPort->im.mrblr))
59765 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
59766 + if (p_FmPort->im.mrblr < 256)
59767 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
59768 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
59769 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
59770 + }
59771 +
59772 + return E_OK;
59773 +}
59774 +
59775 +t_Error FmPortImInit(t_FmPort *p_FmPort)
59776 +{
59777 + t_FmImBd *p_Bd=NULL;
59778 + t_Handle h_BufContext;
59779 + uint64_t tmpPhysBase;
59780 + uint16_t log2Num;
59781 + uint8_t *p_Data/*, *p_Tmp*/;
59782 + int i;
59783 + t_Error err;
59784 + uint16_t tmpReg16;
59785 + uint32_t tmpReg32;
59786 +
59787 + ASSERT_COND(p_FmPort);
59788 +
59789 + p_FmPort->im.p_FmPortImPram =
59790 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
59791 + if (!p_FmPort->im.p_FmPortImPram)
59792 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
59793 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
59794 +
59795 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59796 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59797 + {
59798 + p_FmPort->im.p_BdRing =
59799 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
59800 + p_FmPort->im.fwExtStructsMemId,
59801 + 4);
59802 + if (!p_FmPort->im.p_BdRing)
59803 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
59804 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59805 +
59806 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59807 + if (!p_FmPort->im.p_BdShadow)
59808 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
59809 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59810 +
59811 + /* Initialize the Rx-BD ring */
59812 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
59813 + {
59814 + p_Bd = BD_GET(i);
59815 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
59816 +
59817 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
59818 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59819 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
59820 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
59821 + }
59822 +
59823 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
59824 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
59825 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
59826 + else
59827 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
59828 +
59829 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
59830 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59831 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
59832 +
59833 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
59834 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
59835 +
59836 + /* Initialize Rx QD */
59837 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
59838 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
59839 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59840 +
59841 + /* Update the IM PRAM address in the BMI */
59842 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
59843 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59844 + p_FmPort->fmMuramPhysBaseAddr));
59845 + if (!p_FmPort->polling || p_FmPort->exceptions)
59846 + {
59847 + /* Allocate, configure and register interrupts */
59848 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
59849 + if (err)
59850 + RETURN_ERROR(MAJOR, err, NO_MSG);
59851 +
59852 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
59853 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
59854 + tmpReg32 = 0;
59855 +
59856 + if (p_FmPort->exceptions & IM_EV_BSY)
59857 + {
59858 + tmpReg16 |= IM_RXQD_BSYINTM;
59859 + tmpReg32 |= IM_EV_BSY;
59860 + }
59861 + if (!p_FmPort->polling)
59862 + {
59863 + tmpReg16 |= IM_RXQD_RXFINTM;
59864 + tmpReg32 |= IM_EV_RX;
59865 + }
59866 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
59867 +
59868 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
59869 +
59870 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
59871 + }
59872 + else
59873 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
59874 + }
59875 + else
59876 + {
59877 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
59878 + if (!p_FmPort->im.p_BdRing)
59879 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
59880 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59881 +
59882 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59883 + if (!p_FmPort->im.p_BdShadow)
59884 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
59885 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
59886 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
59887 +
59888 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
59889 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
59890 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
59891 + else
59892 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
59893 +
59894 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
59895 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59896 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
59897 +
59898 + /* Initialize Tx QD */
59899 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
59900 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
59901 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
59902 +
59903 + /* Update the IM PRAM address in the BMI */
59904 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
59905 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
59906 + p_FmPort->fmMuramPhysBaseAddr));
59907 + }
59908 +
59909 +
59910 + return E_OK;
59911 +}
59912 +
59913 +void FmPortImFree(t_FmPort *p_FmPort)
59914 +{
59915 + uint32_t bdStatus;
59916 + uint8_t *p_CurData;
59917 +
59918 + ASSERT_COND(p_FmPort);
59919 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
59920 +
59921 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
59922 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
59923 + {
59924 + if (!p_FmPort->polling || p_FmPort->exceptions)
59925 + {
59926 + /* Deallocate and unregister interrupts */
59927 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
59928 +
59929 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
59930 +
59931 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
59932 +
59933 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
59934 + }
59935 + /* Try first clean what has received */
59936 + FmPortImRx(p_FmPort);
59937 +
59938 + /* Now, get rid of the the empty buffer! */
59939 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59940 +
59941 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
59942 + {
59943 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
59944 +
59945 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
59946 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
59947 +
59948 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
59949 + p_CurData,
59950 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
59951 +
59952 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
59953 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59954 + }
59955 + }
59956 + else
59957 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
59958 +
59959 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
59960 +
59961 + if (p_FmPort->im.p_BdShadow)
59962 + XX_Free(p_FmPort->im.p_BdShadow);
59963 +
59964 + if (p_FmPort->im.p_BdRing)
59965 + XX_FreeSmart(p_FmPort->im.p_BdRing);
59966 +}
59967 +
59968 +
59969 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
59970 +{
59971 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59972 +
59973 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
59974 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
59975 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
59976 +
59977 + p_FmPort->im.mrblr = newVal;
59978 +
59979 + return E_OK;
59980 +}
59981 +
59982 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
59983 +{
59984 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59985 +
59986 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
59987 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
59988 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
59989 +
59990 + p_FmPort->im.bdRingSize = newVal;
59991 +
59992 + return E_OK;
59993 +}
59994 +
59995 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
59996 +{
59997 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59998 +
59999 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60000 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60001 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60002 +
60003 + p_FmPort->im.bdRingSize = newVal;
60004 +
60005 + return E_OK;
60006 +}
60007 +
60008 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
60009 + uint8_t memId,
60010 + uint32_t memAttributes)
60011 +{
60012 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60013 +
60014 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60015 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60016 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60017 +
60018 + p_FmPort->im.fwExtStructsMemId = memId;
60019 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
60020 +
60021 + return E_OK;
60022 +}
60023 +
60024 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
60025 +{
60026 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60027 +
60028 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60029 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60030 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60031 +
60032 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
60033 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
60034 +
60035 + if (!FmIsMaster(p_FmPort->h_Fm))
60036 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
60037 + "in guest-partitions, IM is always in polling!"));
60038 +
60039 + p_FmPort->polling = TRUE;
60040 +
60041 + return E_OK;
60042 +}
60043 +
60044 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
60045 +{
60046 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60047 + t_Error err;
60048 + uint16_t tmpReg16;
60049 + uint32_t tmpReg32;
60050 +
60051 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60052 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60053 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60054 +
60055 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
60056 + {
60057 + if (enable)
60058 + {
60059 + p_FmPort->exceptions |= IM_EV_BSY;
60060 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
60061 + {
60062 + /* Allocate, configure and register interrupts */
60063 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60064 + if (err)
60065 + RETURN_ERROR(MAJOR, err, NO_MSG);
60066 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60067 +
60068 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
60069 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
60070 + tmpReg32 = IM_EV_BSY;
60071 + }
60072 + else
60073 + {
60074 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
60075 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
60076 + }
60077 +
60078 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60079 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60080 + }
60081 + else
60082 + {
60083 + p_FmPort->exceptions &= ~IM_EV_BSY;
60084 + if (!p_FmPort->exceptions && p_FmPort->polling)
60085 + {
60086 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60087 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60088 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60089 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60090 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60091 + }
60092 + else
60093 + {
60094 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
60095 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60096 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
60097 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60098 + }
60099 + }
60100 + }
60101 + else
60102 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
60103 +
60104 + return E_OK;
60105 +}
60106 +
60107 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
60108 + uint8_t *p_Data,
60109 + uint16_t length,
60110 + bool lastBuffer,
60111 + t_Handle h_BufContext)
60112 +{
60113 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60114 + uint16_t nextBdId;
60115 + uint32_t bdStatus, nextBdStatus;
60116 + bool firstBuffer;
60117 +
60118 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60119 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60120 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60121 +
60122 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60123 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60124 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
60125 +
60126 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
60127 + {
60128 + /* Confirm the current BD - BD is available */
60129 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
60130 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
60131 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
60132 + 0,
60133 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60134 +
60135 + bdStatus = length;
60136 +
60137 + /* if this is the first BD of a frame */
60138 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60139 + {
60140 + firstBuffer = TRUE;
60141 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
60142 +
60143 + if (!lastBuffer)
60144 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60145 + }
60146 + else
60147 + firstBuffer = FALSE;
60148 +
60149 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60150 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
60151 +
60152 + /* deal with last */
60153 + if (lastBuffer)
60154 + {
60155 + /* if single buffer frame */
60156 + if (firstBuffer)
60157 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
60158 + else
60159 + {
60160 + /* Set the last BD of the frame */
60161 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
60162 + /* Set the first BD of the frame */
60163 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
60164 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60165 + }
60166 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
60167 + }
60168 + else if (!firstBuffer) /* mid frame buffer */
60169 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
60170 +
60171 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60172 + }
60173 + else
60174 + {
60175 + /* Discard current frame. Return error. */
60176 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
60177 + {
60178 + /* Error: No free BD */
60179 + /* Response: Discard current frame. Return error. */
60180 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
60181 +
60182 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
60183 +
60184 + /* Since firstInFrame is not NULL, one buffer at least has already been
60185 + inserted into the BD ring. Using do-while covers the situation of a
60186 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
60187 + prior to testing whether or not it's equal to TxBd). */
60188 + do
60189 + {
60190 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
60191 + /* Advance BD pointer */
60192 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
60193 + } while (cleanBdId != p_FmPort->im.currBdId);
60194 +
60195 + p_FmPort->im.currBdId = cleanBdId;
60196 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60197 + }
60198 +
60199 + return ERROR_CODE(E_FULL);
60200 + }
60201 +
60202 + return E_OK;
60203 +}
60204 +
60205 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
60206 +{
60207 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60208 +
60209 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
60210 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
60211 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60212 +
60213 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
60214 +}
60215 +
60216 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
60217 +{
60218 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60219 +
60220 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60221 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60222 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60223 +
60224 + return FmPortImRx(p_FmPort);
60225 +}
60226 --- /dev/null
60227 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60228 @@ -0,0 +1,1568 @@
60229 +/*
60230 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60231 + *
60232 + * Redistribution and use in source and binary forms, with or without
60233 + * modification, are permitted provided that the following conditions are met:
60234 + * * Redistributions of source code must retain the above copyright
60235 + * notice, this list of conditions and the following disclaimer.
60236 + * * Redistributions in binary form must reproduce the above copyright
60237 + * notice, this list of conditions and the following disclaimer in the
60238 + * documentation and/or other materials provided with the distribution.
60239 + * * Neither the name of Freescale Semiconductor nor the
60240 + * names of its contributors may be used to endorse or promote products
60241 + * derived from this software without specific prior written permission.
60242 + *
60243 + *
60244 + * ALTERNATIVELY, this software may be distributed under the terms of the
60245 + * GNU General Public License ("GPL") as published by the Free Software
60246 + * Foundation, either version 2 of that License or (at your option) any
60247 + * later version.
60248 + *
60249 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60250 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60251 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60252 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60253 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60254 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60255 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60256 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60257 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60258 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60259 + */
60260 +
60261 +
60262 +#include "common/general.h"
60263 +
60264 +#include "fman_common.h"
60265 +#include "fsl_fman_port.h"
60266 +
60267 +
60268 +/* problem Eyal: the following should not be here*/
60269 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
60270 +
60271 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
60272 +{
60273 + if (cfg->errata_A006675)
60274 + return NIA_ENG_FM_CTL |
60275 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
60276 + else
60277 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
60278 +}
60279 +
60280 +static int init_bmi_rx(struct fman_port *port,
60281 + struct fman_port_cfg *cfg,
60282 + struct fman_port_params *params)
60283 +{
60284 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60285 + uint32_t tmp;
60286 +
60287 + /* Rx Configuration register */
60288 + tmp = 0;
60289 + if (port->im_en)
60290 + tmp |= BMI_PORT_CFG_IM;
60291 + else if (cfg->discard_override)
60292 + tmp |= BMI_PORT_CFG_FDOVR;
60293 + iowrite32be(tmp, &regs->fmbm_rcfg);
60294 +
60295 + /* DMA attributes */
60296 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60297 + if (cfg->dma_ic_stash_on)
60298 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60299 + if (cfg->dma_header_stash_on)
60300 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60301 + if (cfg->dma_sg_stash_on)
60302 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60303 + if (cfg->dma_write_optimize)
60304 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60305 + iowrite32be(tmp, &regs->fmbm_rda);
60306 +
60307 + /* Rx FIFO parameters */
60308 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
60309 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
60310 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
60311 + iowrite32be(tmp, &regs->fmbm_rfp);
60312 +
60313 + if (cfg->excessive_threshold_register)
60314 + /* always allow access to the extra resources */
60315 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
60316 +
60317 + /* Frame end data */
60318 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60319 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
60320 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
60321 + BMI_RX_FRAME_END_CUT_SHIFT;
60322 + if (cfg->errata_A006320)
60323 + tmp &= 0xffe0ffff;
60324 + iowrite32be(tmp, &regs->fmbm_rfed);
60325 +
60326 + /* Internal context parameters */
60327 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60328 + BMI_IC_TO_EXT_SHIFT;
60329 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60330 + BMI_IC_FROM_INT_SHIFT;
60331 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60332 + iowrite32be(tmp, &regs->fmbm_ricp);
60333 +
60334 + /* Internal buffer offset */
60335 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60336 + << BMI_INT_BUF_MARG_SHIFT;
60337 + iowrite32be(tmp, &regs->fmbm_rim);
60338 +
60339 + /* External buffer margins */
60340 + if (!port->im_en)
60341 + {
60342 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
60343 + BMI_EXT_BUF_MARG_START_SHIFT;
60344 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
60345 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
60346 + tmp |= BMI_SG_DISABLE;
60347 + iowrite32be(tmp, &regs->fmbm_rebm);
60348 + }
60349 +
60350 + /* Frame attributes */
60351 + tmp = BMI_CMD_RX_MR_DEF;
60352 + if (!port->im_en)
60353 + {
60354 + tmp |= BMI_CMD_ATTR_ORDER;
60355 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60356 + if (cfg->sync_req)
60357 + tmp |= BMI_CMD_ATTR_SYNC;
60358 + }
60359 + iowrite32be(tmp, &regs->fmbm_rfca);
60360 +
60361 + /* NIA */
60362 + if (port->im_en)
60363 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
60364 + else
60365 + {
60366 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
60367 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
60368 + }
60369 + iowrite32be(tmp, &regs->fmbm_rfne);
60370 +
60371 + /* Enqueue NIA */
60372 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
60373 +
60374 + /* Default/error queues */
60375 + if (!port->im_en)
60376 + {
60377 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
60378 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
60379 + }
60380 +
60381 + /* Discard/error masks */
60382 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
60383 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
60384 +
60385 + /* Statistics counters */
60386 + tmp = 0;
60387 + if (cfg->stats_counters_enable)
60388 + tmp = BMI_COUNTERS_EN;
60389 + iowrite32be(tmp, &regs->fmbm_rstc);
60390 +
60391 + /* Performance counters */
60392 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60393 + tmp = 0;
60394 + if (cfg->perf_counters_enable)
60395 + tmp = BMI_COUNTERS_EN;
60396 + iowrite32be(tmp, &regs->fmbm_rpc);
60397 +
60398 + return 0;
60399 +}
60400 +
60401 +static int init_bmi_tx(struct fman_port *port,
60402 + struct fman_port_cfg *cfg,
60403 + struct fman_port_params *params)
60404 +{
60405 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60406 + uint32_t tmp;
60407 +
60408 + /* Tx Configuration register */
60409 + tmp = 0;
60410 + if (port->im_en)
60411 + tmp |= BMI_PORT_CFG_IM;
60412 + iowrite32be(tmp, &regs->fmbm_tcfg);
60413 +
60414 + /* DMA attributes */
60415 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60416 + if (cfg->dma_ic_stash_on)
60417 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60418 + if (cfg->dma_header_stash_on)
60419 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60420 + if (cfg->dma_sg_stash_on)
60421 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60422 + iowrite32be(tmp, &regs->fmbm_tda);
60423 +
60424 + /* Tx FIFO parameters */
60425 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
60426 + BMI_TX_FIFO_MIN_FILL_SHIFT;
60427 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60428 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60429 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
60430 + FMAN_PORT_BMI_FIFO_UNITS - 1);
60431 + iowrite32be(tmp, &regs->fmbm_tfp);
60432 +
60433 + /* Frame end data */
60434 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60435 + BMI_FRAME_END_CS_IGNORE_SHIFT;
60436 + iowrite32be(tmp, &regs->fmbm_tfed);
60437 +
60438 + /* Internal context parameters */
60439 + if (!port->im_en)
60440 + {
60441 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60442 + BMI_IC_TO_EXT_SHIFT;
60443 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60444 + BMI_IC_FROM_INT_SHIFT;
60445 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60446 + iowrite32be(tmp, &regs->fmbm_ticp);
60447 + }
60448 + /* Frame attributes */
60449 + tmp = BMI_CMD_TX_MR_DEF;
60450 + if (port->im_en)
60451 + tmp |= BMI_CMD_MR_DEAS;
60452 + else
60453 + {
60454 + tmp |= BMI_CMD_ATTR_ORDER;
60455 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60456 + }
60457 + iowrite32be(tmp, &regs->fmbm_tfca);
60458 +
60459 + /* Dequeue NIA + enqueue NIA */
60460 + if (port->im_en)
60461 + {
60462 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
60463 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
60464 + }
60465 + else
60466 + {
60467 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
60468 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
60469 + if (cfg->fmbm_tfne_has_features)
60470 + iowrite32be(!params->dflt_fqid ?
60471 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
60472 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
60473 + if (!params->dflt_fqid && params->dont_release_buf)
60474 + {
60475 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
60476 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
60477 + if (cfg->fmbm_tfne_has_features)
60478 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
60479 + }
60480 + }
60481 +
60482 + /* Confirmation/error queues */
60483 + if (!port->im_en)
60484 + {
60485 + if (params->dflt_fqid || !params->dont_release_buf)
60486 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
60487 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
60488 + }
60489 + /* Statistics counters */
60490 + tmp = 0;
60491 + if (cfg->stats_counters_enable)
60492 + tmp = BMI_COUNTERS_EN;
60493 + iowrite32be(tmp, &regs->fmbm_tstc);
60494 +
60495 + /* Performance counters */
60496 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60497 + tmp = 0;
60498 + if (cfg->perf_counters_enable)
60499 + tmp = BMI_COUNTERS_EN;
60500 + iowrite32be(tmp, &regs->fmbm_tpc);
60501 +
60502 + return 0;
60503 +}
60504 +
60505 +static int init_bmi_oh(struct fman_port *port,
60506 + struct fman_port_cfg *cfg,
60507 + struct fman_port_params *params)
60508 +{
60509 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60510 + uint32_t tmp;
60511 +
60512 + /* OP Configuration register */
60513 + tmp = 0;
60514 + if (cfg->discard_override)
60515 + tmp |= BMI_PORT_CFG_FDOVR;
60516 + iowrite32be(tmp, &regs->fmbm_ocfg);
60517 +
60518 + /* DMA attributes */
60519 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60520 + if (cfg->dma_ic_stash_on)
60521 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60522 + if (cfg->dma_header_stash_on)
60523 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60524 + if (cfg->dma_sg_stash_on)
60525 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60526 + if (cfg->dma_write_optimize)
60527 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60528 + iowrite32be(tmp, &regs->fmbm_oda);
60529 +
60530 + /* Tx FIFO parameters */
60531 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60532 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60533 + iowrite32be(tmp, &regs->fmbm_ofp);
60534 +
60535 + /* Internal context parameters */
60536 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60537 + BMI_IC_TO_EXT_SHIFT;
60538 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60539 + BMI_IC_FROM_INT_SHIFT;
60540 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60541 + iowrite32be(tmp, &regs->fmbm_oicp);
60542 +
60543 + /* Frame attributes */
60544 + tmp = BMI_CMD_OP_MR_DEF;
60545 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60546 + if (cfg->sync_req)
60547 + tmp |= BMI_CMD_ATTR_SYNC;
60548 + if (port->type == E_FMAN_PORT_TYPE_OP)
60549 + tmp |= BMI_CMD_ATTR_ORDER;
60550 + iowrite32be(tmp, &regs->fmbm_ofca);
60551 +
60552 + /* Internal buffer offset */
60553 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60554 + << BMI_INT_BUF_MARG_SHIFT;
60555 + iowrite32be(tmp, &regs->fmbm_oim);
60556 +
60557 + /* Dequeue NIA */
60558 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
60559 +
60560 + /* NIA and Enqueue NIA */
60561 + if (port->type == E_FMAN_PORT_TYPE_HC) {
60562 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
60563 + &regs->fmbm_ofne);
60564 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
60565 + } else {
60566 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
60567 + &regs->fmbm_ofne);
60568 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
60569 + &regs->fmbm_ofene);
60570 + }
60571 +
60572 + /* Default/error queues */
60573 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
60574 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
60575 +
60576 + /* Discard/error masks */
60577 + if (port->type == E_FMAN_PORT_TYPE_OP) {
60578 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
60579 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
60580 + }
60581 +
60582 + /* Statistics counters */
60583 + tmp = 0;
60584 + if (cfg->stats_counters_enable)
60585 + tmp = BMI_COUNTERS_EN;
60586 + iowrite32be(tmp, &regs->fmbm_ostc);
60587 +
60588 + /* Performance counters */
60589 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60590 + tmp = 0;
60591 + if (cfg->perf_counters_enable)
60592 + tmp = BMI_COUNTERS_EN;
60593 + iowrite32be(tmp, &regs->fmbm_opc);
60594 +
60595 + return 0;
60596 +}
60597 +
60598 +static int init_qmi(struct fman_port *port,
60599 + struct fman_port_cfg *cfg,
60600 + struct fman_port_params *params)
60601 +{
60602 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60603 + uint32_t tmp;
60604 +
60605 + tmp = 0;
60606 + if (cfg->queue_counters_enable)
60607 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
60608 + iowrite32be(tmp, &regs->fmqm_pnc);
60609 +
60610 + /* Rx port configuration */
60611 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60612 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
60613 + /* Enqueue NIA */
60614 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60615 + return 0;
60616 + }
60617 +
60618 + /* Continue with Tx and O/H port configuration */
60619 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
60620 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
60621 + /* Enqueue NIA */
60622 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
60623 + &regs->fmqm_pnen);
60624 + /* Dequeue NIA */
60625 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
60626 + } else {
60627 + /* Enqueue NIA */
60628 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60629 + /* Dequeue NIA */
60630 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
60631 + }
60632 +
60633 + /* Dequeue Configuration register */
60634 + tmp = 0;
60635 + if (cfg->deq_high_pri)
60636 + tmp |= QMI_DEQ_CFG_PRI;
60637 +
60638 + switch (cfg->deq_type) {
60639 + case E_FMAN_PORT_DEQ_BY_PRI:
60640 + tmp |= QMI_DEQ_CFG_TYPE1;
60641 + break;
60642 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
60643 + tmp |= QMI_DEQ_CFG_TYPE2;
60644 + break;
60645 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
60646 + tmp |= QMI_DEQ_CFG_TYPE3;
60647 + break;
60648 + default:
60649 + return -EINVAL;
60650 + }
60651 +
60652 + if (cfg->qmi_deq_options_support) {
60653 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
60654 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
60655 + return -EINVAL;
60656 +
60657 + switch (cfg->deq_prefetch_opt) {
60658 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
60659 + break;
60660 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
60661 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
60662 + break;
60663 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
60664 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
60665 + break;
60666 + default:
60667 + return -EINVAL;
60668 + }
60669 + }
60670 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
60671 + QMI_DEQ_CFG_SP_SHIFT;
60672 + tmp |= cfg->deq_byte_cnt;
60673 + iowrite32be(tmp, &regs->fmqm_pndc);
60674 +
60675 + return 0;
60676 +}
60677 +
60678 +static void get_rx_stats_reg(struct fman_port *port,
60679 + enum fman_port_stats_counters counter,
60680 + uint32_t **stats_reg)
60681 +{
60682 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60683 +
60684 + switch (counter) {
60685 + case E_FMAN_PORT_STATS_CNT_FRAME:
60686 + *stats_reg = &regs->fmbm_rfrc;
60687 + break;
60688 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60689 + *stats_reg = &regs->fmbm_rfdc;
60690 + break;
60691 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60692 + *stats_reg = &regs->fmbm_rbdc;
60693 + break;
60694 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
60695 + *stats_reg = &regs->fmbm_rfbc;
60696 + break;
60697 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
60698 + *stats_reg = &regs->fmbm_rlfc;
60699 + break;
60700 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
60701 + *stats_reg = &regs->fmbm_rodc;
60702 + break;
60703 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60704 + *stats_reg = &regs->fmbm_rffc;
60705 + break;
60706 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60707 + *stats_reg = &regs->fmbm_rfldec;
60708 + break;
60709 + default:
60710 + *stats_reg = NULL;
60711 + }
60712 +}
60713 +
60714 +static void get_tx_stats_reg(struct fman_port *port,
60715 + enum fman_port_stats_counters counter,
60716 + uint32_t **stats_reg)
60717 +{
60718 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60719 +
60720 + switch (counter) {
60721 + case E_FMAN_PORT_STATS_CNT_FRAME:
60722 + *stats_reg = &regs->fmbm_tfrc;
60723 + break;
60724 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60725 + *stats_reg = &regs->fmbm_tfdc;
60726 + break;
60727 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60728 + *stats_reg = &regs->fmbm_tbdc;
60729 + break;
60730 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60731 + *stats_reg = &regs->fmbm_tfledc;
60732 + break;
60733 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60734 + *stats_reg = &regs->fmbm_tfufdc;
60735 + break;
60736 + default:
60737 + *stats_reg = NULL;
60738 + }
60739 +}
60740 +
60741 +static void get_oh_stats_reg(struct fman_port *port,
60742 + enum fman_port_stats_counters counter,
60743 + uint32_t **stats_reg)
60744 +{
60745 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60746 +
60747 + switch (counter) {
60748 + case E_FMAN_PORT_STATS_CNT_FRAME:
60749 + *stats_reg = &regs->fmbm_ofrc;
60750 + break;
60751 + case E_FMAN_PORT_STATS_CNT_DISCARD:
60752 + *stats_reg = &regs->fmbm_ofdc;
60753 + break;
60754 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
60755 + *stats_reg = &regs->fmbm_obdc;
60756 + break;
60757 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
60758 + *stats_reg = &regs->fmbm_offc;
60759 + break;
60760 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
60761 + *stats_reg = &regs->fmbm_ofldec;
60762 + break;
60763 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
60764 + *stats_reg = &regs->fmbm_ofledc;
60765 + break;
60766 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
60767 + *stats_reg = &regs->fmbm_ofufdc;
60768 + break;
60769 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
60770 + *stats_reg = &regs->fmbm_ofwdc;
60771 + break;
60772 + default:
60773 + *stats_reg = NULL;
60774 + }
60775 +}
60776 +
60777 +static void get_rx_perf_reg(struct fman_port *port,
60778 + enum fman_port_perf_counters counter,
60779 + uint32_t **perf_reg)
60780 +{
60781 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60782 +
60783 + switch (counter) {
60784 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60785 + *perf_reg = &regs->fmbm_rccn;
60786 + break;
60787 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60788 + *perf_reg = &regs->fmbm_rtuc;
60789 + break;
60790 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
60791 + *perf_reg = &regs->fmbm_rrquc;
60792 + break;
60793 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60794 + *perf_reg = &regs->fmbm_rduc;
60795 + break;
60796 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60797 + *perf_reg = &regs->fmbm_rfuc;
60798 + break;
60799 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
60800 + *perf_reg = &regs->fmbm_rpac;
60801 + break;
60802 + default:
60803 + *perf_reg = NULL;
60804 + }
60805 +}
60806 +
60807 +static void get_tx_perf_reg(struct fman_port *port,
60808 + enum fman_port_perf_counters counter,
60809 + uint32_t **perf_reg)
60810 +{
60811 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60812 +
60813 + switch (counter) {
60814 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60815 + *perf_reg = &regs->fmbm_tccn;
60816 + break;
60817 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60818 + *perf_reg = &regs->fmbm_ttuc;
60819 + break;
60820 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
60821 + *perf_reg = &regs->fmbm_ttcquc;
60822 + break;
60823 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60824 + *perf_reg = &regs->fmbm_tduc;
60825 + break;
60826 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60827 + *perf_reg = &regs->fmbm_tfuc;
60828 + break;
60829 + default:
60830 + *perf_reg = NULL;
60831 + }
60832 +}
60833 +
60834 +static void get_oh_perf_reg(struct fman_port *port,
60835 + enum fman_port_perf_counters counter,
60836 + uint32_t **perf_reg)
60837 +{
60838 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60839 +
60840 + switch (counter) {
60841 + case E_FMAN_PORT_PERF_CNT_CYCLE:
60842 + *perf_reg = &regs->fmbm_occn;
60843 + break;
60844 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
60845 + *perf_reg = &regs->fmbm_otuc;
60846 + break;
60847 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
60848 + *perf_reg = &regs->fmbm_oduc;
60849 + break;
60850 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
60851 + *perf_reg = &regs->fmbm_ofuc;
60852 + break;
60853 + default:
60854 + *perf_reg = NULL;
60855 + }
60856 +}
60857 +
60858 +static void get_qmi_counter_reg(struct fman_port *port,
60859 + enum fman_port_qmi_counters counter,
60860 + uint32_t **queue_reg)
60861 +{
60862 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60863 +
60864 + switch (counter) {
60865 + case E_FMAN_PORT_ENQ_TOTAL:
60866 + *queue_reg = &regs->fmqm_pnetfc;
60867 + break;
60868 + case E_FMAN_PORT_DEQ_TOTAL:
60869 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60870 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
60871 + /* Counter not available for Rx ports */
60872 + *queue_reg = NULL;
60873 + else
60874 + *queue_reg = &regs->fmqm_pndtfc;
60875 + break;
60876 + case E_FMAN_PORT_DEQ_FROM_DFLT:
60877 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60878 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
60879 + /* Counter not available for Rx ports */
60880 + *queue_reg = NULL;
60881 + else
60882 + *queue_reg = &regs->fmqm_pndfdc;
60883 + break;
60884 + case E_FMAN_PORT_DEQ_CONFIRM:
60885 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60886 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
60887 + /* Counter not available for Rx ports */
60888 + *queue_reg = NULL;
60889 + else
60890 + *queue_reg = &regs->fmqm_pndcc;
60891 + break;
60892 + default:
60893 + *queue_reg = NULL;
60894 + }
60895 +}
60896 +
60897 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
60898 +{
60899 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
60900 + cfg->dma_ic_stash_on = FALSE;
60901 + cfg->dma_header_stash_on = FALSE;
60902 + cfg->dma_sg_stash_on = FALSE;
60903 + cfg->dma_write_optimize = TRUE;
60904 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
60905 + cfg->discard_override = FALSE;
60906 + cfg->checksum_bytes_ignore = 0;
60907 + cfg->rx_cut_end_bytes = 4;
60908 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
60909 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
60910 + cfg->rx_fd_bits = 0;
60911 + cfg->ic_ext_offset = 0;
60912 + cfg->ic_int_offset = 0;
60913 + cfg->ic_size = 0;
60914 + cfg->int_buf_start_margin = 0;
60915 + cfg->ext_buf_start_margin = 0;
60916 + cfg->ext_buf_end_margin = 0;
60917 + cfg->tx_fifo_min_level = 0;
60918 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
60919 + cfg->stats_counters_enable = TRUE;
60920 + cfg->perf_counters_enable = TRUE;
60921 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
60922 +
60923 + if (type == E_FMAN_PORT_TYPE_HC) {
60924 + cfg->sync_req = FALSE;
60925 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
60926 + } else {
60927 + cfg->sync_req = TRUE;
60928 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
60929 + }
60930 +
60931 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
60932 + cfg->tx_fifo_deq_pipeline_depth = 4;
60933 + cfg->deq_high_pri = TRUE;
60934 + cfg->deq_byte_cnt = 0x1400;
60935 + } else {
60936 + if ((type == E_FMAN_PORT_TYPE_HC) ||
60937 + (type == E_FMAN_PORT_TYPE_OP))
60938 + cfg->tx_fifo_deq_pipeline_depth = 2;
60939 + else
60940 + cfg->tx_fifo_deq_pipeline_depth = 1;
60941 +
60942 + cfg->deq_high_pri = FALSE;
60943 + cfg->deq_byte_cnt = 0x400;
60944 + }
60945 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
60946 +}
60947 +
60948 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
60949 +{
60950 + uint32_t *bp_reg, tmp;
60951 + uint8_t i, id;
60952 +
60953 + /* Find the pool */
60954 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
60955 + for (i = 0;
60956 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
60957 + i++) {
60958 + tmp = ioread32be(&bp_reg[i]);
60959 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
60960 + BMI_EXT_BUF_POOL_ID_SHIFT);
60961 +
60962 + if (id == bpid)
60963 + break;
60964 + }
60965 +
60966 + return i;
60967 +}
60968 +
60969 +int fman_port_init(struct fman_port *port,
60970 + struct fman_port_cfg *cfg,
60971 + struct fman_port_params *params)
60972 +{
60973 + int err;
60974 +
60975 + /* Init BMI registers */
60976 + switch (port->type) {
60977 + case E_FMAN_PORT_TYPE_RX:
60978 + case E_FMAN_PORT_TYPE_RX_10G:
60979 + err = init_bmi_rx(port, cfg, params);
60980 + break;
60981 + case E_FMAN_PORT_TYPE_TX:
60982 + case E_FMAN_PORT_TYPE_TX_10G:
60983 + err = init_bmi_tx(port, cfg, params);
60984 + break;
60985 + case E_FMAN_PORT_TYPE_OP:
60986 + case E_FMAN_PORT_TYPE_HC:
60987 + err = init_bmi_oh(port, cfg, params);
60988 + break;
60989 + default:
60990 + return -EINVAL;
60991 + }
60992 +
60993 + if (err)
60994 + return err;
60995 +
60996 + /* Init QMI registers */
60997 + if (!port->im_en)
60998 + {
60999 + err = init_qmi(port, cfg, params);
61000 + return err;
61001 + }
61002 + return 0;
61003 +}
61004 +
61005 +int fman_port_enable(struct fman_port *port)
61006 +{
61007 + uint32_t *bmi_cfg_reg, tmp;
61008 + bool rx_port;
61009 +
61010 + switch (port->type) {
61011 + case E_FMAN_PORT_TYPE_RX:
61012 + case E_FMAN_PORT_TYPE_RX_10G:
61013 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61014 + rx_port = TRUE;
61015 + break;
61016 + case E_FMAN_PORT_TYPE_TX:
61017 + case E_FMAN_PORT_TYPE_TX_10G:
61018 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61019 + rx_port = FALSE;
61020 + break;
61021 + case E_FMAN_PORT_TYPE_OP:
61022 + case E_FMAN_PORT_TYPE_HC:
61023 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61024 + rx_port = FALSE;
61025 + break;
61026 + default:
61027 + return -EINVAL;
61028 + }
61029 +
61030 + /* Enable QMI */
61031 + if (!rx_port) {
61032 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
61033 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61034 + }
61035 +
61036 + /* Enable BMI */
61037 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
61038 + iowrite32be(tmp, bmi_cfg_reg);
61039 +
61040 + return 0;
61041 +}
61042 +
61043 +int fman_port_disable(const struct fman_port *port)
61044 +{
61045 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
61046 + bool rx_port, failure = FALSE;
61047 + int count;
61048 +
61049 + switch (port->type) {
61050 + case E_FMAN_PORT_TYPE_RX:
61051 + case E_FMAN_PORT_TYPE_RX_10G:
61052 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61053 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
61054 + rx_port = TRUE;
61055 + break;
61056 + case E_FMAN_PORT_TYPE_TX:
61057 + case E_FMAN_PORT_TYPE_TX_10G:
61058 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61059 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
61060 + rx_port = FALSE;
61061 + break;
61062 + case E_FMAN_PORT_TYPE_OP:
61063 + case E_FMAN_PORT_TYPE_HC:
61064 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61065 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
61066 + rx_port = FALSE;
61067 + break;
61068 + default:
61069 + return -EINVAL;
61070 + }
61071 +
61072 + /* Disable QMI */
61073 + if (!rx_port) {
61074 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
61075 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61076 +
61077 + /* Wait for QMI to finish FD handling */
61078 + count = 100;
61079 + do {
61080 + udelay(10);
61081 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
61082 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
61083 +
61084 + if (count == 0)
61085 + {
61086 + /* Timeout */
61087 + failure = TRUE;
61088 + }
61089 + }
61090 +
61091 + /* Disable BMI */
61092 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
61093 + iowrite32be(tmp, bmi_cfg_reg);
61094 +
61095 + /* Wait for graceful stop end */
61096 + count = 500;
61097 + do {
61098 + udelay(10);
61099 + tmp = ioread32be(bmi_status_reg);
61100 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
61101 +
61102 + if (count == 0)
61103 + {
61104 + /* Timeout */
61105 + failure = TRUE;
61106 + }
61107 +
61108 + if (failure)
61109 + return -EBUSY;
61110 +
61111 + return 0;
61112 +}
61113 +
61114 +int fman_port_set_bpools(const struct fman_port *port,
61115 + const struct fman_port_bpools *bp)
61116 +{
61117 + uint32_t tmp, *bp_reg, *bp_depl_reg;
61118 + uint8_t i, max_bp_num;
61119 + bool grp_depl_used = FALSE, rx_port;
61120 +
61121 + switch (port->type) {
61122 + case E_FMAN_PORT_TYPE_RX:
61123 + case E_FMAN_PORT_TYPE_RX_10G:
61124 + max_bp_num = port->ext_pools_num;
61125 + rx_port = TRUE;
61126 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61127 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
61128 + break;
61129 + case E_FMAN_PORT_TYPE_OP:
61130 + if (port->fm_rev_maj != 4)
61131 + return -EINVAL;
61132 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
61133 + rx_port = FALSE;
61134 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
61135 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
61136 + break;
61137 + default:
61138 + return -EINVAL;
61139 + }
61140 +
61141 + if (rx_port) {
61142 + /* Check buffers are provided in ascending order */
61143 + for (i = 0;
61144 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
61145 + i++) {
61146 + if (bp->bpool[i].size > bp->bpool[i+1].size)
61147 + return -EINVAL;
61148 + }
61149 + }
61150 +
61151 + /* Set up external buffers pools */
61152 + for (i = 0; i < bp->count; i++) {
61153 + tmp = BMI_EXT_BUF_POOL_VALID;
61154 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
61155 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
61156 +
61157 + if (rx_port) {
61158 + if (bp->counters_enable)
61159 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61160 +
61161 + if (bp->bpool[i].is_backup)
61162 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
61163 +
61164 + tmp |= (uint32_t)bp->bpool[i].size;
61165 + }
61166 +
61167 + iowrite32be(tmp, &bp_reg[i]);
61168 + }
61169 +
61170 + /* Clear unused pools */
61171 + for (i = bp->count; i < max_bp_num; i++)
61172 + iowrite32be(0, &bp_reg[i]);
61173 +
61174 + /* Pools depletion */
61175 + tmp = 0;
61176 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
61177 + if (bp->bpool[i].grp_bp_depleted) {
61178 + grp_depl_used = TRUE;
61179 + tmp |= 0x80000000 >> i;
61180 + }
61181 +
61182 + if (bp->bpool[i].single_bp_depleted)
61183 + tmp |= 0x80 >> i;
61184 +
61185 + if (bp->bpool[i].pfc_priorities_en)
61186 + tmp |= 0x0100 << i;
61187 + }
61188 +
61189 + if (grp_depl_used)
61190 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
61191 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
61192 +
61193 + iowrite32be(tmp, bp_depl_reg);
61194 + return 0;
61195 +}
61196 +
61197 +int fman_port_set_rate_limiter(struct fman_port *port,
61198 + struct fman_port_rate_limiter *rate_limiter)
61199 +{
61200 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
61201 + uint32_t granularity, tmp;
61202 + uint8_t usec_bit, factor;
61203 +
61204 + switch (port->type) {
61205 + case E_FMAN_PORT_TYPE_TX:
61206 + case E_FMAN_PORT_TYPE_TX_10G:
61207 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
61208 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61209 + granularity = BMI_RATE_LIMIT_GRAN_TX;
61210 + break;
61211 + case E_FMAN_PORT_TYPE_OP:
61212 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
61213 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61214 + granularity = BMI_RATE_LIMIT_GRAN_OP;
61215 + break;
61216 + default:
61217 + return -EINVAL;
61218 + }
61219 +
61220 + /* Factor is per 1 usec count */
61221 + factor = 1;
61222 + usec_bit = rate_limiter->count_1micro_bit;
61223 +
61224 + /* If rate limit is too small for an 1usec factor, adjust timestamp
61225 + * scale and multiply the factor */
61226 + while (rate_limiter->rate < (granularity / factor)) {
61227 + if (usec_bit == 31)
61228 + /* Can't configure rate limiter - rate is too small */
61229 + return -EINVAL;
61230 +
61231 + usec_bit++;
61232 + factor <<= 1;
61233 + }
61234 +
61235 + /* Figure out register value. The "while" above quarantees that
61236 + * (rate_limiter->rate * factor / granularity) >= 1 */
61237 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
61238 +
61239 + /* Check rate limit isn't too large */
61240 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
61241 + return -EINVAL;
61242 +
61243 + /* Check burst size is in allowed range */
61244 + if ((rate_limiter->burst_size == 0) ||
61245 + (rate_limiter->burst_size >
61246 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
61247 + return -EINVAL;
61248 +
61249 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
61250 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
61251 +
61252 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61253 + (port->fm_rev_maj == 4)) {
61254 + if (rate_limiter->high_burst_size_gran)
61255 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
61256 + }
61257 +
61258 + iowrite32be(tmp, rate_limit_reg);
61259 +
61260 + /* Set up rate limiter scale register */
61261 + tmp = BMI_RATE_LIMIT_SCALE_EN;
61262 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
61263 +
61264 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61265 + (port->fm_rev_maj == 4))
61266 + tmp |= rate_limiter->rate_factor;
61267 +
61268 + iowrite32be(tmp, rate_limit_scale_reg);
61269 +
61270 + return 0;
61271 +}
61272 +
61273 +int fman_port_delete_rate_limiter(struct fman_port *port)
61274 +{
61275 + uint32_t *rate_limit_scale_reg;
61276 +
61277 + switch (port->type) {
61278 + case E_FMAN_PORT_TYPE_TX:
61279 + case E_FMAN_PORT_TYPE_TX_10G:
61280 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61281 + break;
61282 + case E_FMAN_PORT_TYPE_OP:
61283 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61284 + break;
61285 + default:
61286 + return -EINVAL;
61287 + }
61288 +
61289 + iowrite32be(0, rate_limit_scale_reg);
61290 + return 0;
61291 +}
61292 +
61293 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
61294 +{
61295 + uint32_t *err_mask_reg;
61296 +
61297 + /* Obtain register address */
61298 + switch (port->type) {
61299 + case E_FMAN_PORT_TYPE_RX:
61300 + case E_FMAN_PORT_TYPE_RX_10G:
61301 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
61302 + break;
61303 + case E_FMAN_PORT_TYPE_OP:
61304 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
61305 + break;
61306 + default:
61307 + return -EINVAL;
61308 + }
61309 +
61310 + iowrite32be(err_mask, err_mask_reg);
61311 + return 0;
61312 +}
61313 +
61314 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
61315 +{
61316 + uint32_t *discard_mask_reg;
61317 +
61318 + /* Obtain register address */
61319 + switch (port->type) {
61320 + case E_FMAN_PORT_TYPE_RX:
61321 + case E_FMAN_PORT_TYPE_RX_10G:
61322 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
61323 + break;
61324 + case E_FMAN_PORT_TYPE_OP:
61325 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
61326 + break;
61327 + default:
61328 + return -EINVAL;
61329 + }
61330 +
61331 + iowrite32be(discard_mask, discard_mask_reg);
61332 + return 0;
61333 +}
61334 +
61335 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
61336 + uint8_t rx_fd_bits,
61337 + bool add)
61338 +{
61339 + uint32_t tmp;
61340 +
61341 + switch (port->type) {
61342 + case E_FMAN_PORT_TYPE_RX:
61343 + case E_FMAN_PORT_TYPE_RX_10G:
61344 + break;
61345 + default:
61346 + return -EINVAL;
61347 + }
61348 +
61349 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
61350 +
61351 + if (add)
61352 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
61353 + else
61354 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
61355 +
61356 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
61357 + return 0;
61358 +}
61359 +
61360 +int fman_port_set_perf_cnt_params(struct fman_port *port,
61361 + struct fman_port_perf_cnt_params *params)
61362 +{
61363 + uint32_t *pcp_reg, tmp;
61364 +
61365 + /* Obtain register address and check parameters are in range */
61366 + switch (port->type) {
61367 + case E_FMAN_PORT_TYPE_RX:
61368 + case E_FMAN_PORT_TYPE_RX_10G:
61369 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
61370 + if ((params->queue_val == 0) ||
61371 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
61372 + return -EINVAL;
61373 + break;
61374 + case E_FMAN_PORT_TYPE_TX:
61375 + case E_FMAN_PORT_TYPE_TX_10G:
61376 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
61377 + if ((params->queue_val == 0) ||
61378 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
61379 + return -EINVAL;
61380 + break;
61381 + case E_FMAN_PORT_TYPE_OP:
61382 + case E_FMAN_PORT_TYPE_HC:
61383 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
61384 + if (params->queue_val != 0)
61385 + return -EINVAL;
61386 + break;
61387 + default:
61388 + return -EINVAL;
61389 + }
61390 +
61391 + if ((params->task_val == 0) ||
61392 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
61393 + return -EINVAL;
61394 + if ((params->dma_val == 0) ||
61395 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
61396 + return -EINVAL;
61397 + if ((params->fifo_val == 0) ||
61398 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
61399 + MAX_PERFORMANCE_FIFO_COMP))
61400 + return -EINVAL;
61401 + tmp = (uint32_t)(params->task_val - 1) <<
61402 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
61403 + tmp |= (uint32_t)(params->dma_val - 1) <<
61404 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
61405 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
61406 +
61407 + switch (port->type) {
61408 + case E_FMAN_PORT_TYPE_RX:
61409 + case E_FMAN_PORT_TYPE_RX_10G:
61410 + case E_FMAN_PORT_TYPE_TX:
61411 + case E_FMAN_PORT_TYPE_TX_10G:
61412 + tmp |= (uint32_t)(params->queue_val - 1) <<
61413 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
61414 + break;
61415 + default:
61416 + break;
61417 + }
61418 +
61419 +
61420 + iowrite32be(tmp, pcp_reg);
61421 + return 0;
61422 +}
61423 +
61424 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
61425 +{
61426 + uint32_t *stats_reg, tmp;
61427 +
61428 + switch (port->type) {
61429 + case E_FMAN_PORT_TYPE_RX:
61430 + case E_FMAN_PORT_TYPE_RX_10G:
61431 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
61432 + break;
61433 + case E_FMAN_PORT_TYPE_TX:
61434 + case E_FMAN_PORT_TYPE_TX_10G:
61435 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
61436 + break;
61437 + case E_FMAN_PORT_TYPE_OP:
61438 + case E_FMAN_PORT_TYPE_HC:
61439 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
61440 + break;
61441 + default:
61442 + return -EINVAL;
61443 + }
61444 +
61445 + tmp = ioread32be(stats_reg);
61446 +
61447 + if (enable)
61448 + tmp |= BMI_COUNTERS_EN;
61449 + else
61450 + tmp &= ~BMI_COUNTERS_EN;
61451 +
61452 + iowrite32be(tmp, stats_reg);
61453 + return 0;
61454 +}
61455 +
61456 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
61457 +{
61458 + uint32_t *stats_reg, tmp;
61459 +
61460 + switch (port->type) {
61461 + case E_FMAN_PORT_TYPE_RX:
61462 + case E_FMAN_PORT_TYPE_RX_10G:
61463 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
61464 + break;
61465 + case E_FMAN_PORT_TYPE_TX:
61466 + case E_FMAN_PORT_TYPE_TX_10G:
61467 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
61468 + break;
61469 + case E_FMAN_PORT_TYPE_OP:
61470 + case E_FMAN_PORT_TYPE_HC:
61471 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
61472 + break;
61473 + default:
61474 + return -EINVAL;
61475 + }
61476 +
61477 + tmp = ioread32be(stats_reg);
61478 +
61479 + if (enable)
61480 + tmp |= BMI_COUNTERS_EN;
61481 + else
61482 + tmp &= ~BMI_COUNTERS_EN;
61483 +
61484 + iowrite32be(tmp, stats_reg);
61485 + return 0;
61486 +}
61487 +
61488 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
61489 +{
61490 + uint32_t tmp;
61491 +
61492 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
61493 +
61494 + if (enable)
61495 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
61496 + else
61497 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
61498 +
61499 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61500 + return 0;
61501 +}
61502 +
61503 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
61504 + uint8_t bpid,
61505 + bool enable)
61506 +{
61507 + uint8_t index;
61508 + uint32_t tmp;
61509 +
61510 + switch (port->type) {
61511 + case E_FMAN_PORT_TYPE_RX:
61512 + case E_FMAN_PORT_TYPE_RX_10G:
61513 + break;
61514 + default:
61515 + return -EINVAL;
61516 + }
61517 +
61518 + /* Find the pool */
61519 + index = fman_port_find_bpool(port, bpid);
61520 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61521 + /* Not found */
61522 + return -EINVAL;
61523 +
61524 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
61525 +
61526 + if (enable)
61527 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61528 + else
61529 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
61530 +
61531 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
61532 + return 0;
61533 +}
61534 +
61535 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
61536 + enum fman_port_stats_counters counter)
61537 +{
61538 + uint32_t *stats_reg, ret_val;
61539 +
61540 + switch (port->type) {
61541 + case E_FMAN_PORT_TYPE_RX:
61542 + case E_FMAN_PORT_TYPE_RX_10G:
61543 + get_rx_stats_reg(port, counter, &stats_reg);
61544 + break;
61545 + case E_FMAN_PORT_TYPE_TX:
61546 + case E_FMAN_PORT_TYPE_TX_10G:
61547 + get_tx_stats_reg(port, counter, &stats_reg);
61548 + break;
61549 + case E_FMAN_PORT_TYPE_OP:
61550 + case E_FMAN_PORT_TYPE_HC:
61551 + get_oh_stats_reg(port, counter, &stats_reg);
61552 + break;
61553 + default:
61554 + stats_reg = NULL;
61555 + }
61556 +
61557 + if (stats_reg == NULL)
61558 + return 0;
61559 +
61560 + ret_val = ioread32be(stats_reg);
61561 + return ret_val;
61562 +}
61563 +
61564 +void fman_port_set_stats_counter(struct fman_port *port,
61565 + enum fman_port_stats_counters counter,
61566 + uint32_t value)
61567 +{
61568 + uint32_t *stats_reg;
61569 +
61570 + switch (port->type) {
61571 + case E_FMAN_PORT_TYPE_RX:
61572 + case E_FMAN_PORT_TYPE_RX_10G:
61573 + get_rx_stats_reg(port, counter, &stats_reg);
61574 + break;
61575 + case E_FMAN_PORT_TYPE_TX:
61576 + case E_FMAN_PORT_TYPE_TX_10G:
61577 + get_tx_stats_reg(port, counter, &stats_reg);
61578 + break;
61579 + case E_FMAN_PORT_TYPE_OP:
61580 + case E_FMAN_PORT_TYPE_HC:
61581 + get_oh_stats_reg(port, counter, &stats_reg);
61582 + break;
61583 + default:
61584 + stats_reg = NULL;
61585 + }
61586 +
61587 + if (stats_reg == NULL)
61588 + return;
61589 +
61590 + iowrite32be(value, stats_reg);
61591 +}
61592 +
61593 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
61594 + enum fman_port_perf_counters counter)
61595 +{
61596 + uint32_t *perf_reg, ret_val;
61597 +
61598 + switch (port->type) {
61599 + case E_FMAN_PORT_TYPE_RX:
61600 + case E_FMAN_PORT_TYPE_RX_10G:
61601 + get_rx_perf_reg(port, counter, &perf_reg);
61602 + break;
61603 + case E_FMAN_PORT_TYPE_TX:
61604 + case E_FMAN_PORT_TYPE_TX_10G:
61605 + get_tx_perf_reg(port, counter, &perf_reg);
61606 + break;
61607 + case E_FMAN_PORT_TYPE_OP:
61608 + case E_FMAN_PORT_TYPE_HC:
61609 + get_oh_perf_reg(port, counter, &perf_reg);
61610 + break;
61611 + default:
61612 + perf_reg = NULL;
61613 + }
61614 +
61615 + if (perf_reg == NULL)
61616 + return 0;
61617 +
61618 + ret_val = ioread32be(perf_reg);
61619 + return ret_val;
61620 +}
61621 +
61622 +void fman_port_set_perf_counter(struct fman_port *port,
61623 + enum fman_port_perf_counters counter,
61624 + uint32_t value)
61625 +{
61626 + uint32_t *perf_reg;
61627 +
61628 + switch (port->type) {
61629 + case E_FMAN_PORT_TYPE_RX:
61630 + case E_FMAN_PORT_TYPE_RX_10G:
61631 + get_rx_perf_reg(port, counter, &perf_reg);
61632 + break;
61633 + case E_FMAN_PORT_TYPE_TX:
61634 + case E_FMAN_PORT_TYPE_TX_10G:
61635 + get_tx_perf_reg(port, counter, &perf_reg);
61636 + break;
61637 + case E_FMAN_PORT_TYPE_OP:
61638 + case E_FMAN_PORT_TYPE_HC:
61639 + get_oh_perf_reg(port, counter, &perf_reg);
61640 + break;
61641 + default:
61642 + perf_reg = NULL;
61643 + }
61644 +
61645 + if (perf_reg == NULL)
61646 + return;
61647 +
61648 + iowrite32be(value, perf_reg);
61649 +}
61650 +
61651 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
61652 + enum fman_port_qmi_counters counter)
61653 +{
61654 + uint32_t *queue_reg, ret_val;
61655 +
61656 + get_qmi_counter_reg(port, counter, &queue_reg);
61657 +
61658 + if (queue_reg == NULL)
61659 + return 0;
61660 +
61661 + ret_val = ioread32be(queue_reg);
61662 + return ret_val;
61663 +}
61664 +
61665 +void fman_port_set_qmi_counter(struct fman_port *port,
61666 + enum fman_port_qmi_counters counter,
61667 + uint32_t value)
61668 +{
61669 + uint32_t *queue_reg;
61670 +
61671 + get_qmi_counter_reg(port, counter, &queue_reg);
61672 +
61673 + if (queue_reg == NULL)
61674 + return;
61675 +
61676 + iowrite32be(value, queue_reg);
61677 +}
61678 +
61679 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
61680 +{
61681 + uint8_t index;
61682 + uint32_t ret_val;
61683 +
61684 + switch (port->type) {
61685 + case E_FMAN_PORT_TYPE_RX:
61686 + case E_FMAN_PORT_TYPE_RX_10G:
61687 + break;
61688 + default:
61689 + return 0;
61690 + }
61691 +
61692 + /* Find the pool */
61693 + index = fman_port_find_bpool(port, bpid);
61694 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61695 + /* Not found */
61696 + return 0;
61697 +
61698 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
61699 + return ret_val;
61700 +}
61701 +
61702 +void fman_port_set_bpool_counter(struct fman_port *port,
61703 + uint8_t bpid,
61704 + uint32_t value)
61705 +{
61706 + uint8_t index;
61707 +
61708 + switch (port->type) {
61709 + case E_FMAN_PORT_TYPE_RX:
61710 + case E_FMAN_PORT_TYPE_RX_10G:
61711 + break;
61712 + default:
61713 + return;
61714 + }
61715 +
61716 + /* Find the pool */
61717 + index = fman_port_find_bpool(port, bpid);
61718 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61719 + /* Not found */
61720 + return;
61721 +
61722 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
61723 +}
61724 +
61725 +int fman_port_add_congestion_grps(struct fman_port *port,
61726 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61727 +{
61728 + int i;
61729 + uint32_t tmp, *grp_map_reg;
61730 + uint8_t max_grp_map_num;
61731 +
61732 + switch (port->type) {
61733 + case E_FMAN_PORT_TYPE_RX:
61734 + case E_FMAN_PORT_TYPE_RX_10G:
61735 + if (port->fm_rev_maj == 4)
61736 + max_grp_map_num = 1;
61737 + else
61738 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61739 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61740 + break;
61741 + case E_FMAN_PORT_TYPE_OP:
61742 + max_grp_map_num = 1;
61743 + if (port->fm_rev_maj != 4)
61744 + return -EINVAL;
61745 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
61746 + break;
61747 + default:
61748 + return -EINVAL;
61749 + }
61750 +
61751 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
61752 + if (grps_map[i] == 0)
61753 + continue;
61754 + tmp = ioread32be(&grp_map_reg[i]);
61755 + tmp |= grps_map[i];
61756 + iowrite32be(tmp, &grp_map_reg[i]);
61757 + }
61758 +
61759 + return 0;
61760 +}
61761 +
61762 +int fman_port_remove_congestion_grps(struct fman_port *port,
61763 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
61764 +{
61765 + int i;
61766 + uint32_t tmp, *grp_map_reg;
61767 + uint8_t max_grp_map_num;
61768 +
61769 + switch (port->type) {
61770 + case E_FMAN_PORT_TYPE_RX:
61771 + case E_FMAN_PORT_TYPE_RX_10G:
61772 + if (port->fm_rev_maj == 4)
61773 + max_grp_map_num = 1;
61774 + else
61775 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
61776 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
61777 + break;
61778 + case E_FMAN_PORT_TYPE_OP:
61779 + max_grp_map_num = 1;
61780 + if (port->fm_rev_maj != 4)
61781 + return -EINVAL;
61782 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
61783 + break;
61784 + default:
61785 + return -EINVAL;
61786 + }
61787 +
61788 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
61789 + if (grps_map[i] == 0)
61790 + continue;
61791 + tmp = ioread32be(&grp_map_reg[i]);
61792 + tmp &= ~grps_map[i];
61793 + iowrite32be(tmp, &grp_map_reg[i]);
61794 + }
61795 + return 0;
61796 +}
61797 --- /dev/null
61798 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
61799 @@ -0,0 +1,15 @@
61800 +#
61801 +# Makefile for the Freescale Ethernet controllers
61802 +#
61803 +ccflags-y += -DVERSION=\"\"
61804 +#
61805 +#Include netcomm SW specific definitions
61806 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
61807 +
61808 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
61809 +
61810 +ccflags-y += -I$(NCSW_FM_INC)
61811 +
61812 +obj-y += fsl-ncsw-RTC.o
61813 +
61814 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
61815 --- /dev/null
61816 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
61817 @@ -0,0 +1,692 @@
61818 +/*
61819 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61820 + *
61821 + * Redistribution and use in source and binary forms, with or without
61822 + * modification, are permitted provided that the following conditions are met:
61823 + * * Redistributions of source code must retain the above copyright
61824 + * notice, this list of conditions and the following disclaimer.
61825 + * * Redistributions in binary form must reproduce the above copyright
61826 + * notice, this list of conditions and the following disclaimer in the
61827 + * documentation and/or other materials provided with the distribution.
61828 + * * Neither the name of Freescale Semiconductor nor the
61829 + * names of its contributors may be used to endorse or promote products
61830 + * derived from this software without specific prior written permission.
61831 + *
61832 + *
61833 + * ALTERNATIVELY, this software may be distributed under the terms of the
61834 + * GNU General Public License ("GPL") as published by the Free Software
61835 + * Foundation, either version 2 of that License or (at your option) any
61836 + * later version.
61837 + *
61838 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
61839 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
61840 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61841 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
61842 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61843 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61844 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61845 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61846 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61847 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61848 + */
61849 +
61850 +
61851 +/******************************************************************************
61852 + @File fm_rtc.c
61853 +
61854 + @Description FM RTC driver implementation.
61855 +
61856 + @Cautions None
61857 +*//***************************************************************************/
61858 +#include <linux/math64.h>
61859 +#include "error_ext.h"
61860 +#include "debug_ext.h"
61861 +#include "string_ext.h"
61862 +#include "part_ext.h"
61863 +#include "xx_ext.h"
61864 +#include "ncsw_ext.h"
61865 +
61866 +#include "fm_rtc.h"
61867 +#include "fm_common.h"
61868 +
61869 +
61870 +
61871 +/*****************************************************************************/
61872 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
61873 +{
61874 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
61875 + int i;
61876 +
61877 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
61878 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
61879 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
61880 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
61881 +
61882 + if (p_Rtc->outputClockDivisor == 0)
61883 + {
61884 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
61885 + ("Divisor for output clock (should be positive)"));
61886 + }
61887 +
61888 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
61889 + {
61890 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
61891 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
61892 + {
61893 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
61894 + }
61895 + }
61896 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
61897 + {
61898 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
61899 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
61900 + {
61901 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
61902 + }
61903 + }
61904 +
61905 + return E_OK;
61906 +}
61907 +
61908 +/*****************************************************************************/
61909 +static void RtcExceptions(t_Handle h_FmRtc)
61910 +{
61911 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
61912 + struct rtc_regs *p_MemMap;
61913 + register uint32_t events;
61914 +
61915 + ASSERT_COND(p_Rtc);
61916 + p_MemMap = p_Rtc->p_MemMap;
61917 +
61918 + events = fman_rtc_check_and_clear_event(p_MemMap);
61919 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
61920 + {
61921 + if (p_Rtc->alarmParams[0].clearOnExpiration)
61922 + {
61923 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
61924 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
61925 + }
61926 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
61927 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
61928 + }
61929 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
61930 + {
61931 + if (p_Rtc->alarmParams[1].clearOnExpiration)
61932 + {
61933 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
61934 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
61935 + }
61936 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
61937 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
61938 + }
61939 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
61940 + {
61941 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
61942 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
61943 + }
61944 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
61945 + {
61946 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
61947 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
61948 + }
61949 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
61950 + {
61951 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
61952 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
61953 + }
61954 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
61955 + {
61956 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
61957 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
61958 + }
61959 +}
61960 +
61961 +
61962 +/*****************************************************************************/
61963 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
61964 +{
61965 + t_FmRtc *p_Rtc;
61966 +
61967 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
61968 +
61969 + /* Allocate memory for the FM RTC driver parameters */
61970 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
61971 + if (!p_Rtc)
61972 + {
61973 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
61974 + return NULL;
61975 + }
61976 +
61977 + memset(p_Rtc, 0, sizeof(t_FmRtc));
61978 +
61979 + /* Allocate memory for the FM RTC driver parameters */
61980 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
61981 + if (!p_Rtc->p_RtcDriverParam)
61982 + {
61983 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
61984 + XX_Free(p_Rtc);
61985 + return NULL;
61986 + }
61987 +
61988 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
61989 +
61990 + /* Store RTC configuration parameters */
61991 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
61992 +
61993 + /* Set default RTC configuration parameters */
61994 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
61995 +
61996 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
61997 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
61998 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
61999 +
62000 +
62001 + /* Store RTC parameters in the RTC control structure */
62002 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
62003 + p_Rtc->h_App = p_FmRtcParam->h_App;
62004 +
62005 + return p_Rtc;
62006 +}
62007 +
62008 +/*****************************************************************************/
62009 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
62010 +{
62011 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62012 + struct rtc_cfg *p_RtcDriverParam;
62013 + struct rtc_regs *p_MemMap;
62014 + uint32_t freqCompensation = 0;
62015 + uint64_t tmpDouble;
62016 + bool init_freq_comp = FALSE;
62017 +
62018 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62019 + p_MemMap = p_Rtc->p_MemMap;
62020 +
62021 + if (CheckInitParameters(p_Rtc)!=E_OK)
62022 + RETURN_ERROR(MAJOR, E_CONFLICT,
62023 + ("Init Parameters are not Valid"));
62024 +
62025 + /* TODO check that no timestamping MACs are working in this stage. */
62026 +
62027 + /* find source clock frequency in Mhz */
62028 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
62029 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
62030 + else
62031 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
62032 +
62033 + /* if timer in Master mode Initialize TMR_CTRL */
62034 + /* We want the counter (TMR_CNT) to count in nano-seconds */
62035 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
62036 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
62037 + else
62038 + {
62039 + /* Initialize TMR_ADD with the initial frequency compensation value:
62040 + freqCompensation = (2^32 / frequency ratio) */
62041 + /* frequency ratio = sorce clock/rtc clock =
62042 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
62043 + init_freq_comp = TRUE;
62044 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
62045 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
62046 + }
62047 +
62048 + /* check the legality of the relation between source and destination clocks */
62049 + /* should be larger than 1.0001 */
62050 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
62051 + if ((tmpDouble) <= 10001)
62052 + RETURN_ERROR(MAJOR, E_CONFLICT,
62053 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
62054 +
62055 + fman_rtc_init(p_RtcDriverParam,
62056 + p_MemMap,
62057 + FM_RTC_NUM_OF_ALARMS,
62058 + FM_RTC_NUM_OF_PERIODIC_PULSES,
62059 + FM_RTC_NUM_OF_EXT_TRIGGERS,
62060 + init_freq_comp,
62061 + freqCompensation,
62062 + p_Rtc->outputClockDivisor);
62063 +
62064 + /* Register the FM RTC interrupt */
62065 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
62066 +
62067 + /* Free parameters structures */
62068 + XX_Free(p_Rtc->p_RtcDriverParam);
62069 + p_Rtc->p_RtcDriverParam = NULL;
62070 +
62071 + return E_OK;
62072 +}
62073 +
62074 +/*****************************************************************************/
62075 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
62076 +{
62077 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62078 +
62079 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62080 +
62081 + if (p_Rtc->p_RtcDriverParam)
62082 + {
62083 + XX_Free(p_Rtc->p_RtcDriverParam);
62084 + }
62085 + else
62086 + {
62087 + FM_RTC_Disable(h_FmRtc);
62088 + }
62089 +
62090 + /* Unregister FM RTC interrupt */
62091 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
62092 + XX_Free(p_Rtc);
62093 +
62094 + return E_OK;
62095 +}
62096 +
62097 +/*****************************************************************************/
62098 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
62099 + e_FmSrcClk srcClk,
62100 + uint32_t freqInMhz)
62101 +{
62102 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62103 +
62104 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62105 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62106 +
62107 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
62108 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
62109 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
62110 +
62111 + return E_OK;
62112 +}
62113 +
62114 +/*****************************************************************************/
62115 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
62116 +{
62117 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62118 +
62119 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62120 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62121 +
62122 + p_Rtc->clockPeriodNanoSec = period;
62123 +
62124 + return E_OK;
62125 +}
62126 +
62127 +/*****************************************************************************/
62128 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
62129 +{
62130 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62131 +
62132 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62133 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62134 +
62135 + p_Rtc->p_RtcDriverParam->bypass = enabled;
62136 +
62137 + return E_OK;
62138 +}
62139 +
62140 +/*****************************************************************************/
62141 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
62142 +{
62143 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62144 +
62145 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62146 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62147 +
62148 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
62149 +
62150 + return E_OK;
62151 +}
62152 +
62153 +/*****************************************************************************/
62154 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
62155 +{
62156 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62157 +
62158 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62159 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62160 +
62161 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
62162 +
62163 + return E_OK;
62164 +}
62165 +
62166 +/*****************************************************************************/
62167 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
62168 +{
62169 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62170 +
62171 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62172 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62173 +
62174 + p_Rtc->outputClockDivisor = divisor;
62175 +
62176 + return E_OK;
62177 +}
62178 +
62179 +/*****************************************************************************/
62180 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
62181 +{
62182 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62183 +
62184 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62185 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62186 +
62187 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
62188 +
62189 + return E_OK;
62190 +}
62191 +
62192 +/*****************************************************************************/
62193 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
62194 + uint8_t alarmId,
62195 + e_FmRtcAlarmPolarity alarmPolarity)
62196 +{
62197 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62198 +
62199 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62200 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62201 +
62202 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
62203 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62204 +
62205 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
62206 + (enum fman_rtc_alarm_polarity)alarmPolarity;
62207 +
62208 + return E_OK;
62209 +}
62210 +
62211 +/*****************************************************************************/
62212 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
62213 + uint8_t triggerId,
62214 + e_FmRtcTriggerPolarity triggerPolarity)
62215 +{
62216 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62217 +
62218 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62219 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62220 +
62221 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62222 + {
62223 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62224 + }
62225 +
62226 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
62227 + (enum fman_rtc_trigger_polarity)triggerPolarity;
62228 +
62229 + return E_OK;
62230 +}
62231 +
62232 +/*****************************************************************************/
62233 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
62234 +{
62235 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62236 +
62237 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62238 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62239 +
62240 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
62241 + return E_OK;
62242 +}
62243 +
62244 +/*****************************************************************************/
62245 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
62246 +{
62247 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62248 +
62249 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62250 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62251 +
62252 + /* TODO A check must be added here, that no timestamping MAC's
62253 + * are working in this stage. */
62254 + fman_rtc_disable(p_Rtc->p_MemMap);
62255 +
62256 + return E_OK;
62257 +}
62258 +
62259 +/*****************************************************************************/
62260 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
62261 +{
62262 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62263 +
62264 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62265 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62266 +
62267 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
62268 + return E_OK;
62269 +}
62270 +
62271 +/*****************************************************************************/
62272 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
62273 +{
62274 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62275 + uint64_t tmpAlarm;
62276 + bool enable = FALSE;
62277 +
62278 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62279 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62280 +
62281 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
62282 + {
62283 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62284 + }
62285 +
62286 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
62287 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62288 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
62289 + p_Rtc->clockPeriodNanoSec));
62290 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
62291 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
62292 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62293 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
62294 + p_Rtc->clockPeriodNanoSec));
62295 +
62296 + if (p_FmRtcAlarmParams->f_AlarmCallback)
62297 + {
62298 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
62299 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
62300 + enable = TRUE;
62301 + }
62302 +
62303 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
62304 +
62305 + return E_OK;
62306 +}
62307 +
62308 +/*****************************************************************************/
62309 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
62310 +{
62311 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62312 + bool enable = FALSE;
62313 + uint64_t tmpFiper;
62314 +
62315 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62316 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62317 +
62318 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62319 + {
62320 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62321 + }
62322 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
62323 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
62324 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
62325 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62326 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
62327 + p_Rtc->clockPeriodNanoSec));
62328 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
62329 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
62330 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62331 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
62332 + p_Rtc->clockPeriodNanoSec));
62333 + if (tmpFiper & 0xffffffff00000000LL)
62334 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62335 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
62336 + p_Rtc->clockPeriodNanoSec));
62337 +
62338 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
62339 + {
62340 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
62341 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
62342 + enable = TRUE;
62343 + }
62344 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
62345 + return E_OK;
62346 +}
62347 +
62348 +/*****************************************************************************/
62349 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
62350 +{
62351 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62352 +
62353 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62354 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62355 +
62356 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62357 + {
62358 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62359 + }
62360 +
62361 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
62362 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
62363 +
62364 + return E_OK;
62365 +}
62366 +
62367 +/*****************************************************************************/
62368 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
62369 +{
62370 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62371 + bool enable = FALSE;
62372 +
62373 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62374 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62375 +
62376 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62377 + {
62378 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62379 + }
62380 +
62381 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
62382 + {
62383 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
62384 + enable = TRUE;
62385 + }
62386 +
62387 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
62388 + return E_OK;
62389 +}
62390 +
62391 +/*****************************************************************************/
62392 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
62393 +{
62394 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62395 +
62396 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62397 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62398 +
62399 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62400 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62401 +
62402 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
62403 +
62404 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
62405 +
62406 + return E_OK;
62407 +}
62408 +
62409 +/*****************************************************************************/
62410 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
62411 + uint8_t triggerId,
62412 + uint64_t *p_TimeStamp)
62413 +{
62414 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62415 +
62416 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62417 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62418 +
62419 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62420 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62421 +
62422 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
62423 +
62424 + return E_OK;
62425 +}
62426 +
62427 +/*****************************************************************************/
62428 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
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_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
62436 +
62437 + return E_OK;
62438 +}
62439 +
62440 +/*****************************************************************************/
62441 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
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 + do_div(ts, p_Rtc->clockPeriodNanoSec);
62449 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
62450 +
62451 + return E_OK;
62452 +}
62453 +
62454 +/*****************************************************************************/
62455 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
62456 +{
62457 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62458 +
62459 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62460 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62461 +
62462 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
62463 +
62464 + return E_OK;
62465 +}
62466 +
62467 +/*****************************************************************************/
62468 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
62469 +{
62470 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62471 +
62472 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62473 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62474 +
62475 + /* set the new freqCompensation */
62476 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
62477 +
62478 + return E_OK;
62479 +}
62480 +
62481 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
62482 +/*****************************************************************************/
62483 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
62484 +{
62485 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62486 +
62487 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62488 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62489 +
62490 + /* enable interrupt */
62491 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
62492 +
62493 + return E_OK;
62494 +}
62495 +
62496 +/*****************************************************************************/
62497 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
62498 +{
62499 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62500 +
62501 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62502 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62503 +
62504 + /* disable interrupt */
62505 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
62506 +
62507 + return E_OK;
62508 +}
62509 +#endif
62510 --- /dev/null
62511 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62512 @@ -0,0 +1,96 @@
62513 +/*
62514 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62515 + *
62516 + * Redistribution and use in source and binary forms, with or without
62517 + * modification, are permitted provided that the following conditions are met:
62518 + * * Redistributions of source code must retain the above copyright
62519 + * notice, this list of conditions and the following disclaimer.
62520 + * * Redistributions in binary form must reproduce the above copyright
62521 + * notice, this list of conditions and the following disclaimer in the
62522 + * documentation and/or other materials provided with the distribution.
62523 + * * Neither the name of Freescale Semiconductor nor the
62524 + * names of its contributors may be used to endorse or promote products
62525 + * derived from this software without specific prior written permission.
62526 + *
62527 + *
62528 + * ALTERNATIVELY, this software may be distributed under the terms of the
62529 + * GNU General Public License ("GPL") as published by the Free Software
62530 + * Foundation, either version 2 of that License or (at your option) any
62531 + * later version.
62532 + *
62533 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62534 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62535 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62536 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62537 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62538 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62539 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62540 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62541 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62542 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62543 + */
62544 +
62545 +
62546 +/******************************************************************************
62547 + @File fm_rtc.h
62548 +
62549 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
62550 +
62551 + @Cautions None
62552 +*//***************************************************************************/
62553 +
62554 +#ifndef __FM_RTC_H__
62555 +#define __FM_RTC_H__
62556 +
62557 +#include "std_ext.h"
62558 +#include "fm_rtc_ext.h"
62559 +
62560 +
62561 +#define __ERR_MODULE__ MODULE_FM_RTC
62562 +
62563 +/* General definitions */
62564 +
62565 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
62566 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
62567 +#define DEFAULT_BYPASS FALSE
62568 +#define DEFAULT_CLOCK_PERIOD 1000
62569 +
62570 +
62571 +
62572 +typedef struct t_FmRtcAlarm
62573 +{
62574 + t_FmRtcExceptionsCallback *f_AlarmCallback;
62575 + bool clearOnExpiration;
62576 +} t_FmRtcAlarm;
62577 +
62578 +typedef struct t_FmRtcPeriodicPulse
62579 +{
62580 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
62581 +} t_FmRtcPeriodicPulse;
62582 +
62583 +typedef struct t_FmRtcExternalTrigger
62584 +{
62585 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
62586 +} t_FmRtcExternalTrigger;
62587 +
62588 +
62589 +/**************************************************************************//**
62590 + @Description RTC FM driver control structure.
62591 +*//***************************************************************************/
62592 +typedef struct t_FmRtc
62593 +{
62594 + t_Part *p_Part; /**< Pointer to the integration device */
62595 + t_Handle h_Fm;
62596 + t_Handle h_App; /**< Application handle */
62597 + struct rtc_regs *p_MemMap;
62598 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
62599 + uint32_t srcClkFreqMhz;
62600 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
62601 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
62602 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
62603 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
62604 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
62605 +} t_FmRtc;
62606 +
62607 +
62608 +#endif /* __FM_RTC_H__ */
62609 --- /dev/null
62610 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62611 @@ -0,0 +1,334 @@
62612 +/*
62613 + * Copyright 2008-2013 Freescale Semiconductor Inc.
62614 + *
62615 + * Redistribution and use in source and binary forms, with or without
62616 + * modification, are permitted provided that the following conditions are met:
62617 + * * Redistributions of source code must retain the above copyright
62618 + * notice, this list of conditions and the following disclaimer.
62619 + * * Redistributions in binary form must reproduce the above copyright
62620 + * notice, this list of conditions and the following disclaimer in the
62621 + * documentation and/or other materials provided with the distribution.
62622 + * * Neither the name of Freescale Semiconductor nor the
62623 + * names of its contributors may be used to endorse or promote products
62624 + * derived from this software without specific prior written permission.
62625 + *
62626 + *
62627 + * ALTERNATIVELY, this software may be distributed under the terms of the
62628 + * GNU General Public License ("GPL") as published by the Free Software
62629 + * Foundation, either version 2 of that License or (at your option) any
62630 + * later version.
62631 + *
62632 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62633 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62634 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62635 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62636 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62637 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62638 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62639 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62640 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62641 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62642 + */
62643 +
62644 +#include "fsl_fman_rtc.h"
62645 +
62646 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
62647 +{
62648 + int i;
62649 + cfg->src_clk = DEFAULT_SRC_CLOCK;
62650 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
62651 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
62652 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
62653 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
62654 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
62655 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
62656 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
62657 +}
62658 +
62659 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
62660 +{
62661 + return ioread32be(&regs->tmr_tevent);
62662 +}
62663 +
62664 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
62665 +{
62666 + return ioread32be(&regs->tmr_tevent) & ev_mask;
62667 +}
62668 +
62669 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
62670 +{
62671 + return ioread32be(&regs->tmr_temask);
62672 +}
62673 +
62674 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
62675 +{
62676 + iowrite32be(mask, &regs->tmr_temask);
62677 +}
62678 +
62679 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
62680 +{
62681 + iowrite32be(events, &regs->tmr_tevent);
62682 +}
62683 +
62684 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
62685 +{
62686 + uint32_t event;
62687 +
62688 + event = ioread32be(&regs->tmr_tevent);
62689 + event &= ioread32be(&regs->tmr_temask);
62690 +
62691 + if (event)
62692 + iowrite32be(event, &regs->tmr_tevent);
62693 + return event;
62694 +}
62695 +
62696 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
62697 +{
62698 + return ioread32be(&regs->tmr_add);
62699 +}
62700 +
62701 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
62702 +{
62703 + iowrite32be(val, &regs->tmr_add);
62704 +}
62705 +
62706 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
62707 +{
62708 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
62709 +}
62710 +
62711 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
62712 +{
62713 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
62714 +}
62715 +
62716 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
62717 +{
62718 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
62719 +}
62720 +
62721 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
62722 +{
62723 + iowrite32be(val, &regs->tmr_fiper[index]);
62724 +}
62725 +
62726 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
62727 +{
62728 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
62729 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
62730 +}
62731 +
62732 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
62733 +{
62734 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
62735 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
62736 +}
62737 +
62738 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
62739 +{
62740 + uint64_t time;
62741 + /* TMR_CNT_L must be read first to get an accurate value */
62742 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
62743 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
62744 + << 32);
62745 +
62746 + return time;
62747 +}
62748 +
62749 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
62750 +{
62751 + return ioread32be(&regs->tmr_ctrl);
62752 +}
62753 +
62754 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
62755 +{
62756 + iowrite32be(val, &regs->tmr_ctrl);
62757 +}
62758 +
62759 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
62760 +{
62761 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
62762 + udelay(10);
62763 + fman_rtc_set_timer_ctrl(regs, 0);
62764 +}
62765 +
62766 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
62767 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
62768 + uint32_t freq_compensation, uint32_t output_clock_divisor)
62769 +{
62770 + uint32_t tmr_ctrl;
62771 + int i;
62772 +
62773 + fman_rtc_timers_soft_reset(regs);
62774 +
62775 + /* Set the source clock */
62776 + switch (cfg->src_clk) {
62777 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
62778 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
62779 + break;
62780 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
62781 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
62782 + break;
62783 + default:
62784 + /* Use a clock from the External TMR reference clock.*/
62785 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
62786 + break;
62787 + }
62788 +
62789 + /* whatever period the user picked, the timestamp will advance in '1'
62790 + * every time the period passed. */
62791 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
62792 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
62793 +
62794 + if (cfg->invert_input_clk_phase)
62795 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
62796 + if (cfg->invert_output_clk_phase)
62797 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
62798 +
62799 + for (i = 0; i < num_alarms; i++) {
62800 + if (cfg->alarm_polarity[i] ==
62801 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
62802 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
62803 + }
62804 +
62805 + for (i = 0; i < num_ext_triggers; i++)
62806 + if (cfg->trigger_polarity[i] ==
62807 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
62808 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
62809 +
62810 + if (!cfg->timer_slave_mode && cfg->bypass)
62811 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
62812 +
62813 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
62814 + if (init_freq_comp)
62815 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
62816 +
62817 + /* Clear TMR_ALARM registers */
62818 + for (i = 0; i < num_alarms; i++)
62819 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
62820 +
62821 + /* Clear TMR_TEVENT */
62822 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
62823 +
62824 + /* Initialize TMR_TEMASK */
62825 + fman_rtc_set_interrupt_mask(regs, 0);
62826 +
62827 + /* Clear TMR_FIPER registers */
62828 + for (i = 0; i < num_fipers; i++)
62829 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
62830 +
62831 + /* Initialize TMR_PRSC */
62832 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
62833 +
62834 + /* Clear TMR_OFF */
62835 + fman_rtc_set_timer_offset(regs, 0);
62836 +}
62837 +
62838 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
62839 +{
62840 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
62841 +}
62842 +
62843 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
62844 +{
62845 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
62846 +
62847 + /* TODO check that no timestamping MACs are working in this stage. */
62848 + if (reset_clock) {
62849 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
62850 +
62851 + udelay(10);
62852 + /* Clear TMR_OFF */
62853 + fman_rtc_set_timer_offset(regs, 0);
62854 + }
62855 +
62856 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
62857 +}
62858 +
62859 +void fman_rtc_disable(struct rtc_regs *regs)
62860 +{
62861 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
62862 + & ~(FMAN_RTC_TMR_CTRL_TE)));
62863 +}
62864 +
62865 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
62866 +{
62867 + uint32_t tmp_reg;
62868 + if (id == 0)
62869 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
62870 + else
62871 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
62872 + fman_rtc_disable_interupt(regs, tmp_reg);
62873 +
62874 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
62875 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
62876 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
62877 +
62878 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
62879 +}
62880 +
62881 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
62882 +{
62883 + uint32_t tmpReg, tmp_ctrl;
62884 +
62885 + if (id == 0)
62886 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
62887 + else
62888 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
62889 + fman_rtc_disable_interupt(regs, tmpReg);
62890 +
62891 + if (id == 0)
62892 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
62893 + else
62894 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
62895 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
62896 + if (tmp_ctrl & tmpReg)
62897 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
62898 +}
62899 +
62900 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
62901 +{
62902 + uint32_t tmpReg;
62903 + fman_rtc_set_timer_alarm(regs, id, val);
62904 + if (enable) {
62905 + if (id == 0)
62906 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
62907 + else
62908 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
62909 + fman_rtc_enable_interupt(regs, tmpReg);
62910 + }
62911 +}
62912 +
62913 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
62914 + bool enable)
62915 +{
62916 + uint32_t tmpReg;
62917 + fman_rtc_set_timer_fiper(regs, id, val);
62918 + if (enable) {
62919 + if (id == 0)
62920 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
62921 + else
62922 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
62923 + fman_rtc_enable_interupt(regs, tmpReg);
62924 + }
62925 +}
62926 +
62927 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
62928 + bool use_pulse_as_input)
62929 +{
62930 + uint32_t tmpReg;
62931 + if (enable) {
62932 + if (id == 0)
62933 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
62934 + else
62935 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
62936 + fman_rtc_enable_interupt(regs, tmpReg);
62937 + }
62938 + if (use_pulse_as_input) {
62939 + if (id == 0)
62940 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
62941 + else
62942 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
62943 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
62944 + }
62945 +}
62946 --- /dev/null
62947 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
62948 @@ -0,0 +1,15 @@
62949 +#
62950 +# Makefile for the Freescale Ethernet controllers
62951 +#
62952 +ccflags-y += -DVERSION=\"\"
62953 +#
62954 +#Include netcomm SW specific definitions
62955 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
62956 +
62957 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
62958 +
62959 +ccflags-y += -I$(NCSW_FM_INC)
62960 +
62961 +obj-y += fsl-ncsw-sp.o
62962 +
62963 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
62964 --- /dev/null
62965 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
62966 @@ -0,0 +1,757 @@
62967 +/*
62968 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62969 + *
62970 + * Redistribution and use in source and binary forms, with or without
62971 + * modification, are permitted provided that the following conditions are met:
62972 + * * Redistributions of source code must retain the above copyright
62973 + * notice, this list of conditions and the following disclaimer.
62974 + * * Redistributions in binary form must reproduce the above copyright
62975 + * notice, this list of conditions and the following disclaimer in the
62976 + * documentation and/or other materials provided with the distribution.
62977 + * * Neither the name of Freescale Semiconductor nor the
62978 + * names of its contributors may be used to endorse or promote products
62979 + * derived from this software without specific prior written permission.
62980 + *
62981 + *
62982 + * ALTERNATIVELY, this software may be distributed under the terms of the
62983 + * GNU General Public License ("GPL") as published by the Free Software
62984 + * Foundation, either version 2 of that License or (at your option) any
62985 + * later version.
62986 + *
62987 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62988 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62989 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62990 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62991 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62992 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62993 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62994 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62995 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62996 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62997 + */
62998 +
62999 +
63000 +/******************************************************************************
63001 + @File fm_sp.c
63002 +
63003 + @Description FM PCD Storage profile ...
63004 +*//***************************************************************************/
63005 +
63006 +#include "std_ext.h"
63007 +#include "error_ext.h"
63008 +#include "string_ext.h"
63009 +#include "debug_ext.h"
63010 +#include "net_ext.h"
63011 +
63012 +#include "fm_vsp_ext.h"
63013 +#include "fm_sp.h"
63014 +#include "fm_common.h"
63015 +#include "fsl_fman_sp.h"
63016 +
63017 +
63018 +#if (DPAA_VERSION >= 11)
63019 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
63020 +{
63021 + t_Error err = E_OK;
63022 +
63023 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
63024 + RETURN_ERROR(MAJOR, err, NO_MSG);
63025 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
63026 + RETURN_ERROR(MAJOR, err, NO_MSG);
63027 + return err;
63028 +
63029 +}
63030 +
63031 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
63032 +{
63033 + t_Error err = E_OK;
63034 +
63035 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63036 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63037 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
63038 +
63039 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
63040 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
63041 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
63042 +
63043 + RETURN_ERROR(MAJOR, err, NO_MSG);
63044 +
63045 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
63046 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
63047 +
63048 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
63049 + p_FmVspEntry->portType,
63050 + p_FmVspEntry->portId,
63051 + p_FmVspEntry->relativeProfileId);
63052 +
63053 + return err;
63054 +}
63055 +#endif /* (DPAA_VERSION >= 11) */
63056 +
63057 +
63058 +/*****************************************************************************/
63059 +/* Inter-module API routines */
63060 +/*****************************************************************************/
63061 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
63062 + uint8_t *orderedArray,
63063 + uint16_t *sizesArray)
63064 +{
63065 + uint16_t bufSize = 0;
63066 + int i=0, j=0, k=0;
63067 +
63068 + /* First we copy the external buffers pools information to an ordered local array */
63069 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63070 + {
63071 + /* get pool size */
63072 + bufSize = p_FmExtPools->extBufPool[i].size;
63073 +
63074 + /* keep sizes in an array according to poolId for direct access */
63075 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
63076 +
63077 + /* save poolId in an ordered array according to size */
63078 + for (j=0;j<=i;j++)
63079 + {
63080 + /* this is the next free place in the array */
63081 + if (j==i)
63082 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
63083 + else
63084 + {
63085 + /* find the right place for this poolId */
63086 + if (bufSize < sizesArray[orderedArray[j]])
63087 + {
63088 + /* move the poolIds one place ahead to make room for this poolId */
63089 + for (k=i;k>j;k--)
63090 + orderedArray[k] = orderedArray[k-1];
63091 +
63092 + /* now k==j, this is the place for the new size */
63093 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
63094 + break;
63095 + }
63096 + }
63097 + }
63098 + }
63099 +}
63100 +
63101 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
63102 + t_FmBackupBmPools *p_FmBackupBmPools,
63103 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
63104 +{
63105 +
63106 + int i = 0, j = 0;
63107 + bool found;
63108 + uint8_t count = 0;
63109 +
63110 + if (p_FmExtPools)
63111 + {
63112 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
63113 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63114 +
63115 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63116 + {
63117 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
63118 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
63119 + if (!p_FmExtPools->extBufPool[i].size)
63120 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
63121 + }
63122 + }
63123 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
63124 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
63125 +
63126 + /* backup BM pools indication is valid only for some chip derivatives
63127 + (limited by the config routine) */
63128 + if (p_FmBackupBmPools)
63129 + {
63130 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
63131 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
63132 + found = FALSE;
63133 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
63134 + {
63135 +
63136 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63137 + {
63138 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
63139 + {
63140 + found = TRUE;
63141 + break;
63142 + }
63143 + }
63144 + if (!found)
63145 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
63146 + else
63147 + found = FALSE;
63148 + }
63149 + }
63150 +
63151 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
63152 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
63153 + {
63154 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
63155 + 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));
63156 +
63157 + if (!p_FmBufPoolDepletion->numOfPools)
63158 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
63159 +
63160 + found = FALSE;
63161 + count = 0;
63162 + /* for each pool that is in poolsToConsider, check if it is defined
63163 + in extBufPool */
63164 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63165 + {
63166 + if (p_FmBufPoolDepletion->poolsToConsider[i])
63167 + {
63168 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63169 + {
63170 + if (i == p_FmExtPools->extBufPool[j].id)
63171 + {
63172 + found = TRUE;
63173 + count++;
63174 + break;
63175 + }
63176 + }
63177 + if (!found)
63178 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63179 + else
63180 + found = FALSE;
63181 + }
63182 + }
63183 + /* check that the number of pools that we have checked is equal to the number announced by the user */
63184 + if (count != p_FmBufPoolDepletion->numOfPools)
63185 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
63186 + }
63187 +
63188 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
63189 + {
63190 + /* calculate vector for number of pools depletion */
63191 + found = FALSE;
63192 + count = 0;
63193 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63194 + {
63195 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
63196 + {
63197 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63198 + {
63199 + if (i == p_FmExtPools->extBufPool[j].id)
63200 + {
63201 + found = TRUE;
63202 + count++;
63203 + break;
63204 + }
63205 + }
63206 + if (!found)
63207 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63208 + else
63209 + found = FALSE;
63210 + }
63211 + }
63212 + if (!count)
63213 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
63214 + }
63215 +
63216 + return E_OK;
63217 +}
63218 +
63219 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
63220 +{
63221 + /* Check that divisible by 16 and not larger than 240 */
63222 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
63223 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
63224 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
63225 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
63226 +
63227 + /* check that ic size+ic internal offset, does not exceed ic block size */
63228 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
63229 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
63230 + /* Check that divisible by 16 and not larger than 256 */
63231 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
63232 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
63233 +
63234 + /* Check that divisible by 16 and not larger than 4K */
63235 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
63236 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
63237 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
63238 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
63239 +
63240 + return E_OK;
63241 +}
63242 +
63243 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
63244 +{
63245 + /* Check the margin definition */
63246 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
63247 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63248 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
63249 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63250 +
63251 + return E_OK;
63252 +}
63253 +
63254 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
63255 + t_FmBufferPrefixContent *p_BufferPrefixContent,
63256 + t_FmSpBufMargins *p_FmSpBufMargins,
63257 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
63258 + uint8_t *internalBufferOffset)
63259 +{
63260 + uint32_t tmp;
63261 +
63262 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
63263 + ASSERT_COND(p_FmSpIntContextDataCopy);
63264 + ASSERT_COND(p_BufferPrefixContent);
63265 + ASSERT_COND(p_FmSpBufMargins);
63266 + ASSERT_COND(p_FmSpBufferOffsets);
63267 +
63268 + /* Align start of internal context data to 16 byte */
63269 + p_FmSpIntContextDataCopy->extBufOffset =
63270 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
63271 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
63272 + p_BufferPrefixContent->privDataSize);
63273 +
63274 + /* Translate margin and intContext params to FM parameters */
63275 + /* Initialize with illegal value. Later we'll set legal values. */
63276 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
63277 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
63278 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
63279 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
63280 +
63281 + /* Internally the driver supports 4 options
63282 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
63283 + relate to it as 1).
63284 + 2. All IC context (from AD) not including debug.*/
63285 +
63286 + /* This 'if' covers option 2. We copy from beginning of context. */
63287 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63288 + {
63289 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
63290 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
63291 + p_FmSpIntContextDataCopy->intContextOffset = 16;
63292 +
63293 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63294 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
63295 + if (p_BufferPrefixContent->passPrsResult)
63296 + p_FmSpBufferOffsets->prsResultOffset =
63297 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
63298 + if (p_BufferPrefixContent->passTimeStamp)
63299 + p_FmSpBufferOffsets->timeStampOffset =
63300 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
63301 + if (p_BufferPrefixContent->passHashResult)
63302 + p_FmSpBufferOffsets->hashResultOffset =
63303 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
63304 + }
63305 + else
63306 + {
63307 + /* This case covers the options under 1 */
63308 + /* Copy size must be in 16-byte granularity. */
63309 + p_FmSpIntContextDataCopy->size =
63310 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
63311 + ((p_BufferPrefixContent->passTimeStamp ||
63312 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
63313 +
63314 + /* Align start of internal context data to 16 byte */
63315 + p_FmSpIntContextDataCopy->intContextOffset =
63316 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
63317 + ((p_BufferPrefixContent->passTimeStamp ||
63318 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
63319 +
63320 + if (p_BufferPrefixContent->passPrsResult)
63321 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
63322 + if (p_BufferPrefixContent->passTimeStamp)
63323 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
63324 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
63325 + p_FmSpIntContextDataCopy->extBufOffset;
63326 + if (p_BufferPrefixContent->passHashResult)
63327 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
63328 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
63329 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
63330 + p_FmSpIntContextDataCopy->extBufOffset + 8;
63331 + }
63332 +
63333 + if (p_FmSpIntContextDataCopy->size)
63334 + p_FmSpBufMargins->startMargins =
63335 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
63336 + p_FmSpIntContextDataCopy->size);
63337 + else
63338 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
63339 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
63340 +
63341 + /* save extra space for manip in both external and internal buffers */
63342 + if (p_BufferPrefixContent->manipExtraSpace)
63343 + {
63344 + uint8_t extraSpace;
63345 +#ifdef FM_CAPWAP_SUPPORT
63346 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
63347 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63348 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
63349 + 256-CAPWAP_FRAG_EXTRA_SPACE));
63350 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
63351 +#else
63352 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
63353 +#endif /* FM_CAPWAP_SUPPORT */
63354 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
63355 + p_FmSpBufMargins->startMargins += extraSpace;
63356 + *internalBufferOffset = extraSpace;
63357 + }
63358 +
63359 + /* align data start */
63360 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
63361 + if (tmp)
63362 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
63363 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
63364 +
63365 + return E_OK;
63366 +}
63367 +/*********************** End of inter-module routines ************************/
63368 +
63369 +
63370 +#if (DPAA_VERSION >= 11)
63371 +/*****************************************************************************/
63372 +/* API routines */
63373 +/*****************************************************************************/
63374 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
63375 +{
63376 + t_FmVspEntry *p_FmVspEntry = NULL;
63377 + struct fm_storage_profile_params fm_vsp_params;
63378 +
63379 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
63380 + if (!p_FmVspEntry)
63381 + {
63382 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63383 + return NULL;
63384 + }
63385 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
63386 +
63387 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
63388 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
63389 + {
63390 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63391 + XX_Free(p_FmVspEntry);
63392 + return NULL;
63393 + }
63394 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
63395 + fman_vsp_defconfig(&fm_vsp_params);
63396 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
63397 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
63398 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
63399 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
63400 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
63401 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
63402 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
63403 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
63404 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63405 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
63406 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63407 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63408 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
63409 +
63410 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
63411 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
63412 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
63413 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
63414 +
63415 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
63416 +
63417 + return p_FmVspEntry;
63418 +}
63419 +
63420 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
63421 +{
63422 +
63423 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63424 + struct fm_storage_profile_params fm_vsp_params;
63425 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
63426 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
63427 + t_Error err;
63428 + uint16_t absoluteProfileId = 0;
63429 + int i = 0;
63430 +
63431 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63432 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
63433 +
63434 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
63435 +
63436 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
63437 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
63438 +
63439 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
63440 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
63441 + &p_FmVspEntry->bufMargins,
63442 + &p_FmVspEntry->bufferOffsets,
63443 + &p_FmVspEntry->internalBufferOffset);
63444 + if (err != E_OK)
63445 + RETURN_ERROR(MAJOR, err, NO_MSG);
63446 +
63447 +
63448 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
63449 + if (err != E_OK)
63450 + RETURN_ERROR(MAJOR, err, NO_MSG);
63451 +
63452 +
63453 + p_FmVspEntry->p_FmSpRegsBase =
63454 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
63455 + if (!p_FmVspEntry->p_FmSpRegsBase)
63456 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
63457 +
63458 + /* order external buffer pools in ascending order of buffer pools sizes */
63459 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
63460 + orderedArray,
63461 + sizesArray);
63462 +
63463 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
63464 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
63465 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
63466 + {
63467 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
63468 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
63469 + }
63470 +
63471 + /* on user responsibility to fill it according requirement */
63472 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
63473 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
63474 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
63475 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
63476 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
63477 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
63478 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
63479 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
63480 +
63481 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63482 + {
63483 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
63484 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
63485 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
63486 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
63487 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
63488 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
63489 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
63490 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
63491 + }
63492 + else
63493 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
63494 +
63495 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63496 + {
63497 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
63498 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
63499 + }
63500 + else
63501 + fm_vsp_params.backup_pools.num_backup_pools = 0;
63502 +
63503 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
63504 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
63505 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
63506 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
63507 +
63508 + /* no check on err - it was checked earlier */
63509 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
63510 + p_FmVspEntry->portType,
63511 + p_FmVspEntry->portId,
63512 + p_FmVspEntry->relativeProfileId,
63513 + &absoluteProfileId);
63514 +
63515 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
63516 + ASSERT_COND(fm_vsp_params.int_context);
63517 + ASSERT_COND(fm_vsp_params.buf_margins);
63518 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
63519 +
63520 + /* Set all registers related to VSP */
63521 + 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);
63522 +
63523 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
63524 +
63525 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
63526 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
63527 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
63528 +
63529 + return E_OK;
63530 +}
63531 +
63532 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
63533 +{
63534 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63535 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63536 + XX_Free(p_FmVspEntry);
63537 + return E_OK;
63538 +}
63539 +
63540 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
63541 +{
63542 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63543 +
63544 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63545 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63546 +
63547 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
63548 + /* if dataAlign was not initialized by user, we return to driver's default */
63549 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
63550 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63551 +
63552 + return E_OK;
63553 +}
63554 +
63555 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
63556 +{
63557 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63558 +
63559 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63560 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63561 +
63562 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
63563 +
63564 + return E_OK;
63565 +}
63566 +
63567 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
63568 +{
63569 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63570 +
63571 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63572 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63573 +
63574 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
63575 +
63576 + return E_OK;
63577 +}
63578 +
63579 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
63580 +{
63581 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63582 +
63583 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63584 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63585 +
63586 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
63587 +
63588 + return E_OK;
63589 +}
63590 +
63591 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
63592 +{
63593 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63594 +
63595 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63596 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63597 +
63598 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
63599 +
63600 + return E_OK;
63601 +}
63602 +
63603 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
63604 +{
63605 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63606 +
63607 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63608 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63609 +
63610 +
63611 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
63612 +
63613 + return E_OK;
63614 +}
63615 +
63616 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
63617 +{
63618 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63619 +
63620 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63621 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63622 +
63623 +
63624 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
63625 +
63626 + return E_OK;
63627 +}
63628 +
63629 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
63630 +{
63631 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63632 +
63633 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63634 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63635 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
63636 +
63637 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
63638 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63639 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
63640 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
63641 +
63642 + return E_OK;
63643 +}
63644 +
63645 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
63646 +{
63647 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63648 +
63649 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63650 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63651 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
63652 +
63653 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
63654 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63655 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
63656 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
63657 +
63658 + return E_OK;
63659 +}
63660 +
63661 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
63662 +{
63663 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63664 +
63665 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
63666 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
63667 +
63668 + return p_FmVspEntry->bufferOffsets.dataOffset;
63669 +}
63670 +
63671 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
63672 +{
63673 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63674 +
63675 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63676 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63677 +
63678 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
63679 + return NULL;
63680 +
63681 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
63682 +}
63683 +
63684 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
63685 +{
63686 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63687 +
63688 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63689 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63690 +
63691 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
63692 + return NULL;
63693 +
63694 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
63695 +}
63696 +
63697 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
63698 +{
63699 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63700 +
63701 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63702 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63703 +
63704 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
63705 + return NULL;
63706 +
63707 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
63708 +}
63709 +
63710 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
63711 +{
63712 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63713 +
63714 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
63715 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
63716 +
63717 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
63718 + return NULL;
63719 +
63720 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
63721 +}
63722 +
63723 +#endif /* (DPAA_VERSION >= 11) */
63724 --- /dev/null
63725 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
63726 @@ -0,0 +1,85 @@
63727 +/*
63728 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63729 + *
63730 + * Redistribution and use in source and binary forms, with or without
63731 + * modification, are permitted provided that the following conditions are met:
63732 + * * Redistributions of source code must retain the above copyright
63733 + * notice, this list of conditions and the following disclaimer.
63734 + * * Redistributions in binary form must reproduce the above copyright
63735 + * notice, this list of conditions and the following disclaimer in the
63736 + * documentation and/or other materials provided with the distribution.
63737 + * * Neither the name of Freescale Semiconductor nor the
63738 + * names of its contributors may be used to endorse or promote products
63739 + * derived from this software without specific prior written permission.
63740 + *
63741 + *
63742 + * ALTERNATIVELY, this software may be distributed under the terms of the
63743 + * GNU General Public License ("GPL") as published by the Free Software
63744 + * Foundation, either version 2 of that License or (at your option) any
63745 + * later version.
63746 + *
63747 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63748 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63749 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63750 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63751 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63752 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63753 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63754 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63755 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63756 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63757 + */
63758 +
63759 +
63760 +/******************************************************************************
63761 + @File fm_sp.h
63762 +
63763 + @Description FM SP ...
63764 +*//***************************************************************************/
63765 +#ifndef __FM_SP_H
63766 +#define __FM_SP_H
63767 +
63768 +#include "std_ext.h"
63769 +#include "error_ext.h"
63770 +#include "list_ext.h"
63771 +
63772 +#include "fm_sp_common.h"
63773 +#include "fm_common.h"
63774 +
63775 +
63776 +#define __ERR_MODULE__ MODULE_FM_SP
63777 +
63778 +typedef struct {
63779 + t_FmBufferPrefixContent bufferPrefixContent;
63780 + e_FmDmaSwapOption dmaSwapData;
63781 + e_FmDmaCacheOption dmaIntContextCacheAttr;
63782 + e_FmDmaCacheOption dmaHeaderCacheAttr;
63783 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
63784 + bool dmaWriteOptimize;
63785 + uint16_t liodnOffset;
63786 + bool noScatherGather;
63787 + t_FmBufPoolDepletion *p_BufPoolDepletion;
63788 + t_FmBackupBmPools *p_BackupBmPools;
63789 + t_FmExtPools extBufPools;
63790 +} t_FmVspEntryDriverParams;
63791 +
63792 +typedef struct {
63793 + bool valid;
63794 + volatile bool lock;
63795 + uint8_t pointedOwners;
63796 + uint16_t absoluteSpId;
63797 + uint8_t internalBufferOffset;
63798 + t_FmSpBufMargins bufMargins;
63799 + t_FmSpIntContextDataCopy intContext;
63800 + t_FmSpBufferOffsets bufferOffsets;
63801 + t_Handle h_Fm;
63802 + e_FmPortType portType; /**< Port type */
63803 + uint8_t portId; /**< Port Id - relative to type */
63804 + uint8_t relativeProfileId;
63805 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
63806 + t_FmExtPools extBufPools;
63807 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
63808 +} t_FmVspEntry;
63809 +
63810 +
63811 +#endif /* __FM_SP_H */
63812 --- /dev/null
63813 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
63814 @@ -0,0 +1,197 @@
63815 +/*
63816 + * Copyright 2013 Freescale Semiconductor Inc.
63817 + *
63818 + * Redistribution and use in source and binary forms, with or without
63819 + * modification, are permitted provided that the following conditions are met:
63820 + * * Redistributions of source code must retain the above copyright
63821 + * notice, this list of conditions and the following disclaimer.
63822 + * * Redistributions in binary form must reproduce the above copyright
63823 + * notice, this list of conditions and the following disclaimer in the
63824 + * documentation and/or other materials provided with the distribution.
63825 + * * Neither the name of Freescale Semiconductor nor the
63826 + * names of its contributors may be used to endorse or promote products
63827 + * derived from this software without specific prior written permission.
63828 + *
63829 + *
63830 + * ALTERNATIVELY, this software may be distributed under the terms of the
63831 + * GNU General Public License ("GPL") as published by the Free Software
63832 + * Foundation, either version 2 of that License or (at your option) any
63833 + * later version.
63834 + *
63835 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63836 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63837 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63838 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63839 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63840 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63841 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63842 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63843 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63844 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63845 + */
63846 +
63847 +#include "fsl_fman_sp.h"
63848 +
63849 +
63850 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
63851 + uint16_t index)
63852 +{
63853 + struct fm_pcd_storage_profile_regs *sp_regs;
63854 + sp_regs = &regs[index];
63855 + return ioread32be(&sp_regs->fm_sp_acnt);
63856 +}
63857 +
63858 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
63859 + uint16_t index, uint32_t value)
63860 +{
63861 + struct fm_pcd_storage_profile_regs *sp_regs;
63862 + sp_regs = &regs[index];
63863 + iowrite32be(value, &sp_regs->fm_sp_acnt);
63864 +}
63865 +
63866 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
63867 +{
63868 + cfg->dma_swap_data =
63869 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
63870 + cfg->int_context_cache_attr =
63871 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
63872 + cfg->header_cache_attr =
63873 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
63874 + cfg->scatter_gather_cache_attr =
63875 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
63876 + cfg->dma_write_optimize =
63877 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
63878 + cfg->no_scather_gather =
63879 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
63880 +}
63881 +
63882 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
63883 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
63884 +{
63885 + int i, j;
63886 + uint32_t vector = 0;
63887 + for (i = 0; i < max_pools; i++)
63888 + if (pools[i])
63889 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
63890 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
63891 + vector |= mask >> j;
63892 + break;
63893 + }
63894 + return vector;
63895 +}
63896 +
63897 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
63898 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
63899 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
63900 + int max_num_of_pfc_priorities)
63901 +{
63902 + int i = 0, j = 0;
63903 + struct fm_pcd_storage_profile_regs *sp_regs;
63904 + uint32_t tmp_reg, vector;
63905 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
63906 + struct fman_buf_pool_depletion *buf_pool_depletion =
63907 + &fm_vsp_params->buf_pool_depletion;
63908 + struct fman_backup_bm_pools *backup_pools =
63909 + &fm_vsp_params->backup_pools;
63910 + struct fman_sp_int_context_data_copy *int_context_data_copy =
63911 + fm_vsp_params->int_context;
63912 + struct fman_sp_buf_margins *external_buffer_margins =
63913 + fm_vsp_params->buf_margins;
63914 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
63915 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
63916 +
63917 + sp_regs = &regs[index];
63918 +
63919 + /* fill external buffers manager pool information register*/
63920 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
63921 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
63922 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
63923 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
63924 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
63925 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
63926 + /* functionality available only for some deriviatives
63927 + (limited by config) */
63928 + for (j = 0; j < backup_pools->num_backup_pools; j++)
63929 + if (ext_buf_pools->ext_buf_pool[i].id ==
63930 + backup_pools->pool_ids[j]) {
63931 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
63932 + break;
63933 + }
63934 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
63935 + }
63936 +
63937 + /* clear unused pools */
63938 + for (i = ext_buf_pools->num_pools_used;
63939 + i < port_max_num_of_ext_pools; i++)
63940 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
63941 +
63942 + /* fill pool depletion register*/
63943 + tmp_reg = 0;
63944 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
63945 + /* calculate vector for number of pools depletion */
63946 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
63947 + pools_to_consider, ext_buf_pools, 0x80000000);
63948 +
63949 + /* configure num of pools and vector for number of pools mode */
63950 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
63951 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
63952 + tmp_reg |= vector;
63953 + }
63954 +
63955 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
63956 + /* calculate vector for number of pools depletion */
63957 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
63958 + pools_to_consider_for_single_mode,
63959 + ext_buf_pools, 0x00000080);
63960 +
63961 + /* configure num of pools and vector for number of pools mode */
63962 + tmp_reg |= vector;
63963 + }
63964 +
63965 + /* fill QbbPEV */
63966 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
63967 + vector = 0;
63968 + for (i = 0; i < max_num_of_pfc_priorities; i++)
63969 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
63970 + vector |= 0x00000100 << i;
63971 + tmp_reg |= vector;
63972 + }
63973 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
63974 +
63975 + /* fill dma attributes register */
63976 + tmp_reg = 0;
63977 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
63978 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
63979 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
63980 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
63981 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
63982 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
63983 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
63984 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
63985 + if (fm_vsp_params->dma_write_optimize)
63986 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
63987 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
63988 +
63989 + /* IC parameters - fill internal context parameters register */
63990 + tmp_reg = 0;
63991 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
63992 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
63993 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
63994 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
63995 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
63996 + FMAN_SP_IC_SIZE_SHIFT);
63997 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
63998 +
63999 + /* buffer margins - fill external buffer margins register */
64000 + tmp_reg = 0;
64001 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
64002 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
64003 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
64004 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
64005 + if (no_scather_gather)
64006 + tmp_reg |= FMAN_SP_SG_DISABLE;
64007 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
64008 +
64009 + /* buffer margins - fill spliodn register */
64010 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
64011 +}
64012 --- /dev/null
64013 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64014 @@ -0,0 +1,5216 @@
64015 +/*
64016 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64017 + *
64018 + * Redistribution and use in source and binary forms, with or without
64019 + * modification, are permitted provided that the following conditions are met:
64020 + * * Redistributions of source code must retain the above copyright
64021 + * notice, this list of conditions and the following disclaimer.
64022 + * * Redistributions in binary form must reproduce the above copyright
64023 + * notice, this list of conditions and the following disclaimer in the
64024 + * documentation and/or other materials provided with the distribution.
64025 + * * Neither the name of Freescale Semiconductor nor the
64026 + * names of its contributors may be used to endorse or promote products
64027 + * derived from this software without specific prior written permission.
64028 + *
64029 + *
64030 + * ALTERNATIVELY, this software may be distributed under the terms of the
64031 + * GNU General Public License ("GPL") as published by the Free Software
64032 + * Foundation, either version 2 of that License or (at your option) any
64033 + * later version.
64034 + *
64035 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64036 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64037 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64038 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64039 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64040 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64041 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64042 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64043 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64044 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64045 + */
64046 +
64047 +
64048 +/******************************************************************************
64049 + @File fm.c
64050 +
64051 + @Description FM driver routines implementation.
64052 +*//***************************************************************************/
64053 +#include "std_ext.h"
64054 +#include "error_ext.h"
64055 +#include "xx_ext.h"
64056 +#include "string_ext.h"
64057 +#include "sprint_ext.h"
64058 +#include "debug_ext.h"
64059 +#include "fm_muram_ext.h"
64060 +#include <linux/math64.h>
64061 +
64062 +#include "fm_common.h"
64063 +#include "fm_ipc.h"
64064 +#include "fm.h"
64065 +#ifndef CONFIG_FMAN_ARM
64066 +#include <linux/fsl/svr.h>
64067 +#endif
64068 +#include "fsl_fman.h"
64069 +
64070 +
64071 +/****************************************/
64072 +/* static functions */
64073 +/****************************************/
64074 +
64075 +static volatile bool blockingFlag = FALSE;
64076 +static void IpcMsgCompletionCB(t_Handle h_Fm,
64077 + uint8_t *p_Msg,
64078 + uint8_t *p_Reply,
64079 + uint32_t replyLength,
64080 + t_Error status)
64081 +{
64082 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
64083 + blockingFlag = FALSE;
64084 +}
64085 +
64086 +static void FreeInitResources(t_Fm *p_Fm)
64087 +{
64088 + if (p_Fm->camBaseAddr)
64089 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
64090 + if (p_Fm->fifoBaseAddr)
64091 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
64092 + if (p_Fm->resAddr)
64093 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
64094 +}
64095 +
64096 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
64097 +{
64098 + t_FMIramRegs *p_Iram;
64099 +
64100 + ASSERT_COND(p_Fm);
64101 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64102 +
64103 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
64104 +}
64105 +
64106 +static t_Error CheckFmParameters(t_Fm *p_Fm)
64107 +{
64108 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
64109 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
64110 +#if (DPAA_VERSION < 11)
64111 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
64112 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
64113 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64114 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
64115 +#endif /* (DPAA_VERSION < 11) */
64116 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
64117 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
64118 +// 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))
64119 +// 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));
64120 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
64121 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64122 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
64123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64124 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
64125 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
64126 +#if (DPAA_VERSION < 11)
64127 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64128 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64129 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64130 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64131 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
64132 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
64133 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64134 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64135 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64136 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64137 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
64138 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
64139 +#else /* (DPAA_VERSION >= 11) */
64140 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
64141 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
64142 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
64143 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
64144 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
64145 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
64146 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
64147 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
64148 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
64149 +#ifdef FM_AID_MODE_NO_TNUM_SW005
64150 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
64151 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
64152 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
64153 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
64154 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
64155 +#endif /* (DPAA_VERSION < 11) */
64156 +
64157 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
64158 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
64159 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
64160 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64161 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
64162 +
64163 +#if (DPAA_VERSION >= 11)
64164 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
64165 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
64166 +#endif /* (DPAA_VERSION >= 11) */
64167 +
64168 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
64169 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
64170 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
64171 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
64172 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64173 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
64174 + p_Fm->p_FmStateStruct->totalFifoSize,
64175 + BMI_MAX_FIFO_SIZE));
64176 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
64177 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
64178 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
64179 +
64180 +#ifdef FM_HAS_TOTAL_DMAS
64181 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
64182 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
64183 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
64184 +#endif /* FM_HAS_TOTAL_DMAS */
64185 +
64186 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
64187 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
64188 +
64189 + if (!p_Fm->f_Exception)
64190 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64191 + if (!p_Fm->f_BusError)
64192 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64193 +
64194 +#ifdef FM_NO_WATCHDOG
64195 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
64196 + (p_Fm->p_FmDriverParam->dma_watchdog))
64197 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
64198 +#endif /* FM_NO_WATCHDOG */
64199 +
64200 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
64201 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
64202 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
64203 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
64204 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
64205 +
64206 +#ifdef FM_NO_TNUM_AGING
64207 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64208 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64209 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
64210 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
64211 +#endif /* FM_NO_TNUM_AGING */
64212 +
64213 + /* check that user did not set revision-dependent exceptions */
64214 +#ifdef FM_NO_DISPATCH_RAM_ECC
64215 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64216 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64217 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
64218 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
64219 +#endif /* FM_NO_DISPATCH_RAM_ECC */
64220 +
64221 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
64222 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
64223 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
64224 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
64225 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
64226 +
64227 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
64228 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
64229 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
64230 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
64231 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
64232 +
64233 + return E_OK;
64234 +}
64235 +
64236 +
64237 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
64238 +{
64239 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
64240 +
64241 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
64242 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
64243 +
64244 + /* If the MAC is running on guest-partition and we have IPC session with it,
64245 + we inform him about the event through IPC; otherwise, we ignore the event. */
64246 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
64247 + {
64248 + t_Error err;
64249 + t_FmIpcIsr fmIpcIsr;
64250 + t_FmIpcMsg msg;
64251 +
64252 + memset(&msg, 0, sizeof(msg));
64253 + msg.msgId = FM_GUEST_ISR;
64254 + fmIpcIsr.pendingReg = pendingReg;
64255 + fmIpcIsr.boolErr = FALSE;
64256 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
64257 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
64258 + (uint8_t*)&msg,
64259 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
64260 + NULL,
64261 + NULL,
64262 + NULL,
64263 + NULL);
64264 + if (err != E_OK)
64265 + REPORT_ERROR(MINOR, err, NO_MSG);
64266 + }
64267 + else
64268 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
64269 +}
64270 +
64271 +static void BmiErrEvent(t_Fm *p_Fm)
64272 +{
64273 + uint32_t event;
64274 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
64275 +
64276 +
64277 + event = fman_get_bmi_err_event(bmi_rg);
64278 +
64279 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
64280 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
64281 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
64282 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
64283 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
64284 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
64285 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
64286 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
64287 +}
64288 +
64289 +static void QmiErrEvent(t_Fm *p_Fm)
64290 +{
64291 + uint32_t event;
64292 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64293 +
64294 + event = fman_get_qmi_err_event(qmi_rg);
64295 +
64296 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
64297 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
64298 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
64299 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
64300 +}
64301 +
64302 +static void DmaErrEvent(t_Fm *p_Fm)
64303 +{
64304 + uint32_t status, com_id;
64305 + uint8_t tnum;
64306 + uint8_t hardwarePortId;
64307 + uint8_t relativePortId;
64308 + uint16_t liodn;
64309 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
64310 +
64311 + status = fman_get_dma_err_event(dma_rg);
64312 +
64313 + if (status & DMA_STATUS_BUS_ERR)
64314 + {
64315 + com_id = fman_get_dma_com_id(dma_rg);
64316 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
64317 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64318 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
64319 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
64320 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
64321 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
64322 + p_Fm->f_BusError(p_Fm->h_App,
64323 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
64324 + relativePortId,
64325 + fman_get_dma_addr(dma_rg),
64326 + tnum,
64327 + liodn);
64328 + }
64329 + if (status & DMA_STATUS_FM_SPDAT_ECC)
64330 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
64331 + if (status & DMA_STATUS_READ_ECC)
64332 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
64333 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
64334 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
64335 + if (status & DMA_STATUS_FM_WRITE_ECC)
64336 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
64337 + }
64338 +
64339 +static void FpmErrEvent(t_Fm *p_Fm)
64340 +{
64341 + uint32_t event;
64342 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64343 +
64344 + event = fman_get_fpm_err_event(fpm_rg);
64345 +
64346 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
64347 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
64348 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
64349 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
64350 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
64351 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
64352 +}
64353 +
64354 +static void MuramErrIntr(t_Fm *p_Fm)
64355 +{
64356 + uint32_t event;
64357 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64358 +
64359 + event = fman_get_muram_err_event(fpm_rg);
64360 +
64361 + if (event & FPM_RAM_MURAM_ECC)
64362 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
64363 +}
64364 +
64365 +static void IramErrIntr(t_Fm *p_Fm)
64366 +{
64367 + uint32_t event;
64368 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64369 +
64370 + event = fman_get_iram_err_event(fpm_rg);
64371 +
64372 + if (event & FPM_RAM_IRAM_ECC)
64373 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
64374 +}
64375 +
64376 +static void QmiEvent(t_Fm *p_Fm)
64377 +{
64378 + uint32_t event;
64379 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64380 +
64381 + event = fman_get_qmi_event(qmi_rg);
64382 +
64383 + if (event & QMI_INTR_EN_SINGLE_ECC)
64384 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
64385 +}
64386 +
64387 +static void UnimplementedIsr(t_Handle h_Arg)
64388 +{
64389 + UNUSED(h_Arg);
64390 +
64391 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
64392 +}
64393 +
64394 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
64395 +{
64396 + UNUSED(h_Arg); UNUSED(event);
64397 +
64398 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
64399 +}
64400 +
64401 +static void EnableTimeStamp(t_Fm *p_Fm)
64402 +{
64403 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64404 +
64405 + ASSERT_COND(p_Fm->p_FmStateStruct);
64406 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
64407 +
64408 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
64409 +
64410 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
64411 +}
64412 +
64413 +static t_Error ClearIRam(t_Fm *p_Fm)
64414 +{
64415 + t_FMIramRegs *p_Iram;
64416 + int i;
64417 + int iram_size;
64418 +
64419 + ASSERT_COND(p_Fm);
64420 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64421 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
64422 +
64423 + /* Enable the auto-increment */
64424 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64425 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64426 +
64427 + for (i=0; i < (iram_size/4); i++)
64428 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64429 +
64430 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
64431 + CORE_MemoryBarrier();
64432 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
64433 +
64434 + return E_OK;
64435 +}
64436 +
64437 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
64438 +{
64439 + t_FMIramRegs *p_Iram;
64440 + int i;
64441 + uint32_t tmp;
64442 + uint8_t compTo16;
64443 +
64444 + ASSERT_COND(p_Fm);
64445 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64446 +
64447 + /* Enable the auto-increment */
64448 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64449 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64450 +
64451 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64452 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
64453 +
64454 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
64455 + if (compTo16)
64456 + for (i=0; i < ((16-compTo16) / 4); i++)
64457 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64458 +
64459 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
64460 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
64461 +
64462 + /* verify that writing has completed */
64463 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
64464 +
64465 + if (p_Fm->fwVerify)
64466 + {
64467 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64468 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64469 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64470 + {
64471 + tmp = GET_UINT32(p_Iram->idata);
64472 + if (tmp != p_Fm->firmware.p_Code[i])
64473 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
64474 + ("UCode write error : write 0x%x, read 0x%x",
64475 + p_Fm->firmware.p_Code[i],tmp));
64476 + }
64477 + WRITE_UINT32(p_Iram->iadd, 0x0);
64478 + }
64479 +
64480 + /* Enable patch from IRAM */
64481 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64482 + XX_UDelay(1000);
64483 +
64484 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
64485 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
64486 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
64487 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
64488 +
64489 + return E_OK;
64490 +}
64491 +
64492 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
64493 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
64494 +{
64495 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64496 + uint32_t tmpReg;
64497 + uint32_t savedSpliodn[63];
64498 +
64499 + /* write to IRAM first location the debug instruction */
64500 + WRITE_UINT32(p_Iram->iadd, 0);
64501 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64502 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
64503 +
64504 + WRITE_UINT32(p_Iram->iadd, 0);
64505 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64506 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
64507 +
64508 + /* Enable patch from IRAM */
64509 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64510 + CORE_MemoryBarrier();
64511 + XX_UDelay(100);
64512 + IO2MemCpy32((uint8_t *)savedSpliodn,
64513 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64514 + 63*sizeof(uint32_t));
64515 +
64516 + /* reset FMAN */
64517 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64518 + CORE_MemoryBarrier();
64519 + XX_UDelay(100);
64520 +
64521 + /* verify breakpoint debug status register */
64522 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
64523 + if (!tmpReg)
64524 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
64525 +
64526 + /*************************************/
64527 + /* Load FMan-Controller code to IRAM */
64528 + /*************************************/
64529 + ClearIRam(p_Fm);
64530 + if (p_Fm->firmware.p_Code &&
64531 + (LoadFmanCtrlCode(p_Fm) != E_OK))
64532 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
64533 + XX_UDelay(100);
64534 +
64535 + /* reset FMAN again to start the microcode */
64536 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64537 + CORE_MemoryBarrier();
64538 + XX_UDelay(100);
64539 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64540 + (uint8_t *)savedSpliodn,
64541 + 63*sizeof(uint32_t));
64542 +
64543 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
64544 + {
64545 + fman_resume(p_Fm->p_FmFpmRegs);
64546 + CORE_MemoryBarrier();
64547 + XX_UDelay(100);
64548 + }
64549 +
64550 + return E_OK;
64551 +}
64552 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
64553 +
64554 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
64555 +{
64556 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
64557 +do { \
64558 + 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);\
64559 +} while (0)
64560 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
64561 +do { \
64562 + 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);\
64563 +} while (0)
64564 +
64565 + /* error interrupts */
64566 + if (pending & ERR_INTR_EN_1G_MAC0)
64567 + FM_G_CALL_1G_MAC_ERR_ISR(0);
64568 + if (pending & ERR_INTR_EN_1G_MAC1)
64569 + FM_G_CALL_1G_MAC_ERR_ISR(1);
64570 + if (pending & ERR_INTR_EN_1G_MAC2)
64571 + FM_G_CALL_1G_MAC_ERR_ISR(2);
64572 + if (pending & ERR_INTR_EN_1G_MAC3)
64573 + FM_G_CALL_1G_MAC_ERR_ISR(3);
64574 + if (pending & ERR_INTR_EN_1G_MAC4)
64575 + FM_G_CALL_1G_MAC_ERR_ISR(4);
64576 + if (pending & ERR_INTR_EN_1G_MAC5)
64577 + FM_G_CALL_1G_MAC_ERR_ISR(5);
64578 + if (pending & ERR_INTR_EN_1G_MAC6)
64579 + FM_G_CALL_1G_MAC_ERR_ISR(6);
64580 + if (pending & ERR_INTR_EN_1G_MAC7)
64581 + FM_G_CALL_1G_MAC_ERR_ISR(7);
64582 + if (pending & ERR_INTR_EN_10G_MAC0)
64583 + FM_G_CALL_10G_MAC_ERR_ISR(0);
64584 + if (pending & ERR_INTR_EN_10G_MAC1)
64585 + FM_G_CALL_10G_MAC_ERR_ISR(1);
64586 +}
64587 +
64588 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
64589 +{
64590 +#define FM_G_CALL_1G_MAC_ISR(_id) \
64591 +do { \
64592 + 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);\
64593 +} while (0)
64594 +#define FM_G_CALL_10G_MAC_ISR(_id) \
64595 +do { \
64596 + 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);\
64597 +} while (0)
64598 +
64599 + if (pending & INTR_EN_1G_MAC0)
64600 + FM_G_CALL_1G_MAC_ISR(0);
64601 + if (pending & INTR_EN_1G_MAC1)
64602 + FM_G_CALL_1G_MAC_ISR(1);
64603 + if (pending & INTR_EN_1G_MAC2)
64604 + FM_G_CALL_1G_MAC_ISR(2);
64605 + if (pending & INTR_EN_1G_MAC3)
64606 + FM_G_CALL_1G_MAC_ISR(3);
64607 + if (pending & INTR_EN_1G_MAC4)
64608 + FM_G_CALL_1G_MAC_ISR(4);
64609 + if (pending & INTR_EN_1G_MAC5)
64610 + FM_G_CALL_1G_MAC_ISR(5);
64611 + if (pending & INTR_EN_1G_MAC6)
64612 + FM_G_CALL_1G_MAC_ISR(6);
64613 + if (pending & INTR_EN_1G_MAC7)
64614 + FM_G_CALL_1G_MAC_ISR(7);
64615 + if (pending & INTR_EN_10G_MAC0)
64616 + FM_G_CALL_10G_MAC_ISR(0);
64617 + if (pending & INTR_EN_10G_MAC1)
64618 + FM_G_CALL_10G_MAC_ISR(1);
64619 + if (pending & INTR_EN_TMR)
64620 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
64621 +}
64622 +
64623 +#if (DPAA_VERSION >= 11)
64624 +static t_Error SetVSPWindow(t_Handle h_Fm,
64625 + uint8_t hardwarePortId,
64626 + uint8_t baseStorageProfile,
64627 + uint8_t log2NumOfProfiles)
64628 +{
64629 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64630 +
64631 + ASSERT_COND(h_Fm);
64632 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64633 +
64634 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
64635 + !p_Fm->p_FmBmiRegs &&
64636 + p_Fm->h_IpcSessions[0])
64637 + {
64638 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
64639 + t_FmIpcMsg msg;
64640 + t_Error err = E_OK;
64641 +
64642 + memset(&msg, 0, sizeof(msg));
64643 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
64644 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
64645 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
64646 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
64647 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
64648 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
64649 +
64650 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64651 + (uint8_t*)&msg,
64652 + sizeof(msg.msgId),
64653 + NULL,
64654 + NULL,
64655 + NULL,
64656 + NULL);
64657 + if (err != E_OK)
64658 + RETURN_ERROR(MINOR, err, NO_MSG);
64659 + return E_OK;
64660 + }
64661 + else if (!p_Fm->p_FmBmiRegs)
64662 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
64663 + ("Either IPC or 'baseAddress' is required!"));
64664 +
64665 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
64666 + hardwarePortId,
64667 + baseStorageProfile,
64668 + log2NumOfProfiles);
64669 +
64670 + return E_OK;
64671 +}
64672 +
64673 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64674 +{
64675 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64676 + uint8_t profilesFound = 0;
64677 + int i = 0;
64678 + uint32_t intFlags;
64679 +
64680 + if (!numOfProfiles)
64681 + return E_OK;
64682 +
64683 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
64684 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
64685 + return (uint8_t)ILLEGAL_BASE;
64686 +
64687 + if (p_Fm->h_IpcSessions[0])
64688 + {
64689 + t_FmIpcResourceAllocParams ipcAllocParams;
64690 + t_FmIpcMsg msg;
64691 + t_FmIpcReply reply;
64692 + t_Error err;
64693 + uint32_t replyLength;
64694 +
64695 + memset(&msg, 0, sizeof(msg));
64696 + memset(&reply, 0, sizeof(reply));
64697 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64698 + ipcAllocParams.guestId = p_Fm->guestId;
64699 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64700 + ipcAllocParams.base = p_Fm->partVSPBase;
64701 + msg.msgId = FM_VSP_ALLOC;
64702 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64703 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64704 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64705 + (uint8_t*)&msg,
64706 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64707 + (uint8_t*)&reply,
64708 + &replyLength,
64709 + NULL,
64710 + NULL);
64711 + if ((err != E_OK) ||
64712 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
64713 + RETURN_ERROR(MAJOR, err, NO_MSG);
64714 + else
64715 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
64716 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
64717 + RETURN_ERROR(MAJOR, err, NO_MSG);
64718 + }
64719 + if (p_Fm->guestId != NCSW_MASTER_ID)
64720 + {
64721 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
64722 + return (uint8_t)ILLEGAL_BASE;
64723 + }
64724 +
64725 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
64726 + for (i = base; i < base + numOfProfiles; i++)
64727 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
64728 + profilesFound++;
64729 + else
64730 + break;
64731 +
64732 + if (profilesFound == numOfProfiles)
64733 + for (i = base; i<base + numOfProfiles; i++)
64734 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
64735 + else
64736 + {
64737 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
64738 + return (uint8_t)ILLEGAL_BASE;
64739 + }
64740 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
64741 +
64742 + return base;
64743 +}
64744 +
64745 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
64746 +{
64747 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64748 + int i = 0;
64749 +
64750 + ASSERT_COND(p_Fm);
64751 +
64752 + if (p_Fm->h_IpcSessions[0])
64753 + {
64754 + t_FmIpcResourceAllocParams ipcAllocParams;
64755 + t_FmIpcMsg msg;
64756 + t_FmIpcReply reply;
64757 + uint32_t replyLength;
64758 + t_Error err;
64759 +
64760 + memset(&msg, 0, sizeof(msg));
64761 + memset(&reply, 0, sizeof(reply));
64762 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
64763 + ipcAllocParams.guestId = p_Fm->guestId;
64764 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
64765 + ipcAllocParams.base = p_Fm->partVSPBase;
64766 + msg.msgId = FM_VSP_FREE;
64767 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
64768 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
64769 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
64770 + (uint8_t*)&msg,
64771 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
64772 + (uint8_t*)&reply,
64773 + &replyLength,
64774 + NULL,
64775 + NULL);
64776 + if (err != E_OK)
64777 + REPORT_ERROR(MAJOR, err, NO_MSG);
64778 + return;
64779 + }
64780 + if (p_Fm->guestId != NCSW_MASTER_ID)
64781 + {
64782 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
64783 + return;
64784 + }
64785 +
64786 + ASSERT_COND(p_Fm->p_FmSp);
64787 +
64788 + for (i=base; i<numOfProfiles; i++)
64789 + {
64790 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
64791 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
64792 + else
64793 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
64794 + }
64795 +}
64796 +#endif /* (DPAA_VERSION >= 11) */
64797 +
64798 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
64799 + uint8_t *p_Msg,
64800 + uint32_t msgLength,
64801 + uint8_t *p_Reply,
64802 + uint32_t *p_ReplyLength)
64803 +{
64804 + t_Fm *p_Fm = (t_Fm*)h_Fm;
64805 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
64806 +
64807 + UNUSED(p_Reply);
64808 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
64809 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
64810 +
64811 +#ifdef DISABLE_SANITY_CHECKS
64812 + UNUSED(msgLength);
64813 +#endif /* DISABLE_SANITY_CHECKS */
64814 +
64815 + ASSERT_COND(p_Msg);
64816 +
64817 + *p_ReplyLength = 0;
64818 +
64819 + switch (p_IpcMsg->msgId)
64820 + {
64821 + case (FM_GUEST_ISR):
64822 + {
64823 + t_FmIpcIsr ipcIsr;
64824 +
64825 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
64826 + if (ipcIsr.boolErr)
64827 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
64828 + else
64829 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
64830 + break;
64831 + }
64832 + default:
64833 + *p_ReplyLength = 0;
64834 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
64835 + }
64836 + return E_OK;
64837 +}
64838 +
64839 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
64840 + uint8_t *p_Msg,
64841 + uint32_t msgLength,
64842 + uint8_t *p_Reply,
64843 + uint32_t *p_ReplyLength)
64844 +{
64845 + t_Error err;
64846 + t_Fm *p_Fm = (t_Fm*)h_Fm;
64847 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
64848 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
64849 +
64850 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
64851 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
64852 +
64853 +#ifdef DISABLE_SANITY_CHECKS
64854 + UNUSED(msgLength);
64855 +#endif /* DISABLE_SANITY_CHECKS */
64856 +
64857 + ASSERT_COND(p_IpcMsg);
64858 +
64859 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
64860 + *p_ReplyLength = 0;
64861 +
64862 + switch (p_IpcMsg->msgId)
64863 + {
64864 + case (FM_GET_SET_PORT_PARAMS):
64865 + {
64866 + t_FmIpcPortInInitParams ipcInitParams;
64867 + t_FmInterModulePortInitParams initParams;
64868 + t_FmIpcPortOutInitParams ipcOutInitParams;
64869 +
64870 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
64871 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
64872 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
64873 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
64874 + initParams.liodnOffset = ipcInitParams.liodnOffset;
64875 + initParams.numOfTasks = ipcInitParams.numOfTasks;
64876 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
64877 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
64878 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
64879 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
64880 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
64881 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
64882 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
64883 + initParams.liodnBase = ipcInitParams.liodnBase;
64884 +
64885 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
64886 +
64887 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
64888 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
64889 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
64890 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
64891 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
64892 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
64893 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
64894 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
64895 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
64896 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
64897 + break;
64898 + }
64899 + case (FM_SET_SIZE_OF_FIFO):
64900 + {
64901 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
64902 +
64903 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
64904 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
64905 + ipcPortRsrcParams.hardwarePortId,
64906 + &ipcPortRsrcParams.val,
64907 + &ipcPortRsrcParams.extra,
64908 + (bool)ipcPortRsrcParams.boolInitialConfig);
64909 + *p_ReplyLength = sizeof(uint32_t);
64910 + break;
64911 + }
64912 + case (FM_SET_NUM_OF_TASKS):
64913 + {
64914 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
64915 +
64916 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
64917 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
64918 + (uint8_t*)&ipcPortRsrcParams.val,
64919 + (uint8_t*)&ipcPortRsrcParams.extra,
64920 + (bool)ipcPortRsrcParams.boolInitialConfig);
64921 + *p_ReplyLength = sizeof(uint32_t);
64922 + break;
64923 + }
64924 + case (FM_SET_NUM_OF_OPEN_DMAS):
64925 + {
64926 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
64927 +
64928 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
64929 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
64930 + (uint8_t*)&ipcPortRsrcParams.val,
64931 + (uint8_t*)&ipcPortRsrcParams.extra,
64932 + (bool)ipcPortRsrcParams.boolInitialConfig);
64933 + *p_ReplyLength = sizeof(uint32_t);
64934 + break;
64935 + }
64936 + case (FM_RESUME_STALLED_PORT):
64937 + *p_ReplyLength = sizeof(uint32_t);
64938 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
64939 + break;
64940 + case (FM_MASTER_IS_ALIVE):
64941 + {
64942 + uint8_t guestId = p_IpcMsg->msgBody[0];
64943 + /* build the FM master partition IPC address */
64944 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
64945 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
64946 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
64947 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
64948 + if (p_Fm->h_IpcSessions[guestId] == NULL)
64949 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
64950 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
64951 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
64952 + break;
64953 + }
64954 + case (FM_IS_PORT_STALLED):
64955 + {
64956 + bool tmp;
64957 +
64958 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
64959 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
64960 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
64961 + break;
64962 + }
64963 + case (FM_RESET_MAC):
64964 + {
64965 + t_FmIpcMacParams ipcMacParams;
64966 +
64967 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
64968 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
64969 + (e_FmMacType)(ipcMacParams.enumType),
64970 + ipcMacParams.id);
64971 + *p_ReplyLength = sizeof(uint32_t);
64972 + break;
64973 + }
64974 + case (FM_SET_MAC_MAX_FRAME):
64975 + {
64976 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
64977 +
64978 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
64979 + err = FmSetMacMaxFrame(p_Fm,
64980 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
64981 + ipcMacMaxFrameParams.macParams.id,
64982 + ipcMacMaxFrameParams.maxFrameLength);
64983 + if (err != E_OK)
64984 + REPORT_ERROR(MINOR, err, NO_MSG);
64985 + break;
64986 + }
64987 +#if (DPAA_VERSION >= 11)
64988 + case (FM_VSP_ALLOC) :
64989 + {
64990 + t_FmIpcResourceAllocParams ipcAllocParams;
64991 + uint8_t vspBase;
64992 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
64993 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
64994 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
64995 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
64996 + break;
64997 + }
64998 + case (FM_VSP_FREE) :
64999 + {
65000 + t_FmIpcResourceAllocParams ipcAllocParams;
65001 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65002 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65003 + break;
65004 + }
65005 + case (FM_VSP_SET_PORT_WINDOW) :
65006 + {
65007 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
65008 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
65009 + err = SetVSPWindow(h_Fm,
65010 + ipcVspSetPortWindow.hardwarePortId,
65011 + ipcVspSetPortWindow.baseStorageProfile,
65012 + ipcVspSetPortWindow.log2NumOfProfiles);
65013 + return err;
65014 + }
65015 + case (FM_SET_CONG_GRP_PFC_PRIO) :
65016 + {
65017 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65018 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65019 + err = FmSetCongestionGroupPFCpriority(h_Fm,
65020 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
65021 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
65022 + return err;
65023 + }
65024 +#endif /* (DPAA_VERSION >= 11) */
65025 +
65026 + case (FM_FREE_PORT):
65027 + {
65028 + t_FmInterModulePortFreeParams portParams;
65029 + t_FmIpcPortFreeParams ipcPortParams;
65030 +
65031 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
65032 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
65033 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
65034 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
65035 + FmFreePortParams(h_Fm, &portParams);
65036 + break;
65037 + }
65038 + case (FM_REGISTER_INTR):
65039 + {
65040 + t_FmIpcRegisterIntr ipcRegIntr;
65041 +
65042 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
65043 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
65044 + break;
65045 + }
65046 + case (FM_GET_PARAMS):
65047 + {
65048 + t_FmIpcParams ipcParams;
65049 +
65050 + /* Get clock frequency */
65051 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
65052 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
65053 +
65054 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
65055 +
65056 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
65057 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
65058 + break;
65059 + }
65060 + case (FM_GET_FMAN_CTRL_CODE_REV):
65061 + {
65062 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
65063 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
65064 +
65065 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
65066 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
65067 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
65068 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
65069 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
65070 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
65071 + break;
65072 + }
65073 +
65074 + case (FM_DMA_STAT):
65075 + {
65076 + t_FmDmaStatus dmaStatus;
65077 + t_FmIpcDmaStatus ipcDmaStatus;
65078 +
65079 + FM_GetDmaStatus(h_Fm, &dmaStatus);
65080 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
65081 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
65082 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
65083 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
65084 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
65085 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
65086 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
65087 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
65088 + break;
65089 + }
65090 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
65091 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
65092 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65093 + break;
65094 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
65095 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
65096 + break;
65097 + case (FM_GET_TIMESTAMP_SCALE):
65098 + {
65099 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
65100 +
65101 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
65102 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65103 + break;
65104 + }
65105 + case (FM_GET_COUNTER):
65106 + {
65107 + e_FmCounters inCounter;
65108 + uint32_t outCounter;
65109 +
65110 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
65111 + outCounter = FM_GetCounter(h_Fm, inCounter);
65112 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
65113 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65114 + break;
65115 + }
65116 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
65117 + {
65118 + t_FmIpcFmanEvents ipcFmanEvents;
65119 +
65120 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
65121 + FmSetFmanCtrlIntr(h_Fm,
65122 + ipcFmanEvents.eventRegId,
65123 + ipcFmanEvents.enableEvents);
65124 + break;
65125 + }
65126 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
65127 + {
65128 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
65129 +
65130 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
65131 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65132 + break;
65133 + }
65134 + case (FM_GET_PHYS_MURAM_BASE):
65135 + {
65136 + t_FmPhysAddr physAddr;
65137 + t_FmIpcPhysAddr ipcPhysAddr;
65138 +
65139 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
65140 + ipcPhysAddr.high = physAddr.high;
65141 + ipcPhysAddr.low = physAddr.low;
65142 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
65143 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
65144 + break;
65145 + }
65146 + case (FM_ENABLE_RAM_ECC):
65147 + {
65148 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
65149 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
65150 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
65151 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65152 + UNUSED(err);
65153 +#else
65154 + REPORT_ERROR(MINOR, err, NO_MSG);
65155 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65156 + break;
65157 + }
65158 + case (FM_DISABLE_RAM_ECC):
65159 + {
65160 +
65161 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
65162 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
65163 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
65164 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65165 + UNUSED(err);
65166 +#else
65167 + REPORT_ERROR(MINOR, err, NO_MSG);
65168 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65169 + break;
65170 + }
65171 + case (FM_SET_NUM_OF_FMAN_CTRL):
65172 + {
65173 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
65174 +
65175 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
65176 + err = FmSetNumOfRiscsPerPort(h_Fm,
65177 + ipcPortNumOfFmanCtrls.hardwarePortId,
65178 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
65179 + ipcPortNumOfFmanCtrls.orFmanCtrl);
65180 + if (err != E_OK)
65181 + REPORT_ERROR(MINOR, err, NO_MSG);
65182 + break;
65183 + }
65184 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65185 + case (FM_10G_TX_ECC_WA):
65186 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
65187 + *p_ReplyLength = sizeof(uint32_t);
65188 + break;
65189 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65190 + default:
65191 + *p_ReplyLength = 0;
65192 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65193 + }
65194 + return E_OK;
65195 +}
65196 +
65197 +
65198 +/****************************************/
65199 +/* Inter-Module functions */
65200 +/****************************************/
65201 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65202 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
65203 +{
65204 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65205 + t_Error err = E_OK;
65206 + t_FmIpcMsg msg;
65207 + t_FmIpcReply reply;
65208 + uint32_t replyLength;
65209 + uint8_t rxHardwarePortId, txHardwarePortId;
65210 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65211 +
65212 + if (p_Fm->guestId != NCSW_MASTER_ID)
65213 + {
65214 + memset(&msg, 0, sizeof(msg));
65215 + memset(&reply, 0, sizeof(reply));
65216 + msg.msgId = FM_10G_TX_ECC_WA;
65217 + msg.msgBody[0] = macId;
65218 + replyLength = sizeof(uint32_t);
65219 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65220 + (uint8_t*)&msg,
65221 + sizeof(msg.msgId)+sizeof(macId),
65222 + (uint8_t*)&reply,
65223 + &replyLength,
65224 + NULL,
65225 + NULL)) != E_OK)
65226 + RETURN_ERROR(MINOR, err, NO_MSG);
65227 + if (replyLength != sizeof(uint32_t))
65228 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65229 + return (t_Error)(reply.error);
65230 + }
65231 +
65232 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
65233 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
65234 +
65235 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
65236 + macId,
65237 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65238 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65239 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
65240 + macId,
65241 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65242 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65243 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
65244 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
65245 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
65246 + ("MAC should be initialized prior to Rx and Tx ports!"));
65247 +
65248 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
65249 +}
65250 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65251 +
65252 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
65253 +{
65254 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65255 +
65256 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65257 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
65258 +
65259 + return p_Fm->tnumAgingPeriod;
65260 +}
65261 +
65262 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
65263 + uint8_t portNum,
65264 + bool preFetchConfigured)
65265 +{
65266 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65267 +
65268 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65269 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65270 +
65271 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
65272 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
65273 +
65274 + return E_OK;
65275 +}
65276 +
65277 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
65278 + uint8_t portNum,
65279 + bool *p_PortConfigured,
65280 + bool *p_PreFetchConfigured)
65281 +{
65282 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65283 +
65284 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65285 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65286 +
65287 + /* If the prefetch wasn't configured yet (not enable or disabled)
65288 + we return the value TRUE as it was already configured */
65289 + if (!p_Fm->portsPreFetchConfigured[portNum])
65290 + {
65291 + *p_PortConfigured = FALSE;
65292 + *p_PreFetchConfigured = FALSE;
65293 + }
65294 + else
65295 + {
65296 + *p_PortConfigured = TRUE;
65297 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
65298 + }
65299 +
65300 + return E_OK;
65301 +}
65302 +
65303 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
65304 + uint32_t congestionGroupId,
65305 + uint8_t priorityBitMap)
65306 +{
65307 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65308 + uint32_t regNum;
65309 +
65310 + ASSERT_COND(h_Fm);
65311 +
65312 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
65313 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65314 + ("Congestion group ID bigger than %d",
65315 + FM_PORT_NUM_OF_CONGESTION_GRPS));
65316 +
65317 + if (p_Fm->guestId == NCSW_MASTER_ID)
65318 + {
65319 + ASSERT_COND(p_Fm->baseAddr);
65320 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
65321 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
65322 + congestionGroupId,
65323 + priorityBitMap,
65324 + regNum);
65325 + }
65326 + else if (p_Fm->h_IpcSessions[0])
65327 + {
65328 + t_Error err;
65329 + t_FmIpcMsg msg;
65330 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65331 +
65332 + memset(&msg, 0, sizeof(msg));
65333 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65334 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
65335 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
65336 +
65337 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
65338 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65339 +
65340 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65341 + (uint8_t*)&msg,
65342 + sizeof(msg.msgId),
65343 + NULL,
65344 + NULL,
65345 + NULL,
65346 + NULL);
65347 + if (err != E_OK)
65348 + RETURN_ERROR(MINOR, err, NO_MSG);
65349 + }
65350 + else
65351 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
65352 +
65353 + return E_OK;
65354 +}
65355 +
65356 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
65357 +{
65358 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65359 +
65360 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65361 +
65362 + if (!p_Fm->baseAddr)
65363 + {
65364 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65365 + ("No base-addr; probably Guest with IPC!"));
65366 + return 0;
65367 + }
65368 +
65369 + return (p_Fm->baseAddr + FM_MM_PRS);
65370 +}
65371 +
65372 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
65373 +{
65374 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65375 +
65376 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65377 +
65378 + if (!p_Fm->baseAddr)
65379 + {
65380 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65381 + ("No base-addr; probably Guest with IPC!"));
65382 + return 0;
65383 + }
65384 +
65385 + return (p_Fm->baseAddr + FM_MM_KG);
65386 +}
65387 +
65388 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
65389 +{
65390 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65391 +
65392 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65393 +
65394 + if (!p_Fm->baseAddr)
65395 + {
65396 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65397 + ("No base-addr; probably Guest with IPC!"));
65398 + return 0;
65399 + }
65400 +
65401 + return (p_Fm->baseAddr + FM_MM_PLCR);
65402 +}
65403 +
65404 +#if (DPAA_VERSION >= 11)
65405 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
65406 +{
65407 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65408 +
65409 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65410 +
65411 + return p_Fm->vspBaseAddr;
65412 +}
65413 +#endif /* (DPAA_VERSION >= 11) */
65414 +
65415 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
65416 +{
65417 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65418 +
65419 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
65420 +
65421 + return (p_Fm->h_FmMuram);
65422 +}
65423 +
65424 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
65425 +{
65426 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65427 +
65428 + if (p_Fm->fmMuramPhysBaseAddr)
65429 + {
65430 + /* General FM driver initialization */
65431 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
65432 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
65433 + return;
65434 + }
65435 +
65436 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
65437 +
65438 + if (p_Fm->h_IpcSessions[0])
65439 + {
65440 + t_Error err;
65441 + t_FmIpcMsg msg;
65442 + t_FmIpcReply reply;
65443 + uint32_t replyLength;
65444 + t_FmIpcPhysAddr ipcPhysAddr;
65445 +
65446 + memset(&msg, 0, sizeof(msg));
65447 + memset(&reply, 0, sizeof(reply));
65448 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
65449 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
65450 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65451 + (uint8_t*)&msg,
65452 + sizeof(msg.msgId),
65453 + (uint8_t*)&reply,
65454 + &replyLength,
65455 + NULL,
65456 + NULL);
65457 + if (err != E_OK)
65458 + {
65459 + REPORT_ERROR(MINOR, err, NO_MSG);
65460 + return;
65461 + }
65462 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
65463 + {
65464 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
65465 + return;
65466 + }
65467 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
65468 + p_FmPhysAddr->high = ipcPhysAddr.high;
65469 + p_FmPhysAddr->low = ipcPhysAddr.low;
65470 + }
65471 + else
65472 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65473 + ("running in guest-mode without neither IPC nor mapped register!"));
65474 +}
65475 +
65476 +#if (DPAA_VERSION >= 11)
65477 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
65478 + e_FmPortType portType,
65479 + uint8_t portId,
65480 + uint8_t numOfVSPs)
65481 +{
65482 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65483 + t_Error err = E_OK;
65484 + uint32_t profilesFound, intFlags;
65485 + uint8_t first, i;
65486 + uint8_t log2Num;
65487 + uint8_t swPortIndex=0, hardwarePortId;
65488 +
65489 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65490 +
65491 + if (!numOfVSPs)
65492 + return E_OK;
65493 +
65494 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
65495 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
65496 +
65497 + if (!POWER_OF_2(numOfVSPs))
65498 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
65499 +
65500 + LOG2((uint64_t)numOfVSPs, log2Num);
65501 +
65502 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
65503 + first = 0;
65504 + else
65505 + first = 1<<log2Num;
65506 +
65507 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65508 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65509 +
65510 + if (first < p_Fm->partVSPBase)
65511 + while (first < p_Fm->partVSPBase)
65512 + first = first + numOfVSPs;
65513 +
65514 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65515 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65516 +
65517 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65518 + profilesFound = 0;
65519 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
65520 + {
65521 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
65522 + {
65523 + profilesFound++;
65524 + i++;
65525 + if (profilesFound == numOfVSPs)
65526 + break;
65527 + }
65528 + else
65529 + {
65530 + profilesFound = 0;
65531 + /* advance i to the next aligned address */
65532 + first = i = (uint8_t)(first + numOfVSPs);
65533 + }
65534 + }
65535 + if (profilesFound == numOfVSPs)
65536 + for (i = first; i<first + numOfVSPs; i++)
65537 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
65538 + else
65539 + {
65540 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65541 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
65542 + }
65543 +
65544 + hardwarePortId = SwPortIdToHwPortId(portType,
65545 + portId,
65546 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65547 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65548 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65549 +
65550 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
65551 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
65552 +
65553 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
65554 + for (i = first; i < first + numOfVSPs; i++)
65555 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65556 +
65557 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65558 +
65559 + return err;
65560 +}
65561 +
65562 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
65563 + e_FmPortType portType,
65564 + uint8_t portId)
65565 +{
65566 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65567 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
65568 + uint32_t intFlags;
65569 +
65570 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65571 +
65572 + hardwarePortId = SwPortIdToHwPortId(portType,
65573 + portId,
65574 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65575 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65576 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65577 +
65578 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
65579 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
65580 +
65581 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65582 + for (i = first; i < first + numOfVSPs; i++)
65583 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65584 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65585 +
65586 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
65587 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
65588 +
65589 + return E_OK;
65590 +}
65591 +#endif /* (DPAA_VERSION >= 11) */
65592 +
65593 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
65594 +{
65595 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65596 + uint8_t i;
65597 +
65598 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65599 +
65600 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65601 + p_Fm->h_IpcSessions[0])
65602 + {
65603 + t_Error err;
65604 + t_FmIpcMsg msg;
65605 + t_FmIpcReply reply;
65606 + uint32_t replyLength;
65607 +
65608 + memset(&msg, 0, sizeof(msg));
65609 + memset(&reply, 0, sizeof(reply));
65610 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
65611 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65612 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65613 + (uint8_t*)&msg,
65614 + sizeof(msg.msgId),
65615 + (uint8_t*)&reply,
65616 + &replyLength,
65617 + NULL,
65618 + NULL)) != E_OK)
65619 + RETURN_ERROR(MAJOR, err, NO_MSG);
65620 +
65621 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
65622 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65623 +
65624 + *p_EventId = *(uint8_t*)(reply.replyBody);
65625 +
65626 + return (t_Error)(reply.error);
65627 + }
65628 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65629 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65630 + ("running in guest-mode without IPC!"));
65631 +
65632 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
65633 + if (!p_Fm->usedEventRegs[i])
65634 + {
65635 + p_Fm->usedEventRegs[i] = TRUE;
65636 + *p_EventId = i;
65637 + break;
65638 + }
65639 +
65640 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
65641 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
65642 +
65643 + return E_OK;
65644 +}
65645 +
65646 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
65647 +{
65648 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65649 +
65650 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
65651 +
65652 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65653 + p_Fm->h_IpcSessions[0])
65654 + {
65655 + t_Error err;
65656 + t_FmIpcMsg msg;
65657 +
65658 + memset(&msg, 0, sizeof(msg));
65659 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
65660 + msg.msgBody[0] = eventId;
65661 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65662 + (uint8_t*)&msg,
65663 + sizeof(msg.msgId)+sizeof(eventId),
65664 + NULL,
65665 + NULL,
65666 + NULL,
65667 + NULL);
65668 + if (err != E_OK)
65669 + REPORT_ERROR(MINOR, err, NO_MSG);
65670 + return;
65671 + }
65672 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65673 + {
65674 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65675 + ("running in guest-mode without IPC!"));
65676 + return;
65677 + }
65678 +
65679 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
65680 +}
65681 +
65682 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
65683 +{
65684 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65685 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65686 +
65687 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65688 + !p_Fm->p_FmFpmRegs &&
65689 + p_Fm->h_IpcSessions[0])
65690 + {
65691 + t_FmIpcFmanEvents fmanCtrl;
65692 + t_Error err;
65693 + t_FmIpcMsg msg;
65694 +
65695 + fmanCtrl.eventRegId = eventRegId;
65696 + fmanCtrl.enableEvents = enableEvents;
65697 + memset(&msg, 0, sizeof(msg));
65698 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
65699 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
65700 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65701 + (uint8_t*)&msg,
65702 + sizeof(msg.msgId)+sizeof(fmanCtrl),
65703 + NULL,
65704 + NULL,
65705 + NULL,
65706 + NULL);
65707 + if (err != E_OK)
65708 + REPORT_ERROR(MINOR, err, NO_MSG);
65709 + return;
65710 + }
65711 + else if (!p_Fm->p_FmFpmRegs)
65712 + {
65713 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65714 + ("Either IPC or 'baseAddress' is required!"));
65715 + return;
65716 + }
65717 +
65718 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65719 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
65720 +}
65721 +
65722 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
65723 +{
65724 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65725 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65726 +
65727 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65728 + !p_Fm->p_FmFpmRegs &&
65729 + p_Fm->h_IpcSessions[0])
65730 + {
65731 + t_Error err;
65732 + t_FmIpcMsg msg;
65733 + t_FmIpcReply reply;
65734 + uint32_t replyLength, ctrlIntr;
65735 +
65736 + memset(&msg, 0, sizeof(msg));
65737 + memset(&reply, 0, sizeof(reply));
65738 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
65739 + msg.msgBody[0] = eventRegId;
65740 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
65741 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65742 + (uint8_t*)&msg,
65743 + sizeof(msg.msgId)+sizeof(eventRegId),
65744 + (uint8_t*)&reply,
65745 + &replyLength,
65746 + NULL,
65747 + NULL);
65748 + if (err != E_OK)
65749 + {
65750 + REPORT_ERROR(MINOR, err, NO_MSG);
65751 + return 0;
65752 + }
65753 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
65754 + {
65755 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65756 + return 0;
65757 + }
65758 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
65759 + return ctrlIntr;
65760 + }
65761 + else if (!p_Fm->p_FmFpmRegs)
65762 + {
65763 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65764 + ("Either IPC or 'baseAddress' is required!"));
65765 + return 0;
65766 + }
65767 +
65768 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
65769 +}
65770 +
65771 +void FmRegisterIntr(t_Handle h_Fm,
65772 + e_FmEventModules module,
65773 + uint8_t modId,
65774 + e_FmIntrType intrType,
65775 + void (*f_Isr) (t_Handle h_Arg),
65776 + t_Handle h_Arg)
65777 +{
65778 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65779 + int event = 0;
65780 +
65781 + ASSERT_COND(h_Fm);
65782 +
65783 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
65784 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
65785 +
65786 + /* register in local FM structure */
65787 + p_Fm->intrMng[event].f_Isr = f_Isr;
65788 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
65789 +
65790 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65791 + p_Fm->h_IpcSessions[0])
65792 + {
65793 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
65794 + t_Error err;
65795 + t_FmIpcMsg msg;
65796 +
65797 + /* register in Master FM structure */
65798 + fmIpcRegisterIntr.event = (uint32_t)event;
65799 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
65800 + memset(&msg, 0, sizeof(msg));
65801 + msg.msgId = FM_REGISTER_INTR;
65802 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
65803 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65804 + (uint8_t*)&msg,
65805 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
65806 + NULL,
65807 + NULL,
65808 + NULL,
65809 + NULL);
65810 + if (err != E_OK)
65811 + REPORT_ERROR(MINOR, err, NO_MSG);
65812 + }
65813 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65814 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65815 + ("running in guest-mode without IPC!"));
65816 +}
65817 +
65818 +void FmUnregisterIntr(t_Handle h_Fm,
65819 + e_FmEventModules module,
65820 + uint8_t modId,
65821 + e_FmIntrType intrType)
65822 +{
65823 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65824 + int event = 0;
65825 +
65826 + ASSERT_COND(h_Fm);
65827 +
65828 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
65829 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
65830 +
65831 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
65832 + p_Fm->intrMng[event].h_SrcHandle = NULL;
65833 +}
65834 +
65835 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
65836 +{
65837 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65838 +
65839 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65840 +
65841 + if (p_Fm->guestId != NCSW_MASTER_ID)
65842 + {
65843 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
65844 + return;
65845 + }
65846 +
65847 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
65848 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
65849 +}
65850 +
65851 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
65852 +{
65853 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65854 +
65855 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
65856 +
65857 + if (p_Fm->guestId != NCSW_MASTER_ID)
65858 + {
65859 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
65860 + return;
65861 + }
65862 +
65863 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
65864 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
65865 +}
65866 +
65867 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
65868 +{
65869 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65870 +
65871 + if (p_Fm->h_Pcd)
65872 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
65873 +
65874 + p_Fm->h_Pcd = h_FmPcd;
65875 +}
65876 +
65877 +void FmUnregisterPcd(t_Handle h_Fm)
65878 +{
65879 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65880 +
65881 + if (!p_Fm->h_Pcd)
65882 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
65883 +
65884 + p_Fm->h_Pcd = NULL;
65885 +}
65886 +
65887 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
65888 +{
65889 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65890 +
65891 + return p_Fm->h_Pcd;
65892 +}
65893 +
65894 +uint8_t FmGetId(t_Handle h_Fm)
65895 +{
65896 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65897 +
65898 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
65899 +
65900 + return p_Fm->p_FmStateStruct->fmId;
65901 +}
65902 +
65903 +t_Error FmReset(t_Handle h_Fm)
65904 +{
65905 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65906 +
65907 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65908 +
65909 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
65910 + CORE_MemoryBarrier();
65911 + XX_UDelay(100);
65912 +
65913 + return E_OK;
65914 +}
65915 +
65916 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
65917 + uint8_t hardwarePortId,
65918 + uint8_t numOfFmanCtrls,
65919 + t_FmFmanCtrl orFmanCtrl)
65920 +{
65921 +
65922 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65923 + struct fman_fpm_regs *fpm_rg;
65924 +
65925 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65926 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
65927 +
65928 + fpm_rg = p_Fm->p_FmFpmRegs;
65929 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65930 + !p_Fm->p_FmFpmRegs &&
65931 + p_Fm->h_IpcSessions[0])
65932 + {
65933 + t_Error err;
65934 + t_FmIpcPortNumOfFmanCtrls params;
65935 + t_FmIpcMsg msg;
65936 +
65937 + memset(&msg, 0, sizeof(msg));
65938 + params.hardwarePortId = hardwarePortId;
65939 + params.numOfFmanCtrls = numOfFmanCtrls;
65940 + params.orFmanCtrl = orFmanCtrl;
65941 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
65942 + memcpy(msg.msgBody, &params, sizeof(params));
65943 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65944 + (uint8_t*)&msg,
65945 + sizeof(msg.msgId) +sizeof(params),
65946 + NULL,
65947 + NULL,
65948 + NULL,
65949 + NULL);
65950 + if (err != E_OK)
65951 + RETURN_ERROR(MINOR, err, NO_MSG);
65952 + return E_OK;
65953 + }
65954 + else if (!p_Fm->p_FmFpmRegs)
65955 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65956 + ("Either IPC or 'baseAddress' is required!"));
65957 +
65958 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
65959 +
65960 + return E_OK;
65961 +}
65962 +
65963 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
65964 +{
65965 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65966 + t_Error err;
65967 + uint32_t intFlags;
65968 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
65969 + struct fman_rg fman_rg;
65970 +
65971 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
65972 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
65973 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
65974 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
65975 +
65976 + if (p_Fm->guestId != NCSW_MASTER_ID)
65977 + {
65978 + t_FmIpcPortInInitParams portInParams;
65979 + t_FmIpcPortOutInitParams portOutParams;
65980 + t_FmIpcMsg msg;
65981 + t_FmIpcReply reply;
65982 + uint32_t replyLength;
65983 +
65984 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
65985 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
65986 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
65987 + portInParams.liodnOffset = p_PortParams->liodnOffset;
65988 + portInParams.numOfTasks = p_PortParams->numOfTasks;
65989 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
65990 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
65991 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
65992 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
65993 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
65994 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
65995 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
65996 + portInParams.liodnBase = p_PortParams->liodnBase;
65997 +
65998 + memset(&msg, 0, sizeof(msg));
65999 + memset(&reply, 0, sizeof(reply));
66000 + msg.msgId = FM_GET_SET_PORT_PARAMS;
66001 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
66002 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
66003 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66004 + (uint8_t*)&msg,
66005 + sizeof(msg.msgId) +sizeof(portInParams),
66006 + (uint8_t*)&reply,
66007 + &replyLength,
66008 + NULL,
66009 + NULL)) != E_OK)
66010 + RETURN_ERROR(MINOR, err, NO_MSG);
66011 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
66012 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66013 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
66014 +
66015 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
66016 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
66017 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
66018 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
66019 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
66020 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
66021 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
66022 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
66023 +
66024 + return (t_Error)(reply.error);
66025 + }
66026 +
66027 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66028 +
66029 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66030 + if (p_PortParams->independentMode)
66031 + {
66032 + /* set port parameters */
66033 + p_Fm->independentMode = p_PortParams->independentMode;
66034 + /* disable dispatch limit */
66035 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
66036 + }
66037 +
66038 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66039 + {
66040 + if (p_Fm->hcPortInitialized)
66041 + {
66042 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66043 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
66044 + }
66045 + else
66046 + p_Fm->hcPortInitialized = TRUE;
66047 + }
66048 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
66049 +
66050 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
66051 + if (err)
66052 + {
66053 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66054 + RETURN_ERROR(MAJOR, err, NO_MSG);
66055 + }
66056 +
66057 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66058 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66059 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66060 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66061 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66062 + /* for transmit & O/H ports */
66063 + {
66064 + uint8_t enqTh;
66065 + uint8_t deqTh;
66066 +
66067 + /* update qmi ENQ/DEQ threshold */
66068 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
66069 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
66070 + /* if enqTh is too big, we reduce it to the max value that is still OK */
66071 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
66072 + {
66073 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66074 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
66075 + }
66076 +
66077 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
66078 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
66079 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
66080 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
66081 + {
66082 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66083 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
66084 + }
66085 + }
66086 +
66087 +#ifdef FM_LOW_END_RESTRICTION
66088 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66089 + {
66090 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
66091 + {
66092 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66093 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
66094 + }
66095 + else
66096 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
66097 + }
66098 +#endif /* FM_LOW_END_RESTRICTION */
66099 +
66100 + err = FmSetSizeOfFifo(p_Fm,
66101 + hardwarePortId,
66102 + &p_PortParams->sizeOfFifo,
66103 + &p_PortParams->extraSizeOfFifo,
66104 + TRUE);
66105 + if (err)
66106 + {
66107 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66108 + RETURN_ERROR(MAJOR, err, NO_MSG);
66109 + }
66110 +
66111 + err = FmSetNumOfOpenDmas(p_Fm,
66112 + hardwarePortId,
66113 + &p_PortParams->numOfOpenDmas,
66114 + &p_PortParams->numOfExtraOpenDmas,
66115 + TRUE);
66116 + if (err)
66117 + {
66118 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66119 + RETURN_ERROR(MAJOR, err, NO_MSG);
66120 + }
66121 +
66122 + fman_set_liodn_per_port(&fman_rg,
66123 + hardwarePortId,
66124 + p_PortParams->liodnBase,
66125 + p_PortParams->liodnOffset);
66126 +
66127 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66128 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
66129 + hardwarePortId,
66130 + p_PortParams->independentMode,
66131 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
66132 +
66133 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66134 +
66135 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66136 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66137 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66138 + {
66139 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66140 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
66141 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
66142 + else
66143 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66144 + }
66145 + else
66146 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66147 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66148 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66149 + {
66150 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66151 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
66152 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
66153 + else
66154 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66155 + }
66156 +
66157 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
66158 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66159 +
66160 + return E_OK;
66161 +}
66162 +
66163 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
66164 +{
66165 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66166 + uint32_t intFlags;
66167 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
66168 + uint8_t numOfTasks, numOfDmas, macId;
66169 + uint16_t sizeOfFifo;
66170 + t_Error err;
66171 + t_FmIpcPortFreeParams portParams;
66172 + t_FmIpcMsg msg;
66173 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66174 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66175 +
66176 + if (p_Fm->guestId != NCSW_MASTER_ID)
66177 + {
66178 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
66179 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
66180 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66181 + memset(&msg, 0, sizeof(msg));
66182 + msg.msgId = FM_FREE_PORT;
66183 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
66184 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66185 + (uint8_t*)&msg,
66186 + sizeof(msg.msgId)+sizeof(portParams),
66187 + NULL,
66188 + NULL,
66189 + NULL,
66190 + NULL);
66191 + if (err != E_OK)
66192 + REPORT_ERROR(MINOR, err, NO_MSG);
66193 + return;
66194 + }
66195 +
66196 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66197 +
66198 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66199 +
66200 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66201 + {
66202 + ASSERT_COND(p_Fm->hcPortInitialized);
66203 + p_Fm->hcPortInitialized = FALSE;
66204 + }
66205 +
66206 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
66207 +
66208 + /* free numOfTasks */
66209 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66210 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
66211 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
66212 +
66213 + /* free numOfOpenDmas */
66214 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66215 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
66216 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
66217 +
66218 +#ifdef FM_HAS_TOTAL_DMAS
66219 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66220 + {
66221 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
66222 + fman_set_num_of_open_dmas(bmi_rg,
66223 + hardwarePortId,
66224 + 1,
66225 + 0,
66226 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
66227 + }
66228 +#endif /* FM_HAS_TOTAL_DMAS */
66229 +
66230 + /* free sizeOfFifo */
66231 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66232 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
66233 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
66234 +
66235 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66236 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66237 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66238 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66239 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66240 + /* for transmit & O/H ports */
66241 + {
66242 + uint8_t enqTh;
66243 + uint8_t deqTh;
66244 +
66245 + /* update qmi ENQ/DEQ threshold */
66246 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
66247 +
66248 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66249 + so we can enlarge enqTh */
66250 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66251 +
66252 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66253 + so we can reduce deqTh */
66254 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66255 +
66256 + fman_set_qmi_enq_th(qmi_rg, enqTh);
66257 + fman_set_qmi_deq_th(qmi_rg, deqTh);
66258 + }
66259 +
66260 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66261 +
66262 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66263 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66264 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66265 + {
66266 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66267 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
66268 + }
66269 + else
66270 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66271 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66272 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66273 + {
66274 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66275 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
66276 + }
66277 +
66278 +#ifdef FM_LOW_END_RESTRICTION
66279 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66280 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
66281 +#endif /* FM_LOW_END_RESTRICTION */
66282 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66283 +}
66284 +
66285 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
66286 +{
66287 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66288 + t_Error err;
66289 + t_FmIpcMsg msg;
66290 + t_FmIpcReply reply;
66291 + uint32_t replyLength;
66292 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66293 +
66294 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66295 + !p_Fm->baseAddr &&
66296 + p_Fm->h_IpcSessions[0])
66297 + {
66298 + memset(&msg, 0, sizeof(msg));
66299 + memset(&reply, 0, sizeof(reply));
66300 + msg.msgId = FM_IS_PORT_STALLED;
66301 + msg.msgBody[0] = hardwarePortId;
66302 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66303 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66304 + (uint8_t*)&msg,
66305 + sizeof(msg.msgId)+sizeof(hardwarePortId),
66306 + (uint8_t*)&reply,
66307 + &replyLength,
66308 + NULL,
66309 + NULL);
66310 + if (err != E_OK)
66311 + RETURN_ERROR(MINOR, err, NO_MSG);
66312 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66313 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66314 +
66315 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
66316 +
66317 + return (t_Error)(reply.error);
66318 + }
66319 + else if (!p_Fm->baseAddr)
66320 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66321 + ("Either IPC or 'baseAddress' is required!"));
66322 +
66323 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
66324 +
66325 + return E_OK;
66326 +}
66327 +
66328 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
66329 +{
66330 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66331 + t_Error err;
66332 + bool isStalled;
66333 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66334 +
66335 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66336 + !p_Fm->baseAddr &&
66337 + p_Fm->h_IpcSessions[0])
66338 + {
66339 + t_FmIpcMsg msg;
66340 + t_FmIpcReply reply;
66341 + uint32_t replyLength;
66342 +
66343 + memset(&msg, 0, sizeof(msg));
66344 + memset(&reply, 0, sizeof(reply));
66345 + msg.msgId = FM_RESUME_STALLED_PORT;
66346 + msg.msgBody[0] = hardwarePortId;
66347 + replyLength = sizeof(uint32_t);
66348 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66349 + (uint8_t*)&msg,
66350 + sizeof(msg.msgId) + sizeof(hardwarePortId),
66351 + (uint8_t*)&reply,
66352 + &replyLength,
66353 + NULL,
66354 + NULL);
66355 + if (err != E_OK)
66356 + RETURN_ERROR(MINOR, err, NO_MSG);
66357 + if (replyLength != sizeof(uint32_t))
66358 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66359 + return (t_Error)(reply.error);
66360 + }
66361 + else if (!p_Fm->baseAddr)
66362 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66363 + ("Either IPC or 'baseAddress' is required!"));
66364 +
66365 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66366 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
66367 +
66368 + /* Get port status */
66369 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
66370 + if (err)
66371 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
66372 + if (!isStalled)
66373 + return E_OK;
66374 +
66375 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
66376 +
66377 + return E_OK;
66378 +}
66379 +
66380 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
66381 +{
66382 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66383 + t_Error err;
66384 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66385 +
66386 +#if (DPAA_VERSION >= 11)
66387 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66388 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66389 + ("FMan MAC reset!"));
66390 +#endif /*(DPAA_VERSION >= 11)*/
66391 +
66392 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66393 + !p_Fm->baseAddr &&
66394 + p_Fm->h_IpcSessions[0])
66395 + {
66396 + t_FmIpcMacParams macParams;
66397 + t_FmIpcMsg msg;
66398 + t_FmIpcReply reply;
66399 + uint32_t replyLength;
66400 +
66401 + memset(&msg, 0, sizeof(msg));
66402 + memset(&reply, 0, sizeof(reply));
66403 + macParams.id = macId;
66404 + macParams.enumType = (uint32_t)type;
66405 + msg.msgId = FM_RESET_MAC;
66406 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
66407 + replyLength = sizeof(uint32_t);
66408 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66409 + (uint8_t*)&msg,
66410 + sizeof(msg.msgId)+sizeof(macParams),
66411 + (uint8_t*)&reply,
66412 + &replyLength,
66413 + NULL,
66414 + NULL);
66415 + if (err != E_OK)
66416 + RETURN_ERROR(MINOR, err, NO_MSG);
66417 + if (replyLength != sizeof(uint32_t))
66418 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66419 + return (t_Error)(reply.error);
66420 + }
66421 + else if (!p_Fm->baseAddr)
66422 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66423 + ("Either IPC or 'baseAddress' is required!"));
66424 +
66425 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
66426 +
66427 + if (err == -EBUSY)
66428 + return ERROR_CODE(E_TIMEOUT);
66429 + else if (err)
66430 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
66431 +
66432 + return E_OK;
66433 +}
66434 +
66435 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
66436 +{
66437 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66438 +
66439 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66440 + p_Fm->h_IpcSessions[0])
66441 + {
66442 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
66443 + t_Error err;
66444 + t_FmIpcMsg msg;
66445 +
66446 + memset(&msg, 0, sizeof(msg));
66447 + macMaxFrameLengthParams.macParams.id = macId;
66448 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
66449 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
66450 + msg.msgId = FM_SET_MAC_MAX_FRAME;
66451 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
66452 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66453 + (uint8_t*)&msg,
66454 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
66455 + NULL,
66456 + NULL,
66457 + NULL,
66458 + NULL);
66459 + if (err != E_OK)
66460 + RETURN_ERROR(MINOR, err, NO_MSG);
66461 + return E_OK;
66462 + }
66463 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66464 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66465 + ("running in guest-mode without IPC!"));
66466 +
66467 + /* if port is already initialized, check that MaxFrameLength is smaller
66468 + * or equal to the port's max */
66469 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
66470 + if (type == e_FM_MAC_10G)
66471 + {
66472 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
66473 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
66474 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
66475 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
66476 + else
66477 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66478 +
66479 + }
66480 + else
66481 +#else
66482 + UNUSED(type);
66483 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66484 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
66485 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
66486 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
66487 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
66488 + else
66489 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66490 +
66491 + return E_OK;
66492 +}
66493 +
66494 +uint16_t FmGetClockFreq(t_Handle h_Fm)
66495 +{
66496 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66497 +
66498 + /* for multicore environment: this depends on the
66499 + * fact that fmClkFreq was properly initialized at "init". */
66500 + return p_Fm->p_FmStateStruct->fmClkFreq;
66501 +}
66502 +
66503 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
66504 +{
66505 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66506 +
66507 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
66508 +}
66509 +
66510 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
66511 +{
66512 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66513 +
66514 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66515 + !p_Fm->baseAddr &&
66516 + p_Fm->h_IpcSessions[0])
66517 + {
66518 + t_Error err;
66519 + t_FmIpcMsg msg;
66520 + t_FmIpcReply reply;
66521 + uint32_t replyLength, timeStamp;
66522 +
66523 + memset(&msg, 0, sizeof(msg));
66524 + memset(&reply, 0, sizeof(reply));
66525 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
66526 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66527 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66528 + (uint8_t*)&msg,
66529 + sizeof(msg.msgId),
66530 + (uint8_t*)&reply,
66531 + &replyLength,
66532 + NULL,
66533 + NULL)) != E_OK)
66534 + {
66535 + REPORT_ERROR(MAJOR, err, NO_MSG);
66536 + return 0;
66537 + }
66538 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66539 + {
66540 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66541 + return 0;
66542 + }
66543 +
66544 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
66545 + return timeStamp;
66546 + }
66547 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66548 + p_Fm->baseAddr)
66549 + {
66550 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
66551 + {
66552 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
66553 + return 0;
66554 + }
66555 + }
66556 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66557 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
66558 +
66559 + return p_Fm->p_FmStateStruct->count1MicroBit;
66560 +}
66561 +
66562 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
66563 +{
66564 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66565 +
66566 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66567 +
66568 + p_Fm->p_FmStateStruct->ramsEccOwners++;
66569 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66570 +
66571 + return FM_EnableRamsEcc(p_Fm);
66572 +}
66573 +
66574 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
66575 +{
66576 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66577 +
66578 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66579 +
66580 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
66581 + p_Fm->p_FmStateStruct->ramsEccOwners--;
66582 +
66583 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
66584 + {
66585 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66586 + return FM_DisableRamsEcc(p_Fm);
66587 + }
66588 +
66589 + return E_OK;
66590 +}
66591 +
66592 +uint8_t FmGetGuestId(t_Handle h_Fm)
66593 +{
66594 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66595 +
66596 + return p_Fm->guestId;
66597 +}
66598 +
66599 +bool FmIsMaster(t_Handle h_Fm)
66600 +{
66601 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66602 +
66603 + return (p_Fm->guestId == NCSW_MASTER_ID);
66604 +}
66605 +
66606 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
66607 + uint8_t hardwarePortId,
66608 + uint32_t *p_SizeOfFifo,
66609 + uint32_t *p_ExtraSizeOfFifo,
66610 + bool initialConfig)
66611 +{
66612 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66613 + t_FmIpcPortRsrcParams rsrcParams;
66614 + t_Error err;
66615 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66616 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
66617 + uint16_t currentVal = 0, currentExtraVal = 0;
66618 +
66619 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66620 + !p_Fm->baseAddr &&
66621 + p_Fm->h_IpcSessions[0])
66622 + {
66623 + t_FmIpcMsg msg;
66624 + t_FmIpcReply reply;
66625 + uint32_t replyLength;
66626 +
66627 + rsrcParams.hardwarePortId = hardwarePortId;
66628 + rsrcParams.val = sizeOfFifo;
66629 + rsrcParams.extra = extraSizeOfFifo;
66630 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66631 +
66632 + memset(&msg, 0, sizeof(msg));
66633 + memset(&reply, 0, sizeof(reply));
66634 + msg.msgId = FM_SET_SIZE_OF_FIFO;
66635 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66636 + replyLength = sizeof(uint32_t);
66637 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66638 + (uint8_t*)&msg,
66639 + sizeof(msg.msgId) + sizeof(rsrcParams),
66640 + (uint8_t*)&reply,
66641 + &replyLength,
66642 + NULL,
66643 + NULL)) != E_OK)
66644 + RETURN_ERROR(MINOR, err, NO_MSG);
66645 + if (replyLength != sizeof(uint32_t))
66646 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66647 + return (t_Error)(reply.error);
66648 + }
66649 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66650 + p_Fm->baseAddr)
66651 + {
66652 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
66653 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66654 + }
66655 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66656 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66657 + ("running in guest-mode without neither IPC nor mapped register!"));
66658 +
66659 + if (!initialConfig)
66660 + {
66661 + /* !initialConfig - runtime change of existing value.
66662 + * - read the current FIFO and extra FIFO size */
66663 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
66664 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66665 + }
66666 +
66667 + if (extraSizeOfFifo > currentExtraVal)
66668 + {
66669 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
66670 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
66671 + * must be initialized to 1 buffer per port
66672 + */
66673 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
66674 +
66675 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
66676 + }
66677 +
66678 + /* check that there are enough uncommitted fifo size */
66679 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
66680 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
66681 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
66682 + ("Port request fifo size + accumulated size > total FIFO size:"));
66683 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66684 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
66685 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
66686 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
66687 + p_Fm->p_FmStateStruct->totalFifoSize));
66688 + }
66689 + else
66690 + {
66691 + /* update accumulated */
66692 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
66693 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
66694 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
66695 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
66696 + }
66697 +
66698 + return E_OK;
66699 +}
66700 +
66701 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
66702 + uint8_t hardwarePortId,
66703 + uint8_t *p_NumOfTasks,
66704 + uint8_t *p_NumOfExtraTasks,
66705 + bool initialConfig)
66706 +{
66707 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66708 + t_Error err;
66709 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66710 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
66711 +
66712 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66713 +
66714 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66715 + !p_Fm->baseAddr &&
66716 + p_Fm->h_IpcSessions[0])
66717 + {
66718 + t_FmIpcPortRsrcParams rsrcParams;
66719 + t_FmIpcMsg msg;
66720 + t_FmIpcReply reply;
66721 + uint32_t replyLength;
66722 +
66723 + rsrcParams.hardwarePortId = hardwarePortId;
66724 + rsrcParams.val = numOfTasks;
66725 + rsrcParams.extra = numOfExtraTasks;
66726 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66727 +
66728 + memset(&msg, 0, sizeof(msg));
66729 + memset(&reply, 0, sizeof(reply));
66730 + msg.msgId = FM_SET_NUM_OF_TASKS;
66731 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66732 + replyLength = sizeof(uint32_t);
66733 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66734 + (uint8_t*)&msg,
66735 + sizeof(msg.msgId) + sizeof(rsrcParams),
66736 + (uint8_t*)&reply,
66737 + &replyLength,
66738 + NULL,
66739 + NULL)) != E_OK)
66740 + RETURN_ERROR(MINOR, err, NO_MSG);
66741 + if (replyLength != sizeof(uint32_t))
66742 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66743 + return (t_Error)(reply.error);
66744 + }
66745 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66746 + p_Fm->baseAddr)
66747 + {
66748 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
66749 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
66750 + }
66751 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66752 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66753 + ("running in guest-mode without neither IPC nor mapped register!"));
66754 +
66755 + if (!initialConfig)
66756 + {
66757 + /* !initialConfig - runtime change of existing value.
66758 + * - read the current number of tasks */
66759 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66760 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
66761 + }
66762 +
66763 + if (numOfExtraTasks > currentExtraVal)
66764 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
66765 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
66766 +
66767 + /* check that there are enough uncommitted tasks */
66768 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
66769 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
66770 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
66771 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
66772 + p_Fm->p_FmStateStruct->fmId));
66773 + else
66774 + {
66775 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
66776 + /* update accumulated */
66777 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
66778 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
66779 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
66780 + }
66781 +
66782 + return E_OK;
66783 +}
66784 +
66785 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
66786 + uint8_t hardwarePortId,
66787 + uint8_t *p_NumOfOpenDmas,
66788 + uint8_t *p_NumOfExtraOpenDmas,
66789 + bool initialConfig)
66790 +
66791 +{
66792 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66793 + t_Error err;
66794 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66795 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
66796 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
66797 +
66798 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66799 +
66800 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66801 + !p_Fm->baseAddr &&
66802 + p_Fm->h_IpcSessions[0])
66803 + {
66804 + t_FmIpcPortRsrcParams rsrcParams;
66805 + t_FmIpcMsg msg;
66806 + t_FmIpcReply reply;
66807 + uint32_t replyLength;
66808 +
66809 + rsrcParams.hardwarePortId = hardwarePortId;
66810 + rsrcParams.val = numOfOpenDmas;
66811 + rsrcParams.extra = numOfExtraOpenDmas;
66812 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66813 +
66814 + memset(&msg, 0, sizeof(msg));
66815 + memset(&reply, 0, sizeof(reply));
66816 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
66817 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66818 + replyLength = sizeof(uint32_t);
66819 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66820 + (uint8_t*)&msg,
66821 + sizeof(msg.msgId) + sizeof(rsrcParams),
66822 + (uint8_t*)&reply,
66823 + &replyLength,
66824 + NULL,
66825 + NULL)) != E_OK)
66826 + RETURN_ERROR(MINOR, err, NO_MSG);
66827 + if (replyLength != sizeof(uint32_t))
66828 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66829 + return (t_Error)(reply.error);
66830 + }
66831 +#ifdef FM_HAS_TOTAL_DMAS
66832 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66833 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
66834 +#else
66835 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66836 + p_Fm->baseAddr &&
66837 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
66838 + {
66839 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
66840 +
66841 + if (!numOfOpenDmas)
66842 + {
66843 + /* first config without explic it value: Do Nothing - reset value shouldn't be
66844 + changed, read register for port save */
66845 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66846 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
66847 + }
66848 + else
66849 + /* whether it is the first time with explicit value, or runtime "set" - write register */
66850 + fman_set_num_of_open_dmas(bmi_rg,
66851 + hardwarePortId,
66852 + numOfOpenDmas,
66853 + numOfExtraOpenDmas,
66854 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
66855 + }
66856 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66857 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
66858 + ("running in guest-mode without neither IPC nor mapped register!"));
66859 +#endif /* FM_HAS_TOTAL_DMAS */
66860 +
66861 + if (!initialConfig)
66862 + {
66863 + /* !initialConfig - runtime change of existing value.
66864 + * - read the current number of open Dma's */
66865 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
66866 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66867 + }
66868 +
66869 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
66870 + /* it's illegal to be in a state where this is not the first set and no value is specified */
66871 + ASSERT_COND(initialConfig || numOfOpenDmas);
66872 + if (!numOfOpenDmas)
66873 + {
66874 + /* !numOfOpenDmas - first configuration according to values in regs.
66875 + * - read the current number of open Dma's */
66876 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
66877 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66878 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
66879 + * reset values will be used and we just save these values for resource management */
66880 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
66881 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
66882 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
66883 + *p_NumOfOpenDmas = currentVal;
66884 + *p_NumOfExtraOpenDmas = currentExtraVal;
66885 + return E_OK;
66886 + }
66887 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
66888 +
66889 + if (numOfExtraOpenDmas > currentExtraVal)
66890 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
66891 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
66892 +
66893 +#ifdef FM_HAS_TOTAL_DMAS
66894 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
66895 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
66896 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
66897 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
66898 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
66899 + p_Fm->p_FmStateStruct->fmId));
66900 +#else
66901 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
66902 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
66903 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
66904 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
66905 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
66906 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
66907 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
66908 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
66909 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
66910 +#endif /* FM_HAS_TOTAL_DMAS */
66911 + else
66912 + {
66913 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
66914 + /* update acummulated */
66915 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
66916 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
66917 +
66918 +#ifdef FM_HAS_TOTAL_DMAS
66919 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66920 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
66921 +#endif /* FM_HAS_TOTAL_DMAS */
66922 + fman_set_num_of_open_dmas(bmi_rg,
66923 + hardwarePortId,
66924 + numOfOpenDmas,
66925 + numOfExtraOpenDmas,
66926 + totalNumDmas);
66927 + }
66928 +
66929 + return E_OK;
66930 +}
66931 +
66932 +#if (DPAA_VERSION >= 11)
66933 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
66934 + e_FmPortType portType,
66935 + uint8_t portId,
66936 + uint16_t relativeProfile)
66937 +{
66938 + t_Fm *p_Fm;
66939 + t_FmSp *p_FmPcdSp;
66940 + uint8_t swPortIndex=0, hardwarePortId;
66941 +
66942 + ASSERT_COND(h_Fm);
66943 + p_Fm = (t_Fm*)h_Fm;
66944 +
66945 + hardwarePortId = SwPortIdToHwPortId(portType,
66946 + portId,
66947 + p_Fm->p_FmStateStruct->revInfo.majorRev,
66948 + p_Fm->p_FmStateStruct->revInfo.minorRev);
66949 + ASSERT_COND(hardwarePortId);
66950 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
66951 +
66952 + p_FmPcdSp = p_Fm->p_FmSp;
66953 + ASSERT_COND(p_FmPcdSp);
66954 +
66955 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
66956 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
66957 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
66958 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
66959 +
66960 + return E_OK;
66961 +}
66962 +
66963 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
66964 + e_FmPortType portType,
66965 + uint8_t portId,
66966 + uint16_t relativeProfile,
66967 + uint16_t *p_AbsoluteId)
66968 +{
66969 + t_Fm *p_Fm;
66970 + t_FmSp *p_FmPcdSp;
66971 + uint8_t swPortIndex=0, hardwarePortId;
66972 + t_Error err;
66973 +
66974 + ASSERT_COND(h_Fm);
66975 + p_Fm = (t_Fm*)h_Fm;
66976 +
66977 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
66978 + if (err != E_OK)
66979 + return err;
66980 +
66981 + hardwarePortId = SwPortIdToHwPortId(portType,
66982 + portId,
66983 + p_Fm->p_FmStateStruct->revInfo.majorRev,
66984 + p_Fm->p_FmStateStruct->revInfo.minorRev);
66985 + ASSERT_COND(hardwarePortId);
66986 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
66987 +
66988 + p_FmPcdSp = p_Fm->p_FmSp;
66989 + ASSERT_COND(p_FmPcdSp);
66990 +
66991 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
66992 +
66993 + return E_OK;
66994 +}
66995 +#endif /* (DPAA_VERSION >= 11) */
66996 +
66997 +static t_Error InitFmDma(t_Fm *p_Fm)
66998 +{
66999 + t_Error err;
67000 +
67001 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
67002 + if (err != E_OK)
67003 + return err;
67004 +
67005 + /* Allocate MURAM for CAM */
67006 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67007 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
67008 + DMA_CAM_ALIGN));
67009 + if (!p_Fm->camBaseAddr)
67010 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67011 +
67012 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67013 + 0,
67014 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
67015 +
67016 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
67017 + {
67018 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
67019 +
67020 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67021 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
67022 + 64));
67023 + if (!p_Fm->camBaseAddr)
67024 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67025 +
67026 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67027 + 0,
67028 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
67029 +
67030 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
67031 + {
67032 + case (8):
67033 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
67034 + break;
67035 + case (16):
67036 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
67037 + break;
67038 + case (24):
67039 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
67040 + break;
67041 + case (32):
67042 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
67043 + break;
67044 + default:
67045 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
67046 + }
67047 + }
67048 +
67049 + p_Fm->p_FmDriverParam->cam_base_addr =
67050 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67051 +
67052 + return E_OK;
67053 +}
67054 +
67055 +static t_Error InitFmFpm(t_Fm *p_Fm)
67056 +{
67057 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
67058 +}
67059 +
67060 +static t_Error InitFmBmi(t_Fm *p_Fm)
67061 +{
67062 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
67063 +}
67064 +
67065 +static t_Error InitFmQmi(t_Fm *p_Fm)
67066 +{
67067 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
67068 +}
67069 +
67070 +static t_Error InitGuestMode(t_Fm *p_Fm)
67071 +{
67072 + t_Error err = E_OK;
67073 + int i;
67074 + t_FmIpcMsg msg;
67075 + t_FmIpcReply reply;
67076 + uint32_t replyLength;
67077 +
67078 + ASSERT_COND(p_Fm);
67079 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67080 +
67081 + /* build the FM guest partition IPC address */
67082 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
67083 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67084 +
67085 + /* build the FM master partition IPC address */
67086 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
67087 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67088 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67089 +
67090 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67091 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67092 +
67093 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
67094 + if (p_Fm->h_IpcSessions[0])
67095 + {
67096 + uint8_t isMasterAlive;
67097 + t_FmIpcParams ipcParams;
67098 +
67099 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67100 + if (err)
67101 + RETURN_ERROR(MAJOR, err, NO_MSG);
67102 +
67103 + memset(&msg, 0, sizeof(msg));
67104 + memset(&reply, 0, sizeof(reply));
67105 + msg.msgId = FM_MASTER_IS_ALIVE;
67106 + msg.msgBody[0] = p_Fm->guestId;
67107 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67108 + do
67109 + {
67110 + blockingFlag = TRUE;
67111 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67112 + (uint8_t*)&msg,
67113 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
67114 + (uint8_t*)&reply,
67115 + &replyLength,
67116 + IpcMsgCompletionCB,
67117 + p_Fm)) != E_OK)
67118 + REPORT_ERROR(MINOR, err, NO_MSG);
67119 + while (blockingFlag) ;
67120 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67121 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67122 + isMasterAlive = *(uint8_t*)(reply.replyBody);
67123 + } while (!isMasterAlive);
67124 +
67125 + /* read FM parameters and save */
67126 + memset(&msg, 0, sizeof(msg));
67127 + memset(&reply, 0, sizeof(reply));
67128 + msg.msgId = FM_GET_PARAMS;
67129 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67130 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67131 + (uint8_t*)&msg,
67132 + sizeof(msg.msgId),
67133 + (uint8_t*)&reply,
67134 + &replyLength,
67135 + NULL,
67136 + NULL)) != E_OK)
67137 + RETURN_ERROR(MAJOR, err, NO_MSG);
67138 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
67139 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67140 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
67141 +
67142 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
67143 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
67144 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
67145 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
67146 + }
67147 + else
67148 + {
67149 + DBG(WARNING, ("FM Guest mode - without IPC"));
67150 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
67151 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
67152 + if (p_Fm->baseAddr)
67153 + {
67154 + fman_get_revision(p_Fm->p_FmFpmRegs,
67155 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67156 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67157 +
67158 + }
67159 + }
67160 +
67161 +#if (DPAA_VERSION >= 11)
67162 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67163 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67164 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67165 +#endif /* (DPAA_VERSION >= 11) */
67166 +
67167 + /* General FM driver initialization */
67168 + if (p_Fm->baseAddr)
67169 + p_Fm->fmMuramPhysBaseAddr =
67170 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67171 +
67172 + XX_Free(p_Fm->p_FmDriverParam);
67173 + p_Fm->p_FmDriverParam = NULL;
67174 +
67175 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
67176 + (p_Fm->h_IpcSessions[0]))
67177 + {
67178 + FM_DisableRamsEcc(p_Fm);
67179 + FmMuramClear(p_Fm->h_FmMuram);
67180 + FM_EnableRamsEcc(p_Fm);
67181 + }
67182 +
67183 + return E_OK;
67184 +}
67185 +
67186 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
67187 +{
67188 + switch (exception) {
67189 + case e_FM_EX_DMA_BUS_ERROR:
67190 + return E_FMAN_EX_DMA_BUS_ERROR;
67191 + case e_FM_EX_DMA_READ_ECC:
67192 + return E_FMAN_EX_DMA_READ_ECC;
67193 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
67194 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
67195 + case e_FM_EX_DMA_FM_WRITE_ECC:
67196 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
67197 + case e_FM_EX_FPM_STALL_ON_TASKS:
67198 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
67199 + case e_FM_EX_FPM_SINGLE_ECC:
67200 + return E_FMAN_EX_FPM_SINGLE_ECC;
67201 + case e_FM_EX_FPM_DOUBLE_ECC:
67202 + return E_FMAN_EX_FPM_DOUBLE_ECC;
67203 + case e_FM_EX_QMI_SINGLE_ECC:
67204 + return E_FMAN_EX_QMI_SINGLE_ECC;
67205 + case e_FM_EX_QMI_DOUBLE_ECC:
67206 + return E_FMAN_EX_QMI_DOUBLE_ECC;
67207 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
67208 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
67209 + case e_FM_EX_BMI_LIST_RAM_ECC:
67210 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
67211 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
67212 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
67213 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
67214 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
67215 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
67216 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
67217 + case e_FM_EX_IRAM_ECC:
67218 + return E_FMAN_EX_IRAM_ECC;
67219 + case e_FM_EX_MURAM_ECC:
67220 + return E_FMAN_EX_MURAM_ECC;
67221 + default:
67222 + return E_FMAN_EX_DMA_BUS_ERROR;
67223 + }
67224 +}
67225 +
67226 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
67227 +{
67228 + switch (type)
67229 + {
67230 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
67231 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
67232 + CHECK_PORT_ID_OH_PORTS(relativePortId);
67233 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
67234 + case (e_FM_PORT_TYPE_RX):
67235 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67236 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67237 + case (e_FM_PORT_TYPE_RX_10G):
67238 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67239 + * This is the reason why the 1G port offset is used.
67240 + */
67241 + if (majorRev == 6 && minorRev == 4)
67242 + {
67243 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67244 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67245 + }
67246 + else
67247 + {
67248 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
67249 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
67250 + }
67251 + case (e_FM_PORT_TYPE_TX):
67252 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67253 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67254 + case (e_FM_PORT_TYPE_TX_10G):
67255 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67256 + * This is the reason why the 1G port offset is used.
67257 + */
67258 + if (majorRev == 6 && minorRev == 4)
67259 + {
67260 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67261 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67262 + }
67263 + else
67264 + {
67265 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
67266 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
67267 + }
67268 + default:
67269 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
67270 + return 0;
67271 + }
67272 +}
67273 +
67274 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
67275 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
67276 +{
67277 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67278 +
67279 + DECLARE_DUMP;
67280 +
67281 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67282 +
67283 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67284 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
67285 + p_Fm->baseAddr), E_INVALID_OPERATION);
67286 +
67287 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
67288 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
67289 +
67290 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
67291 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
67292 +
67293 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
67294 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
67295 +
67296 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
67297 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
67298 +
67299 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
67300 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
67301 +
67302 + return E_OK;
67303 +}
67304 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
67305 +
67306 +
67307 +/*****************************************************************************/
67308 +/* API Init unit functions */
67309 +/*****************************************************************************/
67310 +t_Handle FM_Config(t_FmParams *p_FmParam)
67311 +{
67312 + t_Fm *p_Fm;
67313 + uint8_t i;
67314 + uintptr_t baseAddr;
67315 +
67316 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
67317 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
67318 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
67319 + E_INVALID_VALUE, NULL);
67320 +
67321 + baseAddr = p_FmParam->baseAddr;
67322 +
67323 + /* Allocate FM structure */
67324 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
67325 + if (!p_Fm)
67326 + {
67327 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
67328 + return NULL;
67329 + }
67330 + memset(p_Fm, 0, sizeof(t_Fm));
67331 +
67332 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
67333 + if (!p_Fm->p_FmStateStruct)
67334 + {
67335 + XX_Free(p_Fm);
67336 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
67337 + return NULL;
67338 + }
67339 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
67340 +
67341 + /* Initialize FM parameters which will be kept by the driver */
67342 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67343 + p_Fm->guestId = p_FmParam->guestId;
67344 +
67345 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
67346 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
67347 +
67348 + /* Allocate the FM driver's parameters structure */
67349 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
67350 + if (!p_Fm->p_FmDriverParam)
67351 + {
67352 + XX_Free(p_Fm->p_FmStateStruct);
67353 + XX_Free(p_Fm);
67354 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
67355 + return NULL;
67356 + }
67357 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
67358 +
67359 +#if (DPAA_VERSION >= 11)
67360 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
67361 + if (!p_Fm->p_FmSp)
67362 + {
67363 + XX_Free(p_Fm->p_FmDriverParam);
67364 + XX_Free(p_Fm->p_FmStateStruct);
67365 + XX_Free(p_Fm);
67366 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
67367 + return NULL;
67368 + }
67369 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
67370 +
67371 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
67372 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
67373 +#endif /* (DPAA_VERSION >= 11) */
67374 +
67375 + /* Initialize FM parameters which will be kept by the driver */
67376 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67377 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
67378 + p_Fm->h_App = p_FmParam->h_App;
67379 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
67380 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
67381 + p_Fm->f_Exception = p_FmParam->f_Exception;
67382 + p_Fm->f_BusError = p_FmParam->f_BusError;
67383 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
67384 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67385 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
67386 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
67387 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67388 + p_Fm->baseAddr = baseAddr;
67389 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
67390 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
67391 + p_Fm->hcPortInitialized = FALSE;
67392 + p_Fm->independentMode = FALSE;
67393 +
67394 + p_Fm->h_Spinlock = XX_InitSpinlock();
67395 + if (!p_Fm->h_Spinlock)
67396 + {
67397 + XX_Free(p_Fm->p_FmDriverParam);
67398 + XX_Free(p_Fm->p_FmStateStruct);
67399 + XX_Free(p_Fm);
67400 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
67401 + return NULL;
67402 + }
67403 +
67404 +#if (DPAA_VERSION >= 11)
67405 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
67406 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
67407 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
67408 +#endif /* (DPAA_VERSION >= 11) */
67409 +
67410 + fman_defconfig(p_Fm->p_FmDriverParam,
67411 + !!(p_Fm->guestId == NCSW_MASTER_ID));
67412 +/* overide macros dependent parameters */
67413 +#ifdef FM_PEDANTIC_DMA
67414 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
67415 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
67416 +#endif /* FM_PEDANTIC_DMA */
67417 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67418 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
67419 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67420 +
67421 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
67422 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
67423 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
67424 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
67425 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
67426 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
67427 + p_Fm->firmware.size = p_FmParam->firmware.size;
67428 + if (p_Fm->firmware.size)
67429 + {
67430 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
67431 + if (!p_Fm->firmware.p_Code)
67432 + {
67433 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67434 + XX_Free(p_Fm->p_FmStateStruct);
67435 + XX_Free(p_Fm->p_FmDriverParam);
67436 + XX_Free(p_Fm);
67437 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
67438 + return NULL;
67439 + }
67440 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
67441 + }
67442 +
67443 + if (p_Fm->guestId != NCSW_MASTER_ID)
67444 + return p_Fm;
67445 +
67446 + /* read revision */
67447 + /* Chip dependent, will be configured in Init */
67448 + fman_get_revision(p_Fm->p_FmFpmRegs,
67449 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67450 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67451 +
67452 +#ifdef FM_AID_MODE_NO_TNUM_SW005
67453 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
67454 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
67455 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
67456 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67457 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67458 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
67459 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67460 +
67461 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
67462 + p_Fm->p_FmStateStruct->totalNumOfTasks =
67463 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
67464 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67465 +
67466 +#ifdef FM_HAS_TOTAL_DMAS
67467 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
67468 +#endif /* FM_HAS_TOTAL_DMAS */
67469 +#if (DPAA_VERSION < 11)
67470 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
67471 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
67472 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
67473 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
67474 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
67475 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
67476 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
67477 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
67478 +#endif /* (DPAA_VERSION < 11) */
67479 +#ifdef FM_NO_TNUM_AGING
67480 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
67481 +#endif
67482 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
67483 +
67484 + return p_Fm;
67485 +}
67486 +
67487 +/**************************************************************************//**
67488 + @Function FM_Init
67489 +
67490 + @Description Initializes the FM module
67491 +
67492 + @Param[in] h_Fm - FM module descriptor
67493 +
67494 + @Return E_OK on success; Error code otherwise.
67495 +*//***************************************************************************/
67496 +t_Error FM_Init(t_Handle h_Fm)
67497 +{
67498 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67499 + struct fman_cfg *p_FmDriverParam = NULL;
67500 + t_Error err = E_OK;
67501 + int i;
67502 + t_FmRevisionInfo revInfo;
67503 + struct fman_rg fman_rg;
67504 +
67505 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67506 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67507 +
67508 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67509 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67510 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67511 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67512 +
67513 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
67514 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
67515 +
67516 + if (p_Fm->guestId != NCSW_MASTER_ID)
67517 + return InitGuestMode(p_Fm);
67518 +
67519 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
67520 + * according to chip. otherwise, we use user's configuration.
67521 + */
67522 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
67523 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
67524 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67525 +
67526 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
67527 +
67528 + p_FmDriverParam = p_Fm->p_FmDriverParam;
67529 +
67530 + FM_GetRevision(p_Fm, &revInfo);
67531 +
67532 + /* clear revision-dependent non existing exception */
67533 +#ifdef FM_NO_DISPATCH_RAM_ECC
67534 + if ((revInfo.majorRev != 4) &&
67535 + (revInfo.majorRev < 6))
67536 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
67537 +#endif /* FM_NO_DISPATCH_RAM_ECC */
67538 +
67539 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
67540 + if (revInfo.majorRev == 4)
67541 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
67542 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
67543 +
67544 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
67545 + if (revInfo.majorRev >= 6)
67546 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
67547 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
67548 +
67549 + FmMuramClear(p_Fm->h_FmMuram);
67550 +
67551 + /* clear CPG */
67552 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
67553 +
67554 + /* add to the default exceptions the user's definitions */
67555 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
67556 +
67557 + /* Reset the FM if required */
67558 + if (p_Fm->resetOnInit)
67559 + {
67560 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67561 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
67562 + RETURN_ERROR(MAJOR, err, NO_MSG);
67563 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67564 +
67565 + if (p_Fm->f_ResetOnInitOverride)
67566 + {
67567 + /* Perform user specific FMan reset */
67568 + p_Fm->f_ResetOnInitOverride(h_Fm);
67569 + }
67570 + else
67571 + {
67572 + /* Perform FMan reset */
67573 + FmReset(h_Fm);
67574 + }
67575 +
67576 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
67577 + {
67578 + fman_resume(p_Fm->p_FmFpmRegs);
67579 + XX_UDelay(100);
67580 + }
67581 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67582 + }
67583 +
67584 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67585 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
67586 + {
67587 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67588 + /* Load FMan-Controller code to IRAM */
67589 +
67590 + ClearIRam(p_Fm);
67591 +
67592 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
67593 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
67594 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67595 + }
67596 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67597 +
67598 +#ifdef FM_CAPWAP_SUPPORT
67599 + /* save first 256 byte in MURAM */
67600 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
67601 + if (!p_Fm->resAddr)
67602 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
67603 +
67604 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
67605 +#endif /* FM_CAPWAP_SUPPORT */
67606 +
67607 +#if (DPAA_VERSION >= 11)
67608 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67609 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67610 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67611 +#endif /* (DPAA_VERSION >= 11) */
67612 +
67613 + /* General FM driver initialization */
67614 + p_Fm->fmMuramPhysBaseAddr =
67615 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67616 +
67617 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67618 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67619 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67620 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
67621 +
67622 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
67623 +
67624 + /**********************/
67625 + /* Init DMA Registers */
67626 + /**********************/
67627 + err = InitFmDma(p_Fm);
67628 + if (err != E_OK)
67629 + {
67630 + FreeInitResources(p_Fm);
67631 + RETURN_ERROR(MAJOR, err, NO_MSG);
67632 + }
67633 +
67634 + /**********************/
67635 + /* Init FPM Registers */
67636 + /**********************/
67637 + err = InitFmFpm(p_Fm);
67638 + if (err != E_OK)
67639 + {
67640 + FreeInitResources(p_Fm);
67641 + RETURN_ERROR(MAJOR, err, NO_MSG);
67642 + }
67643 +
67644 + /* define common resources */
67645 + /* allocate MURAM for FIFO according to total size */
67646 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67647 + p_Fm->p_FmStateStruct->totalFifoSize,
67648 + BMI_FIFO_ALIGN));
67649 + if (!p_Fm->fifoBaseAddr)
67650 + {
67651 + FreeInitResources(p_Fm);
67652 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
67653 + }
67654 +
67655 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67656 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
67657 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
67658 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
67659 +
67660 + /**********************/
67661 + /* Init BMI Registers */
67662 + /**********************/
67663 + err = InitFmBmi(p_Fm);
67664 + if (err != E_OK)
67665 + {
67666 + FreeInitResources(p_Fm);
67667 + RETURN_ERROR(MAJOR, err, NO_MSG);
67668 + }
67669 +
67670 + /**********************/
67671 + /* Init QMI Registers */
67672 + /**********************/
67673 + err = InitFmQmi(p_Fm);
67674 + if (err != E_OK)
67675 + {
67676 + FreeInitResources(p_Fm);
67677 + RETURN_ERROR(MAJOR, err, NO_MSG);
67678 + }
67679 +
67680 + /* build the FM master partition IPC address */
67681 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67682 + {
67683 + FreeInitResources(p_Fm);
67684 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67685 + }
67686 +
67687 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67688 + if (err)
67689 + {
67690 + FreeInitResources(p_Fm);
67691 + RETURN_ERROR(MAJOR, err, NO_MSG);
67692 + }
67693 +
67694 + /* Register the FM interrupts handlers */
67695 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67696 + {
67697 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
67698 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
67699 + }
67700 +
67701 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67702 + {
67703 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
67704 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
67705 + }
67706 +
67707 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
67708 + if (err != E_OK)
67709 + return err; /* FIXME */
67710 +
67711 + EnableTimeStamp(p_Fm);
67712 +
67713 + if (p_Fm->firmware.p_Code)
67714 + {
67715 + XX_Free(p_Fm->firmware.p_Code);
67716 + p_Fm->firmware.p_Code = NULL;
67717 + }
67718 +
67719 + XX_Free(p_Fm->p_FmDriverParam);
67720 + p_Fm->p_FmDriverParam = NULL;
67721 +
67722 + return E_OK;
67723 +}
67724 +
67725 +/**************************************************************************//**
67726 + @Function FM_Free
67727 +
67728 + @Description Frees all resources that were assigned to FM module.
67729 +
67730 + Calling this routine invalidates the descriptor.
67731 +
67732 + @Param[in] h_Fm - FM module descriptor
67733 +
67734 + @Return E_OK on success; Error code otherwise.
67735 +*//***************************************************************************/
67736 +t_Error FM_Free(t_Handle h_Fm)
67737 +{
67738 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67739 + struct fman_rg fman_rg;
67740 +
67741 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67742 +
67743 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67744 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67745 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67746 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67747 +
67748 + if (p_Fm->guestId != NCSW_MASTER_ID)
67749 + {
67750 +#if (DPAA_VERSION >= 11)
67751 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67752 +
67753 + if (p_Fm->p_FmSp)
67754 + {
67755 + XX_Free(p_Fm->p_FmSp);
67756 + p_Fm->p_FmSp = NULL;
67757 + }
67758 +#endif /* (DPAA_VERSION >= 11) */
67759 +
67760 + if (p_Fm->fmModuleName[0] != 0)
67761 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
67762 +
67763 + if (!p_Fm->recoveryMode)
67764 + XX_Free(p_Fm->p_FmStateStruct);
67765 +
67766 + XX_Free(p_Fm);
67767 +
67768 + return E_OK;
67769 + }
67770 +
67771 + fman_free_resources(&fman_rg);
67772 +
67773 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
67774 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
67775 +
67776 + if (p_Fm->p_FmStateStruct)
67777 + {
67778 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
67779 + {
67780 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
67781 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
67782 + }
67783 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
67784 + {
67785 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
67786 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
67787 + }
67788 + }
67789 +
67790 +#if (DPAA_VERSION >= 11)
67791 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67792 +
67793 + if (p_Fm->p_FmSp)
67794 + {
67795 + XX_Free(p_Fm->p_FmSp);
67796 + p_Fm->p_FmSp = NULL;
67797 + }
67798 +#endif /* (DPAA_VERSION >= 11) */
67799 +
67800 + if (p_Fm->h_Spinlock)
67801 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67802 +
67803 + if (p_Fm->p_FmDriverParam)
67804 + {
67805 + if (p_Fm->firmware.p_Code)
67806 + XX_Free(p_Fm->firmware.p_Code);
67807 + XX_Free(p_Fm->p_FmDriverParam);
67808 + p_Fm->p_FmDriverParam = NULL;
67809 + }
67810 +
67811 + FreeInitResources(p_Fm);
67812 +
67813 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
67814 + XX_Free(p_Fm->p_FmStateStruct);
67815 +
67816 + XX_Free(p_Fm);
67817 +
67818 + return E_OK;
67819 +}
67820 +
67821 +/*************************************************/
67822 +/* API Advanced Init unit functions */
67823 +/*************************************************/
67824 +
67825 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
67826 +{
67827 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67828 +
67829 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67830 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67831 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67832 +
67833 + p_Fm->resetOnInit = enable;
67834 +
67835 + return E_OK;
67836 +}
67837 +
67838 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
67839 +{
67840 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67841 +
67842 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67843 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67844 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67845 +
67846 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
67847 +
67848 + return E_OK;
67849 +}
67850 +
67851 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
67852 +{
67853 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67854 +
67855 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67856 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67857 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67858 +
67859 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
67860 +
67861 + return E_OK;
67862 +}
67863 +
67864 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
67865 +{
67866 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67867 + enum fman_dma_cache_override fsl_cache_override;
67868 +
67869 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67870 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67871 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67872 +
67873 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
67874 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
67875 +
67876 + return E_OK;
67877 +}
67878 +
67879 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
67880 +{
67881 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67882 +
67883 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67884 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67885 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67886 +
67887 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
67888 +
67889 + return E_OK;
67890 +}
67891 +
67892 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
67893 +{
67894 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67895 + enum fman_dma_aid_mode fsl_aid_mode;
67896 +
67897 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67898 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67899 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67900 +
67901 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
67902 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
67903 +
67904 + return E_OK;
67905 +}
67906 +
67907 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
67908 +{
67909 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67910 +
67911 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67912 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67913 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67914 +
67915 +#if (DPAA_VERSION >= 11)
67916 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
67917 +#else
67918 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
67919 +
67920 + return E_OK;
67921 +#endif /* (DPAA_VERSION >= 11) */
67922 +}
67923 +
67924 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
67925 +{
67926 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67927 +
67928 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67929 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67930 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67931 +
67932 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
67933 +
67934 + return E_OK;
67935 +}
67936 +
67937 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
67938 +{
67939 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67940 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
67941 +
67942 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67943 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67944 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67945 +
67946 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
67947 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
67948 +
67949 + return E_OK;
67950 +}
67951 +
67952 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
67953 +{
67954 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67955 +
67956 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67957 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67958 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67959 +
67960 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
67961 +
67962 + return E_OK;
67963 +}
67964 +
67965 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
67966 +{
67967 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67968 + enum fman_dma_emergency_level fsl_dma_emer;
67969 +
67970 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67971 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67972 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67973 +
67974 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
67975 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
67976 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
67977 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
67978 +
67979 + return E_OK;
67980 +}
67981 +
67982 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
67983 +{
67984 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67985 +
67986 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67987 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67988 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
67989 +
67990 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
67991 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
67992 +
67993 + return E_OK;
67994 +}
67995 +
67996 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
67997 +{
67998 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67999 + enum fman_dma_err fsl_dma_err;
68000 +
68001 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68002 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68003 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68004 +
68005 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
68006 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
68007 +
68008 + return E_OK;
68009 +}
68010 +
68011 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
68012 +{
68013 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68014 + enum fman_catastrophic_err fsl_catastrophic_err;
68015 +
68016 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68017 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68018 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68019 +
68020 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
68021 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
68022 +
68023 + return E_OK;
68024 +}
68025 +
68026 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
68027 +{
68028 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68029 +
68030 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68031 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68032 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68033 +
68034 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68035 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68036 +
68037 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
68038 +
68039 + return E_OK;
68040 +}
68041 +
68042 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
68043 +{
68044 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68045 +
68046 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
68047 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68048 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68049 +
68050 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68051 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68052 +
68053 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
68054 +
68055 + return E_OK;
68056 +}
68057 +
68058 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
68059 +{
68060 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68061 +
68062 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68063 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68064 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68065 +
68066 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
68067 +
68068 + return E_OK;
68069 +}
68070 +
68071 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
68072 +{
68073 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68074 +
68075 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68076 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68077 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68078 +
68079 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68080 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68081 +
68082 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
68083 +
68084 + return E_OK;
68085 +}
68086 +
68087 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68088 +{
68089 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68090 + uint32_t bitMask = 0;
68091 +
68092 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68093 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68094 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68095 +
68096 + GET_EXCEPTION_FLAG(bitMask, exception);
68097 + if (bitMask)
68098 + {
68099 + if (enable)
68100 + p_Fm->userSetExceptions |= bitMask;
68101 + else
68102 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68103 + }
68104 + else
68105 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68106 +
68107 + return E_OK;
68108 +}
68109 +
68110 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
68111 +{
68112 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68113 +
68114 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68115 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68116 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68117 +
68118 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
68119 +
68120 + return E_OK;
68121 +}
68122 +
68123 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
68124 +{
68125 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68126 +
68127 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68128 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68129 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68130 +
68131 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
68132 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
68133 +
68134 + return E_OK;
68135 +}
68136 +
68137 +/****************************************************/
68138 +/* Hidden-DEBUG Only API */
68139 +/****************************************************/
68140 +
68141 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
68142 +{
68143 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68144 +
68145 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68146 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68147 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68148 +
68149 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
68150 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
68151 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
68152 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
68153 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
68154 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
68155 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
68156 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
68157 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
68158 +
68159 + return E_OK;
68160 +}
68161 +
68162 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
68163 +{
68164 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68165 +
68166 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68167 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68168 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68169 +
68170 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
68171 +
68172 + return E_OK;
68173 +}
68174 +
68175 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68176 +
68177 +{
68178 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68179 +
68180 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68181 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68182 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68183 +
68184 +#if (DPAA_VERSION >= 11)
68185 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68186 +#else
68187 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68188 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68189 +
68190 + return E_OK;
68191 +#endif
68192 +}
68193 +
68194 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68195 +{
68196 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68197 +
68198 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68199 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68200 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68201 +
68202 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68203 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68204 +
68205 + return E_OK;
68206 +}
68207 +
68208 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68209 +{
68210 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68211 +
68212 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68213 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68214 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68215 +
68216 +#if (DPAA_VERSION >= 11)
68217 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68218 +#else
68219 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68220 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68221 +
68222 + return E_OK;
68223 +#endif
68224 +}
68225 +
68226 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
68227 +{
68228 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68229 +
68230 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68231 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68232 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68233 +
68234 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
68235 +
68236 + return E_OK;
68237 +}
68238 +
68239 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
68240 +{
68241 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68242 +
68243 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68244 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68245 +UNUSED(p_Fm);
68246 +
68247 + return E_OK;
68248 +}
68249 +
68250 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
68251 +{
68252 + t_Fm* p_Fm = (t_Fm*)h_Fm;
68253 + if (p_Params->setParams.type & UPDATE_FM_CLD)
68254 + {
68255 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
68256 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
68257 + }
68258 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
68259 + {
68260 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68261 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
68262 + }
68263 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
68264 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
68265 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
68266 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
68267 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
68268 + {
68269 + if (p_Params->setParams.sleep)
68270 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68271 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
68272 + else
68273 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68274 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
68275 + }
68276 + if (p_Params->getParams.type & GET_FM_CLD)
68277 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
68278 + if (p_Params->getParams.type & GET_FMQM_GS)
68279 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
68280 + if (p_Params->getParams.type & GET_FM_NPI)
68281 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
68282 + if (p_Params->getParams.type & GET_FMFP_EXTC)
68283 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
68284 + return E_OK;
68285 +}
68286 +
68287 +
68288 +/****************************************************/
68289 +/* API Run-time Control uint functions */
68290 +/****************************************************/
68291 +void FM_EventIsr(t_Handle h_Fm)
68292 +{
68293 +#define FM_M_CALL_1G_MAC_ISR(_id) \
68294 + { \
68295 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
68296 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
68297 + else \
68298 + 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);\
68299 + }
68300 +#define FM_M_CALL_10G_MAC_ISR(_id) \
68301 + { \
68302 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
68303 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
68304 + else \
68305 + 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);\
68306 + }
68307 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68308 + uint32_t pending, event;
68309 + struct fman_fpm_regs *fpm_rg;
68310 +
68311 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68312 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68313 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68314 +
68315 + fpm_rg = p_Fm->p_FmFpmRegs;
68316 +
68317 + /* normal interrupts */
68318 + pending = fman_get_normal_pending(fpm_rg);
68319 + if (!pending)
68320 + return;
68321 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
68322 + {
68323 + t_FmGetSetParams fmGetSetParams;
68324 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
68325 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
68326 + fmGetSetParams.setParams.sleep = 0;
68327 + FmGetSetParams(h_Fm, &fmGetSetParams);
68328 + }
68329 + if (pending & INTR_EN_QMI)
68330 + QmiEvent(p_Fm);
68331 + if (pending & INTR_EN_PRS)
68332 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
68333 + if (pending & INTR_EN_PLCR)
68334 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
68335 + if (pending & INTR_EN_TMR)
68336 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
68337 +
68338 + /* MAC events may belong to different partitions */
68339 + if (pending & INTR_EN_1G_MAC0)
68340 + FM_M_CALL_1G_MAC_ISR(0);
68341 + if (pending & INTR_EN_1G_MAC1)
68342 + FM_M_CALL_1G_MAC_ISR(1);
68343 + if (pending & INTR_EN_1G_MAC2)
68344 + FM_M_CALL_1G_MAC_ISR(2);
68345 + if (pending & INTR_EN_1G_MAC3)
68346 + FM_M_CALL_1G_MAC_ISR(3);
68347 + if (pending & INTR_EN_1G_MAC4)
68348 + FM_M_CALL_1G_MAC_ISR(4);
68349 + if (pending & INTR_EN_1G_MAC5)
68350 + FM_M_CALL_1G_MAC_ISR(5);
68351 + if (pending & INTR_EN_1G_MAC6)
68352 + FM_M_CALL_1G_MAC_ISR(6);
68353 + if (pending & INTR_EN_1G_MAC7)
68354 + FM_M_CALL_1G_MAC_ISR(7);
68355 + if (pending & INTR_EN_10G_MAC0)
68356 + FM_M_CALL_10G_MAC_ISR(0);
68357 + if (pending & INTR_EN_10G_MAC1)
68358 + FM_M_CALL_10G_MAC_ISR(1);
68359 +
68360 + /* IM port events may belong to different partitions */
68361 + if (pending & INTR_EN_REV0)
68362 + {
68363 + event = fman_get_controller_event(fpm_rg, 0);
68364 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
68365 + /*TODO IPC ISR For Fman Ctrl */
68366 + ASSERT_COND(0);
68367 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
68368 + else
68369 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
68370 +
68371 + }
68372 + if (pending & INTR_EN_REV1)
68373 + {
68374 + event = fman_get_controller_event(fpm_rg, 1);
68375 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
68376 + /*TODO IPC ISR For Fman Ctrl */
68377 + ASSERT_COND(0);
68378 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
68379 + else
68380 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
68381 + }
68382 + if (pending & INTR_EN_REV2)
68383 + {
68384 + event = fman_get_controller_event(fpm_rg, 2);
68385 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
68386 + /*TODO IPC ISR For Fman Ctrl */
68387 + ASSERT_COND(0);
68388 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
68389 + else
68390 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
68391 + }
68392 + if (pending & INTR_EN_REV3)
68393 + {
68394 + event = fman_get_controller_event(fpm_rg, 3);
68395 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
68396 + /*TODO IPC ISR For Fman Ctrl */
68397 + ASSERT_COND(0);
68398 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
68399 + else
68400 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
68401 + }
68402 +#ifdef FM_MACSEC_SUPPORT
68403 + if (pending & INTR_EN_MACSEC_MAC0)
68404 + {
68405 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
68406 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
68407 + else
68408 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
68409 + }
68410 +#endif /* FM_MACSEC_SUPPORT */
68411 +}
68412 +
68413 +t_Error FM_ErrorIsr(t_Handle h_Fm)
68414 +{
68415 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
68416 + { \
68417 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
68418 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
68419 + else \
68420 + 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);\
68421 + }
68422 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
68423 + { \
68424 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
68425 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
68426 + else \
68427 + 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);\
68428 + }
68429 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68430 + uint32_t pending;
68431 + struct fman_fpm_regs *fpm_rg;
68432 +
68433 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
68434 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68435 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68436 +
68437 + fpm_rg = p_Fm->p_FmFpmRegs;
68438 +
68439 + /* error interrupts */
68440 + pending = fman_get_fpm_error_interrupts(fpm_rg);
68441 + if (!pending)
68442 + return ERROR_CODE(E_EMPTY);
68443 +
68444 + if (pending & ERR_INTR_EN_BMI)
68445 + BmiErrEvent(p_Fm);
68446 + if (pending & ERR_INTR_EN_QMI)
68447 + QmiErrEvent(p_Fm);
68448 + if (pending & ERR_INTR_EN_FPM)
68449 + FpmErrEvent(p_Fm);
68450 + if (pending & ERR_INTR_EN_DMA)
68451 + DmaErrEvent(p_Fm);
68452 + if (pending & ERR_INTR_EN_IRAM)
68453 + IramErrIntr(p_Fm);
68454 + if (pending & ERR_INTR_EN_MURAM)
68455 + MuramErrIntr(p_Fm);
68456 + if (pending & ERR_INTR_EN_PRS)
68457 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
68458 + if (pending & ERR_INTR_EN_PLCR)
68459 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
68460 + if (pending & ERR_INTR_EN_KG)
68461 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
68462 +
68463 + /* MAC events may belong to different partitions */
68464 + if (pending & ERR_INTR_EN_1G_MAC0)
68465 + FM_M_CALL_1G_MAC_ERR_ISR(0);
68466 + if (pending & ERR_INTR_EN_1G_MAC1)
68467 + FM_M_CALL_1G_MAC_ERR_ISR(1);
68468 + if (pending & ERR_INTR_EN_1G_MAC2)
68469 + FM_M_CALL_1G_MAC_ERR_ISR(2);
68470 + if (pending & ERR_INTR_EN_1G_MAC3)
68471 + FM_M_CALL_1G_MAC_ERR_ISR(3);
68472 + if (pending & ERR_INTR_EN_1G_MAC4)
68473 + FM_M_CALL_1G_MAC_ERR_ISR(4);
68474 + if (pending & ERR_INTR_EN_1G_MAC5)
68475 + FM_M_CALL_1G_MAC_ERR_ISR(5);
68476 + if (pending & ERR_INTR_EN_1G_MAC6)
68477 + FM_M_CALL_1G_MAC_ERR_ISR(6);
68478 + if (pending & ERR_INTR_EN_1G_MAC7)
68479 + FM_M_CALL_1G_MAC_ERR_ISR(7);
68480 + if (pending & ERR_INTR_EN_10G_MAC0)
68481 + FM_M_CALL_10G_MAC_ERR_ISR(0);
68482 + if (pending & ERR_INTR_EN_10G_MAC1)
68483 + FM_M_CALL_10G_MAC_ERR_ISR(1);
68484 +
68485 +#ifdef FM_MACSEC_SUPPORT
68486 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
68487 + {
68488 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
68489 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
68490 + else
68491 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
68492 + }
68493 +#endif /* FM_MACSEC_SUPPORT */
68494 +
68495 + return E_OK;
68496 +}
68497 +
68498 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
68499 +{
68500 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68501 + int i;
68502 + uint8_t sum;
68503 + uint8_t hardwarePortId;
68504 + uint8_t weights[64];
68505 + uint8_t weight, maxPercent = 0;
68506 + struct fman_bmi_regs *bmi_rg;
68507 +
68508 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68509 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68510 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68511 +
68512 + bmi_rg = p_Fm->p_FmBmiRegs;
68513 +
68514 + memset(weights, 0, (sizeof(uint8_t) * 64));
68515 +
68516 + /* check that all ports add up to 100% */
68517 + sum = 0;
68518 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68519 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
68520 + if (sum != 100)
68521 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
68522 +
68523 + /* find highest percent */
68524 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68525 + {
68526 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
68527 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
68528 + }
68529 +
68530 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
68531 +
68532 + /* calculate weight for each port */
68533 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68534 + {
68535 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
68536 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
68537 + is not reached, we round up so that:
68538 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
68539 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
68540 + ...
68541 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
68542 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
68543 + weight++;
68544 +
68545 + /* find the location of this port within the register */
68546 + hardwarePortId =
68547 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
68548 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
68549 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68550 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68551 +
68552 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68553 + weights[hardwarePortId] = weight;
68554 + }
68555 +
68556 + fman_set_ports_bandwidth(bmi_rg, weights);
68557 +
68558 + return E_OK;
68559 +}
68560 +
68561 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
68562 +{
68563 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68564 + struct fman_fpm_regs *fpm_rg;
68565 +
68566 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68567 +
68568 + fpm_rg = p_Fm->p_FmFpmRegs;
68569 +
68570 + if (p_Fm->guestId != NCSW_MASTER_ID)
68571 + {
68572 + t_FmIpcMsg msg;
68573 + t_Error err;
68574 +
68575 + memset(&msg, 0, sizeof(msg));
68576 + msg.msgId = FM_ENABLE_RAM_ECC;
68577 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68578 + (uint8_t*)&msg,
68579 + sizeof(msg.msgId),
68580 + NULL,
68581 + NULL,
68582 + NULL,
68583 + NULL);
68584 + if (err != E_OK)
68585 + RETURN_ERROR(MINOR, err, NO_MSG);
68586 + return E_OK;
68587 + }
68588 +
68589 + if (!p_Fm->p_FmStateStruct->internalCall)
68590 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
68591 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68592 +
68593 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
68594 + return E_OK;
68595 + else
68596 + {
68597 + fman_enable_rams_ecc(fpm_rg);
68598 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
68599 + }
68600 +
68601 + return E_OK;
68602 +}
68603 +
68604 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
68605 +{
68606 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68607 + bool explicitDisable = FALSE;
68608 + struct fman_fpm_regs *fpm_rg;
68609 +
68610 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68611 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68612 +
68613 + fpm_rg = p_Fm->p_FmFpmRegs;
68614 +
68615 + if (p_Fm->guestId != NCSW_MASTER_ID)
68616 + {
68617 + t_Error err;
68618 + t_FmIpcMsg msg;
68619 +
68620 + memset(&msg, 0, sizeof(msg));
68621 + msg.msgId = FM_DISABLE_RAM_ECC;
68622 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68623 + (uint8_t*)&msg,
68624 + sizeof(msg.msgId),
68625 + NULL,
68626 + NULL,
68627 + NULL,
68628 + NULL)) != E_OK)
68629 + RETURN_ERROR(MINOR, err, NO_MSG);
68630 + return E_OK;
68631 + }
68632 +
68633 + if (!p_Fm->p_FmStateStruct->internalCall)
68634 + explicitDisable = TRUE;
68635 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68636 +
68637 + /* if rams are already disabled, or if rams were explicitly enabled and are
68638 + currently called indirectly (not explicitly), ignore this call. */
68639 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
68640 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
68641 + return E_OK;
68642 + else
68643 + {
68644 + if (p_Fm->p_FmStateStruct->explicitEnable)
68645 + /* This is the case were both explicit are TRUE.
68646 + Turn off this flag for cases were following ramsEnable
68647 + routines are called */
68648 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
68649 +
68650 + fman_enable_rams_ecc(fpm_rg);
68651 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
68652 + }
68653 +
68654 + return E_OK;
68655 +}
68656 +
68657 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68658 +{
68659 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68660 + uint32_t bitMask = 0;
68661 + enum fman_exceptions fslException;
68662 + struct fman_rg fman_rg;
68663 +
68664 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68665 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68666 +
68667 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68668 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68669 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68670 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68671 +
68672 + GET_EXCEPTION_FLAG(bitMask, exception);
68673 + if (bitMask)
68674 + {
68675 + if (enable)
68676 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
68677 + else
68678 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68679 +
68680 + fslException = FmanExceptionTrans(exception);
68681 +
68682 + return (t_Error)fman_set_exception(&fman_rg,
68683 + fslException,
68684 + enable);
68685 + }
68686 + else
68687 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68688 +
68689 + return E_OK;
68690 +}
68691 +
68692 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
68693 +{
68694 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68695 +
68696 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
68697 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
68698 +
68699 + return E_OK;
68700 +}
68701 +
68702 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
68703 +{
68704 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68705 + t_FMIramRegs *p_Iram;
68706 + uint32_t revInfo;
68707 +
68708 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68709 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
68710 +
68711 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68712 + p_Fm->h_IpcSessions[0])
68713 + {
68714 + t_Error err;
68715 + t_FmIpcMsg msg;
68716 + t_FmIpcReply reply;
68717 + uint32_t replyLength;
68718 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
68719 +
68720 + memset(&msg, 0, sizeof(msg));
68721 + memset(&reply, 0, sizeof(reply));
68722 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
68723 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
68724 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68725 + (uint8_t*)&msg,
68726 + sizeof(msg.msgId),
68727 + (uint8_t*)&reply,
68728 + &replyLength,
68729 + NULL,
68730 + NULL)) != E_OK)
68731 + RETURN_ERROR(MINOR, err, NO_MSG);
68732 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
68733 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68734 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
68735 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
68736 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
68737 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
68738 + return (t_Error)(reply.error);
68739 + }
68740 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68741 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68742 + ("running in guest-mode without IPC!"));
68743 +
68744 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68745 + WRITE_UINT32(p_Iram->iadd, 0x4);
68746 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
68747 + revInfo = GET_UINT32(p_Iram->idata);
68748 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
68749 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
68750 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
68751 +
68752 + return E_OK;
68753 +}
68754 +
68755 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
68756 +{
68757 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68758 + t_Error err;
68759 + uint32_t counterValue;
68760 + struct fman_rg fman_rg;
68761 + enum fman_counters fsl_counter;
68762 +
68763 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
68764 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
68765 +
68766 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68767 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68768 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68769 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68770 +
68771 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68772 + !p_Fm->baseAddr &&
68773 + p_Fm->h_IpcSessions[0])
68774 + {
68775 + t_FmIpcMsg msg;
68776 + t_FmIpcReply reply;
68777 + uint32_t replyLength, outCounter;
68778 +
68779 + memset(&msg, 0, sizeof(msg));
68780 + memset(&reply, 0, sizeof(reply));
68781 + msg.msgId = FM_GET_COUNTER;
68782 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
68783 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
68784 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68785 + (uint8_t*)&msg,
68786 + sizeof(msg.msgId) +sizeof(counterValue),
68787 + (uint8_t*)&reply,
68788 + &replyLength,
68789 + NULL,
68790 + NULL);
68791 + if (err != E_OK)
68792 + {
68793 + REPORT_ERROR(MAJOR, err, NO_MSG);
68794 + return 0;
68795 + }
68796 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
68797 + {
68798 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68799 + return 0;
68800 + }
68801 +
68802 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
68803 + return outCounter;
68804 + }
68805 + else if (!p_Fm->baseAddr)
68806 + {
68807 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
68808 + return 0;
68809 + }
68810 +
68811 + /* When applicable (when there is an 'enable counters' bit,
68812 + check that counters are enabled */
68813 + switch (counter)
68814 + {
68815 + case (e_FM_COUNTERS_DEQ_1):
68816 + case (e_FM_COUNTERS_DEQ_2):
68817 + case (e_FM_COUNTERS_DEQ_3):
68818 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
68819 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
68820 + {
68821 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
68822 + return 0;
68823 + }
68824 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
68825 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
68826 + case (e_FM_COUNTERS_DEQ_0):
68827 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
68828 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
68829 + case (e_FM_COUNTERS_DEQ_FROM_FD):
68830 + case (e_FM_COUNTERS_DEQ_CONFIRM):
68831 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
68832 + {
68833 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
68834 + return 0;
68835 + }
68836 + break;
68837 + default:
68838 + break;
68839 + }
68840 +
68841 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
68842 + return fman_get_counter(&fman_rg, fsl_counter);
68843 +}
68844 +
68845 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
68846 +{
68847 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68848 + struct fman_rg fman_rg;
68849 + enum fman_counters fsl_counter;
68850 +
68851 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68852 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68853 +
68854 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68855 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68856 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68857 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68858 +
68859 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
68860 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
68861 +}
68862 +
68863 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
68864 +{
68865 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68866 + struct fman_dma_regs *dma_rg;
68867 +
68868 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68869 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68870 +
68871 + dma_rg = p_Fm->p_FmDmaRegs;
68872 +
68873 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
68874 +}
68875 +
68876 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
68877 +{
68878 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68879 + struct fman_dma_regs *dma_rg;
68880 +
68881 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68882 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68883 +
68884 + dma_rg = p_Fm->p_FmDmaRegs;
68885 +
68886 + fman_set_dma_ext_bus_pri(dma_rg, pri);
68887 +}
68888 +
68889 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
68890 +{
68891 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68892 + uint32_t dmaStatus;
68893 + struct fman_dma_regs *dma_rg;
68894 +
68895 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68896 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68897 +
68898 + dma_rg = p_Fm->p_FmDmaRegs;
68899 +
68900 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68901 + !p_Fm->baseAddr &&
68902 + p_Fm->h_IpcSessions[0])
68903 + {
68904 + t_FmIpcDmaStatus ipcDmaStatus;
68905 + t_FmIpcMsg msg;
68906 + t_FmIpcReply reply;
68907 + t_Error err;
68908 + uint32_t replyLength;
68909 +
68910 + memset(&msg, 0, sizeof(msg));
68911 + memset(&reply, 0, sizeof(reply));
68912 + msg.msgId = FM_DMA_STAT;
68913 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
68914 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68915 + (uint8_t*)&msg,
68916 + sizeof(msg.msgId),
68917 + (uint8_t*)&reply,
68918 + &replyLength,
68919 + NULL,
68920 + NULL);
68921 + if (err != E_OK)
68922 + {
68923 + REPORT_ERROR(MINOR, err, NO_MSG);
68924 + return;
68925 + }
68926 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
68927 + {
68928 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68929 + return;
68930 + }
68931 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
68932 +
68933 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
68934 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
68935 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
68936 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
68937 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
68938 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
68939 + return;
68940 + }
68941 + else if (!p_Fm->baseAddr)
68942 + {
68943 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
68944 + ("Either IPC or 'baseAddress' is required!"));
68945 + return;
68946 + }
68947 +
68948 + dmaStatus = fman_get_dma_status(dma_rg);
68949 +
68950 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
68951 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
68952 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68953 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
68954 + else
68955 + {
68956 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
68957 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
68958 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
68959 + }
68960 +}
68961 +
68962 +void FM_Resume(t_Handle h_Fm)
68963 +{
68964 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68965 + struct fman_fpm_regs *fpm_rg;
68966 +
68967 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68968 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68969 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68970 +
68971 + fpm_rg = p_Fm->p_FmFpmRegs;
68972 +
68973 + fman_resume(fpm_rg);
68974 +}
68975 +
68976 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
68977 + fmSpecialOperations_t spOper,
68978 + uint8_t *p_SpOperCoding)
68979 +{
68980 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68981 + t_FmCtrlCodeRevisionInfo revInfo;
68982 + t_Error err;
68983 +
68984 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68985 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68986 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
68987 +
68988 + if (!spOper)
68989 + {
68990 + *p_SpOperCoding = 0;
68991 + return E_OK;
68992 + }
68993 +
68994 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
68995 + {
68996 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
68997 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
68998 + }
68999 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
69000 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
69001 +
69002 + switch (spOper)
69003 + {
69004 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
69005 + *p_SpOperCoding = 9;
69006 + break;
69007 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
69008 + *p_SpOperCoding = 10;
69009 + break;
69010 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
69011 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69012 + *p_SpOperCoding = 5;
69013 + break;
69014 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
69015 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69016 + *p_SpOperCoding = 6;
69017 + break;
69018 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
69019 + *p_SpOperCoding = 3;
69020 + break;
69021 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
69022 + *p_SpOperCoding = 1;
69023 + break;
69024 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
69025 + *p_SpOperCoding = 12;
69026 + break;
69027 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
69028 + *p_SpOperCoding = 4;
69029 + break;
69030 + case (FM_SP_OP_IPSEC):
69031 + *p_SpOperCoding = 2;
69032 + break;
69033 + case (FM_SP_OP_DCL4C):
69034 + *p_SpOperCoding = 7;
69035 + break;
69036 + case (FM_SP_OP_CLEAR_RPD):
69037 + *p_SpOperCoding = 8;
69038 + break;
69039 + default:
69040 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
69041 + }
69042 +
69043 + return E_OK;
69044 +}
69045 +
69046 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
69047 +{
69048 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69049 + t_FmTrbRegs *p_MonRegs;
69050 + uint8_t i;
69051 +
69052 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69053 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69054 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69055 +
69056 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69057 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
69058 +
69059 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69060 + {
69061 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69062 +
69063 + /* Reset control registers */
69064 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
69065 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
69066 +
69067 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
69068 + counter #2 counts all stalls in risc - other stall*/
69069 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
69070 +
69071 + /* Enable monitoring */
69072 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
69073 + }
69074 +
69075 + return E_OK;
69076 +}
69077 +
69078 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
69079 +{
69080 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69081 + t_FmTrbRegs *p_MonRegs;
69082 + uint8_t i;
69083 +
69084 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69085 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69086 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69087 +
69088 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69089 + {
69090 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69091 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
69092 + }
69093 +
69094 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69095 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
69096 +
69097 + return E_OK;
69098 +}
69099 +
69100 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
69101 +{
69102 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69103 + t_FmTrbRegs *p_MonRegs;
69104 + uint64_t clkCnt, utilValue, effValue;
69105 +
69106 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69107 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69108 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69109 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
69110 +
69111 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
69112 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
69113 +
69114 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
69115 +
69116 + clkCnt = (uint64_t)
69117 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
69118 +
69119 + utilValue = (uint64_t)
69120 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
69121 +
69122 + effValue = (uint64_t)
69123 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
69124 +
69125 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
69126 + if (clkCnt != utilValue)
69127 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
69128 + else
69129 + p_Mon->percentCnt[1] = 0;
69130 +
69131 + return E_OK;
69132 +}
69133 +
69134 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
69135 +{
69136 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69137 +
69138 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
69139 +
69140 + return (p_Fm->h_FmMuram);
69141 +}
69142 +
69143 +/****************************************************/
69144 +/* Hidden-DEBUG Only API */
69145 +/****************************************************/
69146 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
69147 +{
69148 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69149 + enum fman_exceptions fslException;
69150 + struct fman_rg fman_rg;
69151 +
69152 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69153 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69154 +
69155 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69156 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69157 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69158 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69159 +
69160 + switch (exception)
69161 + {
69162 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69163 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
69164 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69165 + break;
69166 + case e_FM_EX_QMI_SINGLE_ECC:
69167 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69168 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
69169 +
69170 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
69171 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69172 + break;
69173 + case e_FM_EX_QMI_DOUBLE_ECC:
69174 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
69175 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69176 + break;
69177 + case e_FM_EX_BMI_LIST_RAM_ECC:
69178 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
69179 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69180 + break;
69181 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69182 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
69183 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69184 + break;
69185 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69186 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
69187 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69188 + break;
69189 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69190 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
69191 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69192 + break;
69193 + default:
69194 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
69195 + }
69196 +
69197 + fslException = FmanExceptionTrans(exception);
69198 + fman_force_intr (&fman_rg, fslException);
69199 +
69200 + return E_OK;
69201 +}
69202 +
69203 +t_Handle FmGetPcd(t_Handle h_Fm)
69204 +{
69205 + return ((t_Fm*)h_Fm)->h_Pcd;
69206 +}
69207 +#if (DPAA_VERSION >= 11)
69208 +extern void *g_MemacRegs;
69209 +void fm_clk_down(void);
69210 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
69211 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
69212 +{
69213 + int macId;
69214 + uint32_t event, rcr;
69215 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69216 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69217 + rcr |= 0x04000000;
69218 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69219 +
69220 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
69221 + do
69222 + {
69223 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
69224 + } while ((event & 0x00000020) == 0);
69225 + fm_clk_down();
69226 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69227 + rcr &= ~0x04000000;
69228 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69229 +}
69230 +#endif
69231 --- /dev/null
69232 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69233 @@ -0,0 +1,648 @@
69234 +/*
69235 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69236 + *
69237 + * Redistribution and use in source and binary forms, with or without
69238 + * modification, are permitted provided that the following conditions are met:
69239 + * * Redistributions of source code must retain the above copyright
69240 + * notice, this list of conditions and the following disclaimer.
69241 + * * Redistributions in binary form must reproduce the above copyright
69242 + * notice, this list of conditions and the following disclaimer in the
69243 + * documentation and/or other materials provided with the distribution.
69244 + * * Neither the name of Freescale Semiconductor nor the
69245 + * names of its contributors may be used to endorse or promote products
69246 + * derived from this software without specific prior written permission.
69247 + *
69248 + *
69249 + * ALTERNATIVELY, this software may be distributed under the terms of the
69250 + * GNU General Public License ("GPL") as published by the Free Software
69251 + * Foundation, either version 2 of that License or (at your option) any
69252 + * later version.
69253 + *
69254 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69255 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69256 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69257 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69258 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69259 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69260 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69261 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69262 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69263 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69264 + */
69265 +
69266 +
69267 +/******************************************************************************
69268 + @File fm.h
69269 +
69270 + @Description FM internal structures and definitions.
69271 +*//***************************************************************************/
69272 +#ifndef __FM_H
69273 +#define __FM_H
69274 +
69275 +#include "error_ext.h"
69276 +#include "std_ext.h"
69277 +#include "fm_ext.h"
69278 +#include "fm_ipc.h"
69279 +
69280 +#include "fsl_fman.h"
69281 +
69282 +#define __ERR_MODULE__ MODULE_FM
69283 +
69284 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
69285 +#define FM_MAX_NUM_OF_GUESTS 100
69286 +
69287 +/**************************************************************************//**
69288 + @Description Exceptions
69289 +*//***************************************************************************/
69290 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
69291 +#define FM_EX_DMA_READ_ECC 0x40000000
69292 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
69293 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
69294 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
69295 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
69296 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
69297 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
69298 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
69299 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
69300 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
69301 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
69302 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
69303 +#define FM_EX_IRAM_ECC 0x00040000
69304 +#define FM_EX_MURAM_ECC 0x00020000
69305 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
69306 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
69307 +
69308 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
69309 +
69310 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
69311 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
69312 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
69313 +
69314 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
69315 +switch (exception){ \
69316 + case e_FM_EX_DMA_BUS_ERROR: \
69317 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
69318 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
69319 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
69320 + case e_FM_EX_DMA_READ_ECC: \
69321 + bitMask = FM_EX_DMA_READ_ECC; break; \
69322 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
69323 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
69324 + case e_FM_EX_DMA_FM_WRITE_ECC: \
69325 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
69326 + case e_FM_EX_FPM_STALL_ON_TASKS: \
69327 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
69328 + case e_FM_EX_FPM_SINGLE_ECC: \
69329 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
69330 + case e_FM_EX_FPM_DOUBLE_ECC: \
69331 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
69332 + case e_FM_EX_QMI_SINGLE_ECC: \
69333 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
69334 + case e_FM_EX_QMI_DOUBLE_ECC: \
69335 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
69336 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
69337 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
69338 + case e_FM_EX_BMI_LIST_RAM_ECC: \
69339 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
69340 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
69341 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
69342 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
69343 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
69344 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
69345 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
69346 + case e_FM_EX_IRAM_ECC: \
69347 + bitMask = FM_EX_IRAM_ECC; break; \
69348 + case e_FM_EX_MURAM_ECC: \
69349 + bitMask = FM_EX_MURAM_ECC; break; \
69350 + default: bitMask = 0;break; \
69351 +}
69352 +
69353 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
69354 + switch (_mod) { \
69355 + case e_FM_MOD_PRS: \
69356 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69357 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
69358 + break; \
69359 + case e_FM_MOD_KG: \
69360 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69361 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
69362 + break; \
69363 + case e_FM_MOD_PLCR: \
69364 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69365 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
69366 + break; \
69367 + case e_FM_MOD_TMR: \
69368 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69369 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
69370 + break; \
69371 + case e_FM_MOD_10G_MAC: \
69372 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69373 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
69374 + break; \
69375 + case e_FM_MOD_1G_MAC: \
69376 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69377 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
69378 + break; \
69379 + case e_FM_MOD_MACSEC: \
69380 + switch (_id){ \
69381 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
69382 + break; \
69383 + } \
69384 + break; \
69385 + case e_FM_MOD_FMAN_CTRL: \
69386 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
69387 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
69388 + break; \
69389 + default: _event = e_FM_EV_DUMMY_LAST; \
69390 + break; \
69391 + }
69392 +
69393 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
69394 + switch (_cache_override){ \
69395 + case e_FM_DMA_NO_CACHE_OR: \
69396 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69397 + case e_FM_DMA_NO_STASH_DATA: \
69398 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
69399 + case e_FM_DMA_MAY_STASH_DATA: \
69400 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
69401 + case e_FM_DMA_STASH_DATA: \
69402 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
69403 + default: \
69404 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69405 + }
69406 +
69407 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
69408 + switch (_aid_mode){ \
69409 + case e_FM_DMA_AID_OUT_PORT_ID: \
69410 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69411 + case e_FM_DMA_AID_OUT_TNUM: \
69412 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
69413 + default: \
69414 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69415 + }
69416 +
69417 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
69418 + switch (_dma_dbg_cnt){ \
69419 + case e_FM_DMA_DBG_NO_CNT: \
69420 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69421 + case e_FM_DMA_DBG_CNT_DONE: \
69422 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
69423 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
69424 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
69425 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
69426 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
69427 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
69428 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
69429 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
69430 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
69431 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
69432 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
69433 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
69434 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
69435 + default: \
69436 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69437 + }
69438 +
69439 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
69440 + switch (_dma_emer){ \
69441 + case e_FM_DMA_EM_EBS: \
69442 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69443 + case e_FM_DMA_EM_SOS: \
69444 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
69445 + default: \
69446 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69447 + }
69448 +
69449 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
69450 + switch (_dma_err){ \
69451 + case e_FM_DMA_ERR_CATASTROPHIC: \
69452 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69453 + case e_FM_DMA_ERR_REPORT: \
69454 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
69455 + default: \
69456 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69457 + }
69458 +
69459 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
69460 + switch (_catastrophic_err){ \
69461 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
69462 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69463 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
69464 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
69465 + default: \
69466 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69467 + }
69468 +
69469 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
69470 + switch (_counters){ \
69471 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
69472 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69473 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
69474 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
69475 + case e_FM_COUNTERS_DEQ_0: \
69476 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
69477 + case e_FM_COUNTERS_DEQ_1: \
69478 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
69479 + case e_FM_COUNTERS_DEQ_2: \
69480 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
69481 + case e_FM_COUNTERS_DEQ_3: \
69482 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
69483 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
69484 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
69485 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
69486 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
69487 + case e_FM_COUNTERS_DEQ_FROM_FD: \
69488 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
69489 + case e_FM_COUNTERS_DEQ_CONFIRM: \
69490 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
69491 + default: \
69492 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69493 + }
69494 +
69495 +/**************************************************************************//**
69496 + @Description defaults
69497 +*//***************************************************************************/
69498 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
69499 + FM_EX_DMA_READ_ECC |\
69500 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
69501 + FM_EX_DMA_FM_WRITE_ECC |\
69502 + FM_EX_FPM_STALL_ON_TASKS |\
69503 + FM_EX_FPM_SINGLE_ECC |\
69504 + FM_EX_FPM_DOUBLE_ECC |\
69505 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
69506 + FM_EX_BMI_LIST_RAM_ECC |\
69507 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
69508 + FM_EX_BMI_STATISTICS_RAM_ECC |\
69509 + FM_EX_IRAM_ECC |\
69510 + FM_EX_MURAM_ECC |\
69511 + FM_EX_BMI_DISPATCH_RAM_ECC |\
69512 + FM_EX_QMI_DOUBLE_ECC |\
69513 + FM_EX_QMI_SINGLE_ECC)
69514 +
69515 +#define DEFAULT_eccEnable FALSE
69516 +#ifdef FM_PEDANTIC_DMA
69517 +#define DEFAULT_aidOverride TRUE
69518 +#else
69519 +#define DEFAULT_aidOverride FALSE
69520 +#endif /* FM_PEDANTIC_DMA */
69521 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
69522 +#define DEFAULT_dmaStopOnBusError FALSE
69523 +#define DEFAULT_stopAtBusError FALSE
69524 +#define DEFAULT_axiDbgNumOfBeats 1
69525 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69526 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69527 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69528 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69529 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
69530 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
69531 +#define DEFAULT_resetOnInit FALSE
69532 +#define DEFAULT_resetOnInitOverrideCallback NULL
69533 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
69534 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
69535 +#define DEFAULT_externalEccRamsEnable FALSE
69536 +#define DEFAULT_VerifyUcode FALSE
69537 +
69538 +#if (DPAA_VERSION < 11)
69539 +#define DEFAULT_totalFifoSize(major, minor) \
69540 + (((major == 2) || (major == 5)) ? \
69541 + (100*KILOBYTE) : ((major == 4) ? \
69542 + (49*KILOBYTE) : (122*KILOBYTE)))
69543 +#define DEFAULT_totalNumOfTasks(major, minor) \
69544 + BMI_MAX_NUM_OF_TASKS
69545 +
69546 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
69547 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
69548 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69549 +#define DEFAULT_dmaCamNumOfEntries 32
69550 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69551 +#define DEFAULT_dmaEnEmergency FALSE
69552 +#define DEFAULT_dmaSosEmergency 0
69553 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69554 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69555 +#define DEFAULT_dmaEmergencySwitchCounter 0
69556 +
69557 +#define DEFAULT_dispLimit 0
69558 +#define DEFAULT_prsDispTh 16
69559 +#define DEFAULT_plcrDispTh 16
69560 +#define DEFAULT_kgDispTh 16
69561 +#define DEFAULT_bmiDispTh 16
69562 +#define DEFAULT_qmiEnqDispTh 16
69563 +#define DEFAULT_qmiDeqDispTh 16
69564 +#define DEFAULT_fmCtl1DispTh 16
69565 +#define DEFAULT_fmCtl2DispTh 16
69566 +
69567 +#else /* (DPAA_VERSION < 11) */
69568 +/* Defaults are registers' reset values */
69569 +#define DEFAULT_totalFifoSize(major, minor) \
69570 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
69571 + (156*KILOBYTE) : (295*KILOBYTE))
69572 +
69573 +/* According to the default value of FMBM_CFG2[TNTSKS] */
69574 +#define DEFAULT_totalNumOfTasks(major, minor) \
69575 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
69576 +
69577 +#define DEFAULT_dmaCommQLow 0x2A
69578 +#define DEFAULT_dmaCommQHigh 0x3F
69579 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69580 +#define DEFAULT_dmaCamNumOfEntries 64
69581 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69582 +#define DEFAULT_dmaEnEmergency FALSE
69583 +#define DEFAULT_dmaSosEmergency 0
69584 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69585 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69586 +#define DEFAULT_dmaEmergencySwitchCounter 0
69587 +
69588 +#define DEFAULT_dispLimit 0
69589 +#define DEFAULT_prsDispTh 16
69590 +#define DEFAULT_plcrDispTh 16
69591 +#define DEFAULT_kgDispTh 16
69592 +#define DEFAULT_bmiDispTh 16
69593 +#define DEFAULT_qmiEnqDispTh 16
69594 +#define DEFAULT_qmiDeqDispTh 16
69595 +#define DEFAULT_fmCtl1DispTh 16
69596 +#define DEFAULT_fmCtl2DispTh 16
69597 +#endif /* (DPAA_VERSION < 11) */
69598 +
69599 +#define FM_TIMESTAMP_1_USEC_BIT 8
69600 +
69601 +/**************************************************************************//**
69602 + @Collection Defines used for enabling/disabling FM interrupts
69603 + @{
69604 +*//***************************************************************************/
69605 +#define ERR_INTR_EN_DMA 0x00010000
69606 +#define ERR_INTR_EN_FPM 0x80000000
69607 +#define ERR_INTR_EN_BMI 0x00800000
69608 +#define ERR_INTR_EN_QMI 0x00400000
69609 +#define ERR_INTR_EN_PRS 0x00200000
69610 +#define ERR_INTR_EN_KG 0x00100000
69611 +#define ERR_INTR_EN_PLCR 0x00080000
69612 +#define ERR_INTR_EN_MURAM 0x00040000
69613 +#define ERR_INTR_EN_IRAM 0x00020000
69614 +#define ERR_INTR_EN_10G_MAC0 0x00008000
69615 +#define ERR_INTR_EN_10G_MAC1 0x00000040
69616 +#define ERR_INTR_EN_1G_MAC0 0x00004000
69617 +#define ERR_INTR_EN_1G_MAC1 0x00002000
69618 +#define ERR_INTR_EN_1G_MAC2 0x00001000
69619 +#define ERR_INTR_EN_1G_MAC3 0x00000800
69620 +#define ERR_INTR_EN_1G_MAC4 0x00000400
69621 +#define ERR_INTR_EN_1G_MAC5 0x00000200
69622 +#define ERR_INTR_EN_1G_MAC6 0x00000100
69623 +#define ERR_INTR_EN_1G_MAC7 0x00000080
69624 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
69625 +
69626 +#define INTR_EN_QMI 0x40000000
69627 +#define INTR_EN_PRS 0x20000000
69628 +#define INTR_EN_WAKEUP 0x10000000
69629 +#define INTR_EN_PLCR 0x08000000
69630 +#define INTR_EN_1G_MAC0 0x00080000
69631 +#define INTR_EN_1G_MAC1 0x00040000
69632 +#define INTR_EN_1G_MAC2 0x00020000
69633 +#define INTR_EN_1G_MAC3 0x00010000
69634 +#define INTR_EN_1G_MAC4 0x00000040
69635 +#define INTR_EN_1G_MAC5 0x00000020
69636 +#define INTR_EN_1G_MAC6 0x00000008
69637 +#define INTR_EN_1G_MAC7 0x00000002
69638 +#define INTR_EN_10G_MAC0 0x00200000
69639 +#define INTR_EN_10G_MAC1 0x00100000
69640 +#define INTR_EN_REV0 0x00008000
69641 +#define INTR_EN_REV1 0x00004000
69642 +#define INTR_EN_REV2 0x00002000
69643 +#define INTR_EN_REV3 0x00001000
69644 +#define INTR_EN_BRK 0x00000080
69645 +#define INTR_EN_TMR 0x01000000
69646 +#define INTR_EN_MACSEC_MAC0 0x00000001
69647 +/* @} */
69648 +
69649 +/**************************************************************************//**
69650 + @Description Memory Mapped Registers
69651 +*//***************************************************************************/
69652 +
69653 +#if defined(__MWERKS__) && !defined(__GNUC__)
69654 +#pragma pack(push,1)
69655 +#endif /* defined(__MWERKS__) && ... */
69656 +
69657 +typedef struct
69658 +{
69659 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
69660 + volatile uint32_t idata; /**< FM IRAM instruction data register */
69661 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
69662 + volatile uint32_t iready; /**< FM IRAM ready register */
69663 + volatile uint32_t res[0x1FFFC];
69664 +} t_FMIramRegs;
69665 +
69666 +/* Trace buffer registers -
69667 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
69668 +typedef struct t_FmTrbRegs
69669 +{
69670 + volatile uint32_t tcrh;
69671 + volatile uint32_t tcrl;
69672 + volatile uint32_t tesr;
69673 + volatile uint32_t tecr0h;
69674 + volatile uint32_t tecr0l;
69675 + volatile uint32_t terf0h;
69676 + volatile uint32_t terf0l;
69677 + volatile uint32_t tecr1h;
69678 + volatile uint32_t tecr1l;
69679 + volatile uint32_t terf1h;
69680 + volatile uint32_t terf1l;
69681 + volatile uint32_t tpcch;
69682 + volatile uint32_t tpccl;
69683 + volatile uint32_t tpc1h;
69684 + volatile uint32_t tpc1l;
69685 + volatile uint32_t tpc2h;
69686 + volatile uint32_t tpc2l;
69687 + volatile uint32_t twdimr;
69688 + volatile uint32_t twicvr;
69689 + volatile uint32_t tar;
69690 + volatile uint32_t tdr;
69691 + volatile uint32_t tsnum1;
69692 + volatile uint32_t tsnum2;
69693 + volatile uint32_t tsnum3;
69694 + volatile uint32_t tsnum4;
69695 +} t_FmTrbRegs;
69696 +
69697 +#if defined(__MWERKS__) && !defined(__GNUC__)
69698 +#pragma pack(pop)
69699 +#endif /* defined(__MWERKS__) && ... */
69700 +
69701 +/**************************************************************************//**
69702 + @Description General defines
69703 +*//***************************************************************************/
69704 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
69705 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
69706 +
69707 +/**************************************************************************//**
69708 + @Description FPM defines
69709 +*//***************************************************************************/
69710 +/* masks */
69711 +#define FPM_BRKC_RDBG 0x00000200
69712 +#define FPM_BRKC_SLP 0x00000800
69713 +/**************************************************************************//**
69714 + @Description BMI defines
69715 +*//***************************************************************************/
69716 +/* masks */
69717 +#define BMI_INIT_START 0x80000000
69718 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
69719 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
69720 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
69721 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
69722 +/**************************************************************************//**
69723 + @Description QMI defines
69724 +*//***************************************************************************/
69725 +/* masks */
69726 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
69727 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
69728 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
69729 +
69730 +/**************************************************************************//**
69731 + @Description IRAM defines
69732 +*//***************************************************************************/
69733 +/* masks */
69734 +#define IRAM_IADD_AIE 0x80000000
69735 +#define IRAM_READY 0x80000000
69736 +
69737 +/**************************************************************************//**
69738 + @Description TRB defines
69739 +*//***************************************************************************/
69740 +/* masks */
69741 +#define TRB_TCRH_RESET 0x04000000
69742 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
69743 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
69744 +#define TRB_TCRL_RESET 0x20000000
69745 +#define TRB_TCRL_UTIL 0x00000460
69746 +typedef struct {
69747 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
69748 + t_Handle h_SrcHandle;
69749 +} t_FmanCtrlIntrSrc;
69750 +
69751 +
69752 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
69753 +
69754 +typedef struct
69755 +{
69756 +/***************************/
69757 +/* Master/Guest parameters */
69758 +/***************************/
69759 + uint8_t fmId;
69760 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
69761 + uint16_t fmClkFreq;
69762 + uint16_t fmMacClkFreq;
69763 + t_FmRevisionInfo revInfo;
69764 +/**************************/
69765 +/* Master Only parameters */
69766 +/**************************/
69767 + bool enabledTimeStamp;
69768 + uint8_t count1MicroBit;
69769 + uint8_t totalNumOfTasks;
69770 + uint32_t totalFifoSize;
69771 + uint8_t maxNumOfOpenDmas;
69772 + uint8_t accumulatedNumOfTasks;
69773 + uint32_t accumulatedFifoSize;
69774 + uint8_t accumulatedNumOfOpenDmas;
69775 + uint8_t accumulatedNumOfDeqTnums;
69776 +#ifdef FM_LOW_END_RESTRICTION
69777 + bool lowEndRestriction;
69778 +#endif /* FM_LOW_END_RESTRICTION */
69779 + uint32_t exceptions;
69780 + int irq;
69781 + int errIrq;
69782 + bool ramsEccEnable;
69783 + bool explicitEnable;
69784 + bool internalCall;
69785 + uint8_t ramsEccOwners;
69786 + uint32_t extraFifoPoolSize;
69787 + uint8_t extraTasksPoolSize;
69788 + uint8_t extraOpenDmasPoolSize;
69789 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
69790 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
69791 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
69792 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
69793 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
69794 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
69795 +} t_FmStateStruct;
69796 +
69797 +#if (DPAA_VERSION >= 11)
69798 +typedef struct t_FmMapParam {
69799 + uint16_t profilesBase;
69800 + uint16_t numOfProfiles;
69801 + t_Handle h_FmPort;
69802 +} t_FmMapParam;
69803 +
69804 +typedef struct t_FmAllocMng {
69805 + bool allocated;
69806 + uint8_t ownerId; /* guestId for KG in multi-partition only,
69807 + portId for PLCR in any environment */
69808 +} t_FmAllocMng;
69809 +
69810 +typedef struct t_FmPcdSpEntry {
69811 + bool valid;
69812 + t_FmAllocMng profilesMng;
69813 +} t_FmPcdSpEntry;
69814 +
69815 +typedef struct t_FmSp {
69816 + void *p_FmPcdStoragePrflRegs;
69817 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
69818 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
69819 +} t_FmSp;
69820 +#endif /* (DPAA_VERSION >= 11) */
69821 +
69822 +typedef struct t_Fm
69823 +{
69824 +/***************************/
69825 +/* Master/Guest parameters */
69826 +/***************************/
69827 +/* locals for recovery */
69828 + uintptr_t baseAddr;
69829 +
69830 +/* un-needed for recovery */
69831 + t_Handle h_Pcd;
69832 + char fmModuleName[MODULE_NAME_SIZE];
69833 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
69834 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
69835 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
69836 + uint8_t guestId;
69837 +/**************************/
69838 +/* Master Only parameters */
69839 +/**************************/
69840 +/* locals for recovery */
69841 + struct fman_fpm_regs *p_FmFpmRegs;
69842 + struct fman_bmi_regs *p_FmBmiRegs;
69843 + struct fman_qmi_regs *p_FmQmiRegs;
69844 + struct fman_dma_regs *p_FmDmaRegs;
69845 + struct fman_regs *p_FmRegs;
69846 + t_FmExceptionsCallback *f_Exception;
69847 + t_FmBusErrorCallback *f_BusError;
69848 + t_Handle h_App; /* Application handle */
69849 + t_Handle h_Spinlock;
69850 + bool recoveryMode;
69851 + t_FmStateStruct *p_FmStateStruct;
69852 + uint16_t tnumAgingPeriod;
69853 +#if (DPAA_VERSION >= 11)
69854 + t_FmSp *p_FmSp;
69855 + uint8_t partNumOfVSPs;
69856 + uint8_t partVSPBase;
69857 + uintptr_t vspBaseAddr;
69858 +#endif /* (DPAA_VERSION >= 11) */
69859 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
69860 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
69861 +
69862 +/* un-needed for recovery */
69863 + struct fman_cfg *p_FmDriverParam;
69864 + t_Handle h_FmMuram;
69865 + uint64_t fmMuramPhysBaseAddr;
69866 + bool independentMode;
69867 + bool hcPortInitialized;
69868 + uintptr_t camBaseAddr; /* save for freeing */
69869 + uintptr_t resAddr;
69870 + uintptr_t fifoBaseAddr; /* save for freeing */
69871 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
69872 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
69873 + t_FmFirmwareParams firmware;
69874 + bool fwVerify;
69875 + bool resetOnInit;
69876 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
69877 + uint32_t userSetExceptions;
69878 +} t_Fm;
69879 +
69880 +
69881 +#endif /* __FM_H */
69882 --- /dev/null
69883 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
69884 @@ -0,0 +1,465 @@
69885 +/*
69886 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69887 + *
69888 + * Redistribution and use in source and binary forms, with or without
69889 + * modification, are permitted provided that the following conditions are met:
69890 + * * Redistributions of source code must retain the above copyright
69891 + * notice, this list of conditions and the following disclaimer.
69892 + * * Redistributions in binary form must reproduce the above copyright
69893 + * notice, this list of conditions and the following disclaimer in the
69894 + * documentation and/or other materials provided with the distribution.
69895 + * * Neither the name of Freescale Semiconductor nor the
69896 + * names of its contributors may be used to endorse or promote products
69897 + * derived from this software without specific prior written permission.
69898 + *
69899 + *
69900 + * ALTERNATIVELY, this software may be distributed under the terms of the
69901 + * GNU General Public License ("GPL") as published by the Free Software
69902 + * Foundation, either version 2 of that License or (at your option) any
69903 + * later version.
69904 + *
69905 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69906 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69907 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69908 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69909 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69910 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69911 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69912 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69913 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69914 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69915 + */
69916 +
69917 +
69918 +/**************************************************************************//**
69919 + @File fm_ipc.h
69920 +
69921 + @Description FM Inter-Partition prototypes, structures and definitions.
69922 +*//***************************************************************************/
69923 +#ifndef __FM_IPC_H
69924 +#define __FM_IPC_H
69925 +
69926 +#include "error_ext.h"
69927 +#include "std_ext.h"
69928 +
69929 +
69930 +/**************************************************************************//**
69931 + @Group FM_grp Frame Manager API
69932 +
69933 + @Description FM API functions, definitions and enums
69934 +
69935 + @{
69936 +*//***************************************************************************/
69937 +
69938 +/**************************************************************************//**
69939 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
69940 +
69941 + @Description FM Inter-Partition messaging unit API definitions and enums.
69942 +
69943 + @{
69944 +*//***************************************************************************/
69945 +
69946 +#if defined(__MWERKS__) && !defined(__GNUC__)
69947 +#pragma pack(push,1)
69948 +#endif /* defined(__MWERKS__) && ... */
69949 +
69950 +/**************************************************************************//**
69951 + @Description enum for defining MAC types
69952 +*//***************************************************************************/
69953 +
69954 +/**************************************************************************//**
69955 + @Description A structure of parameters for specifying a MAC.
69956 +*//***************************************************************************/
69957 +typedef _Packed struct
69958 +{
69959 + uint8_t id;
69960 + uint32_t enumType;
69961 +} _PackedType t_FmIpcMacParams;
69962 +
69963 +/**************************************************************************//**
69964 + @Description A structure of parameters for specifying a MAC.
69965 +*//***************************************************************************/
69966 +typedef _Packed struct
69967 +{
69968 + t_FmIpcMacParams macParams;
69969 + uint16_t maxFrameLength;
69970 +} _PackedType t_FmIpcMacMaxFrameParams;
69971 +
69972 +/**************************************************************************//**
69973 + @Description FM physical Address
69974 +*//***************************************************************************/
69975 +typedef _Packed struct t_FmIpcPhysAddr
69976 +{
69977 + volatile uint8_t high;
69978 + volatile uint32_t low;
69979 +} _PackedType t_FmIpcPhysAddr;
69980 +
69981 +
69982 +typedef _Packed struct t_FmIpcPortOutInitParams {
69983 + uint8_t numOfTasks; /**< OUT */
69984 + uint8_t numOfExtraTasks; /**< OUT */
69985 + uint8_t numOfOpenDmas; /**< OUT */
69986 + uint8_t numOfExtraOpenDmas; /**< OUT */
69987 + uint32_t sizeOfFifo; /**< OUT */
69988 + uint32_t extraSizeOfFifo; /**< OUT */
69989 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
69990 +} _PackedType t_FmIpcPortOutInitParams;
69991 +
69992 +/**************************************************************************//**
69993 + @Description Structure for IPC communication during FM_PORT_Init.
69994 +*//***************************************************************************/
69995 +typedef _Packed struct t_FmIpcPortInInitParams {
69996 + uint8_t hardwarePortId; /**< IN. port Id */
69997 + uint32_t enumPortType; /**< IN. Port type */
69998 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
69999 + uint16_t liodnOffset; /**< IN. Port's requested resource */
70000 + uint8_t numOfTasks; /**< IN. Port's requested resource */
70001 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
70002 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
70003 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
70004 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
70005 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
70006 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70007 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
70008 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
70009 + LIODN base for this port, to be
70010 + used together with LIODN offset. */
70011 +} _PackedType t_FmIpcPortInInitParams;
70012 +
70013 +
70014 +/**************************************************************************//**
70015 + @Description Structure for IPC communication between port and FM
70016 + regarding tasks and open DMA resources management.
70017 +*//***************************************************************************/
70018 +typedef _Packed struct t_FmIpcPortRsrcParams {
70019 + uint8_t hardwarePortId; /**< IN. port Id */
70020 + uint32_t val; /**< IN. Port's requested resource */
70021 + uint32_t extra; /**< IN. Port's requested resource */
70022 + uint8_t boolInitialConfig;
70023 +} _PackedType t_FmIpcPortRsrcParams;
70024 +
70025 +
70026 +/**************************************************************************//**
70027 + @Description Structure for IPC communication between port and FM
70028 + regarding tasks and open DMA resources management.
70029 +*//***************************************************************************/
70030 +typedef _Packed struct t_FmIpcPortFifoParams {
70031 + t_FmIpcPortRsrcParams rsrcParams;
70032 + uint32_t enumPortType;
70033 + uint8_t boolIndependentMode;
70034 + uint8_t deqPipelineDepth;
70035 + uint8_t numOfPools;
70036 + uint16_t secondLargestBufSize;
70037 + uint16_t largestBufSize;
70038 + uint8_t boolInitialConfig;
70039 +} _PackedType t_FmIpcPortFifoParams;
70040 +
70041 +/**************************************************************************//**
70042 + @Description Structure for port-FM communication during FM_PORT_Free.
70043 +*//***************************************************************************/
70044 +typedef _Packed struct t_FmIpcPortFreeParams {
70045 + uint8_t hardwarePortId; /**< IN. port Id */
70046 + uint32_t enumPortType; /**< IN. Port type */
70047 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70048 +} _PackedType t_FmIpcPortFreeParams;
70049 +
70050 +/**************************************************************************//**
70051 + @Description Structure for defining DMA status
70052 +*//***************************************************************************/
70053 +typedef _Packed struct t_FmIpcDmaStatus {
70054 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
70055 + uint8_t boolBusError; /**< Bus error occurred */
70056 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
70057 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70058 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70059 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
70060 +} _PackedType t_FmIpcDmaStatus;
70061 +
70062 +typedef _Packed struct t_FmIpcRegisterIntr
70063 +{
70064 + uint8_t guestId; /* IN */
70065 + uint32_t event; /* IN */
70066 +} _PackedType t_FmIpcRegisterIntr;
70067 +
70068 +typedef _Packed struct t_FmIpcIsr
70069 +{
70070 + uint8_t boolErr; /* IN */
70071 + uint32_t pendingReg; /* IN */
70072 +} _PackedType t_FmIpcIsr;
70073 +
70074 +/**************************************************************************//**
70075 + @Description structure for returning FM parameters
70076 +*//***************************************************************************/
70077 +typedef _Packed struct t_FmIpcParams {
70078 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
70079 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
70080 + uint8_t majorRev; /**< OUT: FM Major revision */
70081 + uint8_t minorRev; /**< OUT: FM Minor revision */
70082 +} _PackedType t_FmIpcParams;
70083 +
70084 +
70085 +/**************************************************************************//**
70086 + @Description structure for returning Fman Ctrl Code revision information
70087 +*//***************************************************************************/
70088 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
70089 + uint16_t packageRev; /**< OUT: Package revision */
70090 + uint8_t majorRev; /**< OUT: Major revision */
70091 + uint8_t minorRev; /**< OUT: Minor revision */
70092 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
70093 +
70094 +/**************************************************************************//**
70095 + @Description Structure for defining Fm number of Fman controlers
70096 +*//***************************************************************************/
70097 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
70098 + uint8_t hardwarePortId; /**< IN. port Id */
70099 + uint8_t numOfFmanCtrls; /**< IN. Port type */
70100 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
70101 +} t_FmIpcPortNumOfFmanCtrls;
70102 +
70103 +/**************************************************************************//**
70104 + @Description structure for setting Fman contriller events
70105 +*//***************************************************************************/
70106 +typedef _Packed struct t_FmIpcFmanEvents {
70107 + uint8_t eventRegId; /**< IN: Fman controller event register id */
70108 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
70109 +} _PackedType t_FmIpcFmanEvents;
70110 +
70111 +typedef _Packed struct t_FmIpcResourceAllocParams {
70112 + uint8_t guestId;
70113 + uint16_t base;
70114 + uint16_t num;
70115 +}_PackedType t_FmIpcResourceAllocParams;
70116 +
70117 +typedef _Packed struct t_FmIpcVspSetPortWindow {
70118 + uint8_t hardwarePortId;
70119 + uint8_t baseStorageProfile;
70120 + uint8_t log2NumOfProfiles;
70121 +}_PackedType t_FmIpcVspSetPortWindow;
70122 +
70123 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
70124 + uint32_t congestionGroupId;
70125 + uint8_t priorityBitMap;
70126 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
70127 +
70128 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
70129 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
70130 +#define FM_IPC_MAX_MSG_SIZE 30
70131 +
70132 +typedef _Packed struct t_FmIpcMsg
70133 +{
70134 + uint32_t msgId;
70135 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
70136 +} _PackedType t_FmIpcMsg;
70137 +
70138 +typedef _Packed struct t_FmIpcReply
70139 +{
70140 + uint32_t error;
70141 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
70142 +} _PackedType t_FmIpcReply;
70143 +
70144 +#if defined(__MWERKS__) && !defined(__GNUC__)
70145 +#pragma pack(pop)
70146 +#endif /* defined(__MWERKS__) && ... */
70147 +
70148 +
70149 +/***************************************************************************/
70150 +/************************ FRONT-END-TO-BACK-END*****************************/
70151 +/***************************************************************************/
70152 +
70153 +/**************************************************************************//**
70154 + @Function FM_GET_TIMESTAMP_SCALE
70155 +
70156 + @Description Used by FM front-end.
70157 +
70158 + @Param[out] uint32_t Pointer
70159 +*//***************************************************************************/
70160 +#define FM_GET_TIMESTAMP_SCALE 1
70161 +
70162 +/**************************************************************************//**
70163 + @Function FM_GET_COUNTER
70164 +
70165 + @Description Used by FM front-end.
70166 +
70167 + @Param[in/out] t_FmIpcGetCounter Pointer
70168 +*//***************************************************************************/
70169 +#define FM_GET_COUNTER 2
70170 +
70171 +/**************************************************************************//**
70172 + @Function FM_GET_SET_PORT_PARAMS
70173 +
70174 + @Description Used by FM front-end for the PORT module in order to set and get
70175 + parameters in/from master FM module on FM PORT initialization time.
70176 +
70177 + @Param[in/out] t_FmIcPortInitParams Pointer
70178 +*//***************************************************************************/
70179 +#define FM_GET_SET_PORT_PARAMS 4
70180 +
70181 +/**************************************************************************//**
70182 + @Function FM_FREE_PORT
70183 +
70184 + @Description Used by FM front-end for the PORT module when a port is freed
70185 + to free all FM PORT resources.
70186 +
70187 + @Param[in] uint8_t Pointer
70188 +*//***************************************************************************/
70189 +#define FM_FREE_PORT 5
70190 +
70191 +/**************************************************************************//**
70192 + @Function FM_RESET_MAC
70193 +
70194 + @Description Used by front-end for the MAC module to reset the MAC registers
70195 +
70196 + @Param[in] t_FmIpcMacParams Pointer .
70197 +*//***************************************************************************/
70198 +#define FM_RESET_MAC 6
70199 +
70200 +/**************************************************************************//**
70201 + @Function FM_RESUME_STALLED_PORT
70202 +
70203 + @Description Used by FM front-end for the PORT module in order to
70204 + release a stalled FM Port.
70205 +
70206 + @Param[in] uint8_t Pointer
70207 +*//***************************************************************************/
70208 +#define FM_RESUME_STALLED_PORT 7
70209 +
70210 +/**************************************************************************//**
70211 + @Function FM_IS_PORT_STALLED
70212 +
70213 + @Description Used by FM front-end for the PORT module in order to check whether
70214 + an FM port is stalled.
70215 +
70216 + @Param[in/out] t_FmIcPortIsStalled Pointer
70217 +*//***************************************************************************/
70218 +#define FM_IS_PORT_STALLED 8
70219 +
70220 +/**************************************************************************//**
70221 + @Function FM_GET_PARAMS
70222 +
70223 + @Description Used by FM front-end for the PORT module in order to dump
70224 + return FM parameters.
70225 +
70226 + @Param[in] uint8_t Pointer
70227 +*//***************************************************************************/
70228 +#define FM_GET_PARAMS 10
70229 +
70230 +/**************************************************************************//**
70231 + @Function FM_REGISTER_INTR
70232 +
70233 + @Description Used by FM front-end to register an interrupt handler to
70234 + be called upon interrupt for guest.
70235 +
70236 + @Param[out] t_FmIpcRegisterIntr Pointer
70237 +*//***************************************************************************/
70238 +#define FM_REGISTER_INTR 11
70239 +
70240 +/**************************************************************************//**
70241 + @Function FM_DMA_STAT
70242 +
70243 + @Description Used by FM front-end to read the FM DMA status.
70244 +
70245 + @Param[out] t_FmIpcDmaStatus Pointer
70246 +*//***************************************************************************/
70247 +#define FM_DMA_STAT 13
70248 +
70249 +/**************************************************************************//**
70250 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
70251 +
70252 + @Description Used by FM front-end to allocate event register.
70253 +
70254 + @Param[out] Event register id Pointer
70255 +*//***************************************************************************/
70256 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
70257 +
70258 +/**************************************************************************//**
70259 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
70260 +
70261 + @Description Used by FM front-end to free locate event register.
70262 +
70263 + @Param[in] uint8_t Pointer - Event register id
70264 +*//***************************************************************************/
70265 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
70266 +
70267 +/**************************************************************************//**
70268 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70269 +
70270 + @Description Used by FM front-end to enable events in the FPM
70271 + Fman controller event register.
70272 +
70273 + @Param[in] t_FmIpcFmanEvents Pointer
70274 +*//***************************************************************************/
70275 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
70276 +
70277 +/**************************************************************************//**
70278 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70279 +
70280 + @Description Used by FM front-end to enable events in the FPM
70281 + Fman controller event register.
70282 +
70283 + @Param[in/out] t_FmIpcFmanEvents Pointer
70284 +*//***************************************************************************/
70285 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
70286 +
70287 +/**************************************************************************//**
70288 + @Function FM_SET_MAC_MAX_FRAME
70289 +
70290 + @Description Used by FM front-end to set MAC's MTU/RTU's in
70291 + back-end.
70292 +
70293 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
70294 +*//***************************************************************************/
70295 +#define FM_SET_MAC_MAX_FRAME 18
70296 +
70297 +/**************************************************************************//**
70298 + @Function FM_GET_PHYS_MURAM_BASE
70299 +
70300 + @Description Used by FM front-end in order to get MURAM base address
70301 +
70302 + @Param[in/out] t_FmIpcPhysAddr Pointer
70303 +*//***************************************************************************/
70304 +#define FM_GET_PHYS_MURAM_BASE 19
70305 +
70306 +/**************************************************************************//**
70307 + @Function FM_MASTER_IS_ALIVE
70308 +
70309 + @Description Used by FM front-end in order to verify Master is up
70310 +
70311 + @Param[in/out] bool
70312 +*//***************************************************************************/
70313 +#define FM_MASTER_IS_ALIVE 20
70314 +
70315 +#define FM_ENABLE_RAM_ECC 21
70316 +#define FM_DISABLE_RAM_ECC 22
70317 +#define FM_SET_NUM_OF_FMAN_CTRL 23
70318 +#define FM_SET_SIZE_OF_FIFO 24
70319 +#define FM_SET_NUM_OF_TASKS 25
70320 +#define FM_SET_NUM_OF_OPEN_DMAS 26
70321 +#define FM_VSP_ALLOC 27
70322 +#define FM_VSP_FREE 28
70323 +#define FM_VSP_SET_PORT_WINDOW 29
70324 +#define FM_GET_FMAN_CTRL_CODE_REV 30
70325 +#define FM_SET_CONG_GRP_PFC_PRIO 31
70326 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
70327 +#define FM_10G_TX_ECC_WA 100
70328 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
70329 +
70330 +/***************************************************************************/
70331 +/************************ BACK-END-TO-FRONT-END*****************************/
70332 +/***************************************************************************/
70333 +
70334 +/**************************************************************************//**
70335 + @Function FM_GUEST_ISR
70336 +
70337 + @Description Used by FM back-end to report an interrupt to the front-end.
70338 +
70339 + @Param[out] t_FmIpcIsr Pointer
70340 +*//***************************************************************************/
70341 +#define FM_GUEST_ISR 1
70342 +
70343 +
70344 +
70345 +/** @} */ /* end of FM_IPC_grp group */
70346 +/** @} */ /* end of FM_grp group */
70347 +
70348 +
70349 +#endif /* __FM_IPC_H */
70350 --- /dev/null
70351 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70352 @@ -0,0 +1,174 @@
70353 +/*
70354 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70355 + *
70356 + * Redistribution and use in source and binary forms, with or without
70357 + * modification, are permitted provided that the following conditions are met:
70358 + * * Redistributions of source code must retain the above copyright
70359 + * notice, this list of conditions and the following disclaimer.
70360 + * * Redistributions in binary form must reproduce the above copyright
70361 + * notice, this list of conditions and the following disclaimer in the
70362 + * documentation and/or other materials provided with the distribution.
70363 + * * Neither the name of Freescale Semiconductor nor the
70364 + * names of its contributors may be used to endorse or promote products
70365 + * derived from this software without specific prior written permission.
70366 + *
70367 + *
70368 + * ALTERNATIVELY, this software may be distributed under the terms of the
70369 + * GNU General Public License ("GPL") as published by the Free Software
70370 + * Foundation, either version 2 of that License or (at your option) any
70371 + * later version.
70372 + *
70373 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70374 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70375 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70376 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70377 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70378 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70379 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70380 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70381 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70382 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70383 + */
70384 +
70385 +
70386 +/******************************************************************************
70387 + @File FM_muram.c
70388 +
70389 + @Description FM MURAM ...
70390 +*//***************************************************************************/
70391 +#include "error_ext.h"
70392 +#include "std_ext.h"
70393 +#include "mm_ext.h"
70394 +#include "string_ext.h"
70395 +#include "sprint_ext.h"
70396 +#include "fm_muram_ext.h"
70397 +#include "fm_common.h"
70398 +
70399 +#define __ERR_MODULE__ MODULE_FM_MURAM
70400 +
70401 +
70402 +typedef struct
70403 +{
70404 + t_Handle h_Mem;
70405 + uintptr_t baseAddr;
70406 + uint32_t size;
70407 +} t_FmMuram;
70408 +
70409 +
70410 +void FmMuramClear(t_Handle h_FmMuram)
70411 +{
70412 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70413 +
70414 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
70415 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
70416 +}
70417 +
70418 +
70419 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
70420 +{
70421 + t_Handle h_Mem;
70422 + t_FmMuram *p_FmMuram;
70423 +
70424 + if (!baseAddress)
70425 + {
70426 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
70427 + return NULL;
70428 + }
70429 +
70430 + if (baseAddress%4)
70431 + {
70432 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
70433 + return NULL;
70434 + }
70435 +
70436 + /* Allocate FM MURAM structure */
70437 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
70438 + if (!p_FmMuram)
70439 + {
70440 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
70441 + return NULL;
70442 + }
70443 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
70444 +
70445 +
70446 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
70447 + {
70448 + XX_Free(p_FmMuram);
70449 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
70450 + return NULL;
70451 + }
70452 +
70453 + /* Initialize FM MURAM parameters which will be kept by the driver */
70454 + p_FmMuram->baseAddr = baseAddress;
70455 + p_FmMuram->size = size;
70456 + p_FmMuram->h_Mem = h_Mem;
70457 +
70458 + return p_FmMuram;
70459 +}
70460 +
70461 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
70462 +{
70463 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70464 +
70465 + if (p_FmMuram->h_Mem)
70466 + MM_Free(p_FmMuram->h_Mem);
70467 +
70468 + XX_Free(h_FmMuram);
70469 +
70470 + return E_OK;
70471 +}
70472 +
70473 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
70474 +{
70475 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70476 + uintptr_t addr;
70477 +
70478 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70479 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70480 +
70481 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
70482 +
70483 + if (addr == ILLEGAL_BASE)
70484 + return NULL;
70485 +
70486 + return UINT_TO_PTR(addr);
70487 +}
70488 +
70489 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
70490 +{
70491 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70492 + uintptr_t addr;
70493 +
70494 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70495 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70496 +
70497 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
70498 +
70499 + if (addr == ILLEGAL_BASE)
70500 + return NULL;
70501 +
70502 + return UINT_TO_PTR(addr);
70503 +}
70504 +
70505 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
70506 +{
70507 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70508 +
70509 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
70510 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
70511 +
70512 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
70513 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
70514 +
70515 + return E_OK;
70516 +}
70517 +
70518 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
70519 +{
70520 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70521 +
70522 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
70523 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
70524 +
70525 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
70526 +}
70527 --- /dev/null
70528 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70529 @@ -0,0 +1,1398 @@
70530 +/*
70531 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70532 + *
70533 + * Redistribution and use in source and binary forms, with or without
70534 + * modification, are permitted provided that the following conditions are met:
70535 + * * Redistributions of source code must retain the above copyright
70536 + * notice, this list of conditions and the following disclaimer.
70537 + * * Redistributions in binary form must reproduce the above copyright
70538 + * notice, this list of conditions and the following disclaimer in the
70539 + * documentation and/or other materials provided with the distribution.
70540 + * * Neither the name of Freescale Semiconductor nor the
70541 + * names of its contributors may be used to endorse or promote products
70542 + * derived from this software without specific prior written permission.
70543 + *
70544 + *
70545 + * ALTERNATIVELY, this software may be distributed under the terms of the
70546 + * GNU General Public License ("GPL") as published by the Free Software
70547 + * Foundation, either version 2 of that License or (at your option) any
70548 + * later version.
70549 + *
70550 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70551 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70552 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70553 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70554 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70555 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70556 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70557 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70558 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70559 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70560 + */
70561 +
70562 +
70563 +#include <linux/math64.h>
70564 +#include "fsl_fman.h"
70565 +#include "dpaa_integration_ext.h"
70566 +
70567 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
70568 +{
70569 + uint32_t event, mask, force;
70570 +
70571 + event = ioread32be(&bmi_rg->fmbm_ievr);
70572 + mask = ioread32be(&bmi_rg->fmbm_ier);
70573 + event &= mask;
70574 + /* clear the forced events */
70575 + force = ioread32be(&bmi_rg->fmbm_ifr);
70576 + if (force & event)
70577 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
70578 + /* clear the acknowledged events */
70579 + iowrite32be(event, &bmi_rg->fmbm_ievr);
70580 + return event;
70581 +}
70582 +
70583 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
70584 +{
70585 + uint32_t event, mask, force;
70586 +
70587 + event = ioread32be(&qmi_rg->fmqm_eie);
70588 + mask = ioread32be(&qmi_rg->fmqm_eien);
70589 + event &= mask;
70590 +
70591 + /* clear the forced events */
70592 + force = ioread32be(&qmi_rg->fmqm_eif);
70593 + if (force & event)
70594 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
70595 + /* clear the acknowledged events */
70596 + iowrite32be(event, &qmi_rg->fmqm_eie);
70597 + return event;
70598 +}
70599 +
70600 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
70601 +{
70602 + return ioread32be(&dma_rg->fmdmtcid);
70603 +}
70604 +
70605 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
70606 +{
70607 + uint64_t addr;
70608 +
70609 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
70610 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
70611 +
70612 + return addr;
70613 +}
70614 +
70615 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
70616 +{
70617 + uint32_t status, mask;
70618 +
70619 + status = ioread32be(&dma_rg->fmdmsr);
70620 + mask = ioread32be(&dma_rg->fmdmmr);
70621 +
70622 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
70623 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
70624 + status &= ~DMA_STATUS_BUS_ERR;
70625 +
70626 + /* clear relevant bits if mask has no DMA_MODE_ECC */
70627 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
70628 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
70629 + DMA_STATUS_READ_ECC |
70630 + DMA_STATUS_SYSTEM_WRITE_ECC |
70631 + DMA_STATUS_FM_WRITE_ECC);
70632 +
70633 + /* clear set events */
70634 + iowrite32be(status, &dma_rg->fmdmsr);
70635 +
70636 + return status;
70637 +}
70638 +
70639 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
70640 +{
70641 + uint32_t event;
70642 +
70643 + event = ioread32be(&fpm_rg->fmfp_ee);
70644 + /* clear the all occurred events */
70645 + iowrite32be(event, &fpm_rg->fmfp_ee);
70646 + return event;
70647 +}
70648 +
70649 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
70650 +{
70651 + uint32_t event, mask;
70652 +
70653 + event = ioread32be(&fpm_rg->fm_rcr);
70654 + mask = ioread32be(&fpm_rg->fm_rie);
70655 +
70656 + /* clear MURAM event bit (do not clear IRAM event) */
70657 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
70658 +
70659 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
70660 + return event;
70661 + else
70662 + return 0;
70663 +}
70664 +
70665 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
70666 +{
70667 + uint32_t event, mask;
70668 +
70669 + event = ioread32be(&fpm_rg->fm_rcr) ;
70670 + mask = ioread32be(&fpm_rg->fm_rie);
70671 + /* clear IRAM event bit (do not clear MURAM event) */
70672 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
70673 + &fpm_rg->fm_rcr);
70674 +
70675 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
70676 + return event;
70677 + else
70678 + return 0;
70679 +}
70680 +
70681 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
70682 +{
70683 + uint32_t event, mask, force;
70684 +
70685 + event = ioread32be(&qmi_rg->fmqm_ie);
70686 + mask = ioread32be(&qmi_rg->fmqm_ien);
70687 + event &= mask;
70688 + /* clear the forced events */
70689 + force = ioread32be(&qmi_rg->fmqm_if);
70690 + if (force & event)
70691 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
70692 + /* clear the acknowledged events */
70693 + iowrite32be(event, &qmi_rg->fmqm_ie);
70694 + return event;
70695 +}
70696 +
70697 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
70698 + uint8_t count1ubit,
70699 + uint16_t fm_clk_freq)
70700 +{
70701 + uint32_t tmp;
70702 + uint64_t frac;
70703 + uint32_t intgr;
70704 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
70705 +
70706 + /* configure timestamp so that bit 8 will count 1 microsecond
70707 + * Find effective count rate at TIMESTAMP least significant bits:
70708 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
70709 + * Find frequency ratio between effective count rate and the clock:
70710 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
70711 + * 256/600 = 0.4266666... */
70712 +
70713 + intgr = ts_freq / fm_clk_freq;
70714 + /* we multiply by 2^16 to keep the fraction of the division
70715 + * we do not div back, since we write this value as a fraction
70716 + * see spec */
70717 +
70718 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
70719 + /* we check remainder of the division in order to round up if not int */
70720 + if (do_div(frac, fm_clk_freq))
70721 + frac++;
70722 +
70723 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
70724 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
70725 +
70726 + /* enable timestamp with original clock */
70727 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
70728 +}
70729 +
70730 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
70731 +{
70732 + return ioread32be(&fpm_rg->fm_epi);
70733 +}
70734 +
70735 +
70736 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
70737 +{
70738 + int timeout = 100;
70739 +
70740 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
70741 +
70742 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
70743 + udelay(10);
70744 +
70745 + if (!timeout)
70746 + return -EBUSY;
70747 + return 0;
70748 +}
70749 +
70750 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
70751 + uint8_t event_reg_id,
70752 + uint32_t enable_events)
70753 +{
70754 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
70755 +}
70756 +
70757 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
70758 +{
70759 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
70760 +}
70761 +
70762 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
70763 + uint8_t port_id,
70764 + uint8_t num_fman_ctrls,
70765 + uint32_t or_fman_ctrl)
70766 +{
70767 + uint32_t tmp = 0;
70768 +
70769 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
70770 + /*TODO - maybe to put CTL# according to another criteria*/
70771 + if (num_fman_ctrls == 2)
70772 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
70773 + /* order restoration */
70774 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
70775 +
70776 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70777 +}
70778 +
70779 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
70780 + uint8_t port_id,
70781 + bool independent_mode,
70782 + bool is_rx_port)
70783 +{
70784 + uint32_t tmp = 0;
70785 +
70786 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
70787 + if (independent_mode) {
70788 + if (is_rx_port)
70789 + tmp |= (FPM_PRT_FM_CTL1 <<
70790 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
70791 + else
70792 + tmp |= (FPM_PRT_FM_CTL2 <<
70793 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
70794 + } else {
70795 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
70796 +
70797 + /* order restoration */
70798 + if (port_id % 2)
70799 + tmp |= (FPM_PRT_FM_CTL1 <<
70800 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
70801 + else
70802 + tmp |= (FPM_PRT_FM_CTL2 <<
70803 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
70804 + }
70805 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70806 +}
70807 +
70808 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
70809 +{
70810 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
70811 +}
70812 +
70813 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
70814 +{
70815 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
70816 +}
70817 +
70818 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
70819 +{
70820 + uint32_t tmp_reg;
70821 +
70822 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
70823 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
70824 + tmp_reg |= ((uint32_t)val << 8);
70825 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
70826 +}
70827 +
70828 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
70829 +{
70830 + uint32_t tmp_reg;
70831 +
70832 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
70833 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
70834 + tmp_reg |= (uint32_t)val;
70835 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
70836 +}
70837 +
70838 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
70839 +{
70840 + iowrite32be(0, &fpm_rg->fmfp_mxd);
70841 +}
70842 +
70843 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
70844 + uint16_t liodn_base,
70845 + uint16_t liodn_ofst)
70846 +{
70847 + uint32_t tmp;
70848 +
70849 + if ((port_id > 63) || (port_id < 1))
70850 + return;
70851 +
70852 + /* set LIODN base for this port */
70853 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
70854 + if (port_id % 2) {
70855 + tmp &= ~FM_LIODN_BASE_MASK;
70856 + tmp |= (uint32_t)liodn_base;
70857 + } else {
70858 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
70859 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
70860 + }
70861 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
70862 + iowrite32be((uint32_t)liodn_ofst,
70863 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
70864 +}
70865 +
70866 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
70867 +{
70868 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
70869 +}
70870 +
70871 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
70872 +{
70873 + uint32_t tmp;
70874 +
70875 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
70876 + FPM_PRC_REALSE_STALLED);
70877 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
70878 +}
70879 +
70880 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
70881 +{
70882 + uint32_t msk, timeout = 100;
70883 +
70884 + /* Get the relevant bit mask */
70885 + if (is_10g) {
70886 + switch (mac_id) {
70887 + case(0):
70888 + msk = FPM_RSTC_10G0_RESET;
70889 + break;
70890 + case(1):
70891 + msk = FPM_RSTC_10G1_RESET;
70892 + break;
70893 + default:
70894 + return -EINVAL;
70895 + }
70896 + } else {
70897 + switch (mac_id) {
70898 + case(0):
70899 + msk = FPM_RSTC_1G0_RESET;
70900 + break;
70901 + case(1):
70902 + msk = FPM_RSTC_1G1_RESET;
70903 + break;
70904 + case(2):
70905 + msk = FPM_RSTC_1G2_RESET;
70906 + break;
70907 + case(3):
70908 + msk = FPM_RSTC_1G3_RESET;
70909 + break;
70910 + case(4):
70911 + msk = FPM_RSTC_1G4_RESET;
70912 + break;
70913 + case (5):
70914 + msk = FPM_RSTC_1G5_RESET;
70915 + break;
70916 + case (6):
70917 + msk = FPM_RSTC_1G6_RESET;
70918 + break;
70919 + case (7):
70920 + msk = FPM_RSTC_1G7_RESET;
70921 + break;
70922 + default:
70923 + return -EINVAL;
70924 + }
70925 + }
70926 + /* reset */
70927 + iowrite32be(msk, &fpm_rg->fm_rstc);
70928 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
70929 + udelay(10);
70930 +
70931 + if (!timeout)
70932 + return -EBUSY;
70933 + return 0;
70934 +}
70935 +
70936 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
70937 +{
70938 + uint32_t tmp_reg;
70939 +
70940 + if ((port_id > 63) || (port_id < 1))
70941 + return 0;
70942 +
70943 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
70944 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
70945 +}
70946 +
70947 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
70948 +{
70949 + uint32_t reg, res;
70950 +
70951 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
70952 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
70953 + return res * FMAN_BMI_FIFO_UNITS;
70954 +}
70955 +
70956 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
70957 + uint8_t port_id)
70958 +{
70959 + uint32_t tmp_reg;
70960 +
70961 + if ((port_id > 63) || (port_id < 1))
70962 + return 0;
70963 +
70964 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
70965 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
70966 + BMI_EXTRA_FIFO_SIZE_SHIFT);
70967 +}
70968 +
70969 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
70970 + uint8_t port_id,
70971 + uint32_t sz_fifo,
70972 + uint32_t extra_sz_fifo)
70973 +{
70974 + uint32_t tmp;
70975 +
70976 + if ((port_id > 63) || (port_id < 1))
70977 + return;
70978 +
70979 + /* calculate reg */
70980 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
70981 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
70982 + BMI_EXTRA_FIFO_SIZE_SHIFT));
70983 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
70984 +}
70985 +
70986 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
70987 +{
70988 + uint32_t tmp;
70989 +
70990 + if ((port_id > 63) || (port_id < 1))
70991 + return 0;
70992 +
70993 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
70994 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
70995 + BMI_NUM_OF_TASKS_SHIFT) + 1);
70996 +}
70997 +
70998 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
70999 +{
71000 + uint32_t tmp;
71001 +
71002 + if ((port_id > 63) || (port_id < 1))
71003 + return 0;
71004 +
71005 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71006 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
71007 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
71008 +}
71009 +
71010 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
71011 + uint8_t port_id,
71012 + uint8_t num_tasks,
71013 + uint8_t num_extra_tasks)
71014 +{
71015 + uint32_t tmp;
71016 +
71017 + if ((port_id > 63) || (port_id < 1))
71018 + return;
71019 +
71020 + /* calculate reg */
71021 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71022 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
71023 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
71024 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
71025 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71026 +}
71027 +
71028 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71029 +{
71030 + uint32_t tmp;
71031 +
71032 + if ((port_id > 63) || (port_id < 1))
71033 + return 0;
71034 +
71035 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71036 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
71037 + BMI_NUM_OF_DMAS_SHIFT) + 1);
71038 +}
71039 +
71040 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71041 +{
71042 + uint32_t tmp;
71043 +
71044 + if ((port_id > 63) || (port_id < 1))
71045 + return 0;
71046 +
71047 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71048 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
71049 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
71050 +}
71051 +
71052 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
71053 + uint8_t port_id,
71054 + uint8_t num_open_dmas,
71055 + uint8_t num_extra_open_dmas,
71056 + uint8_t total_num_dmas)
71057 +{
71058 + uint32_t tmp = 0;
71059 +
71060 + if ((port_id > 63) || (port_id < 1))
71061 + return;
71062 +
71063 + /* calculate reg */
71064 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71065 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
71066 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
71067 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
71068 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71069 +
71070 + /* update total num of DMA's with committed number of open DMAS,
71071 + * and max uncommitted pool. */
71072 + if (total_num_dmas)
71073 + {
71074 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
71075 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
71076 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
71077 + }
71078 +}
71079 +
71080 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
71081 + uint8_t port_id,
71082 + uint8_t base_storage_profile,
71083 + uint8_t log2_num_of_profiles)
71084 +{
71085 + uint32_t tmp = 0;
71086 + if ((port_id > 63) || (port_id < 1))
71087 + return;
71088 +
71089 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
71090 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
71091 + tmp |= (uint32_t)log2_num_of_profiles << 28;
71092 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
71093 +}
71094 +
71095 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
71096 + uint32_t congestion_group_id,
71097 + uint8_t priority_bit_map,
71098 + uint32_t reg_num)
71099 +{
71100 + uint32_t offset, tmp = 0;
71101 +
71102 + offset = (congestion_group_id%4)*8;
71103 +
71104 + tmp = ioread32be(&cpg_rg[reg_num]);
71105 + tmp &= ~(0xFF<<offset);
71106 + tmp |= (uint32_t)priority_bit_map << offset;
71107 +
71108 + iowrite32be(tmp,&cpg_rg[reg_num]);
71109 +}
71110 +
71111 +/*****************************************************************************/
71112 +/* API Init unit functions */
71113 +/*****************************************************************************/
71114 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
71115 +{
71116 + memset(cfg, 0, sizeof(struct fman_cfg));
71117 +
71118 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
71119 + cfg->dma_err = DEFAULT_DMA_ERR;
71120 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
71121 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
71122 + cfg->en_iram_test_mode = FALSE;
71123 + cfg->en_muram_test_mode = FALSE;
71124 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
71125 +
71126 + if (!is_master)
71127 + return;
71128 +
71129 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
71130 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
71131 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
71132 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
71133 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
71134 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
71135 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
71136 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
71137 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
71138 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
71139 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
71140 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
71141 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
71142 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
71143 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
71144 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
71145 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
71146 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
71147 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
71148 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
71149 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
71150 +
71151 + cfg->pedantic_dma = FALSE;
71152 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
71153 + cfg->dma_stop_on_bus_error = FALSE;
71154 + cfg->qmi_deq_option_support = FALSE;
71155 +}
71156 +
71157 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71158 +{
71159 + uint32_t tmp_reg;
71160 +
71161 + /* read the values from the registers as they are initialized by the HW with
71162 + * the required values.
71163 + */
71164 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
71165 + cfg->total_fifo_size =
71166 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
71167 +
71168 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
71169 + cfg->total_num_of_tasks =
71170 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
71171 +
71172 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
71173 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71174 +
71175 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
71176 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71177 +
71178 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
71179 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
71180 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
71181 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
71182 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
71183 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
71184 +
71185 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
71186 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
71187 +
71188 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
71189 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
71190 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
71191 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
71192 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
71193 +
71194 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
71195 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
71196 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
71197 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
71198 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
71199 +
71200 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
71201 + cfg->dma_sos_emergency = tmp_reg;
71202 +
71203 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
71204 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
71205 +
71206 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
71207 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
71208 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
71209 +}
71210 +
71211 +void fman_reset(struct fman_fpm_regs *fpm_rg)
71212 +{
71213 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
71214 +}
71215 +
71216 +/**************************************************************************//**
71217 + @Function FM_Init
71218 +
71219 + @Description Initializes the FM module
71220 +
71221 + @Param[in] h_Fm - FM module descriptor
71222 +
71223 + @Return E_OK on success; Error code otherwise.
71224 +*//***************************************************************************/
71225 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
71226 +{
71227 + uint32_t tmp_reg;
71228 +
71229 + /**********************/
71230 + /* Init DMA Registers */
71231 + /**********************/
71232 + /* clear status reg events */
71233 + /* oren - check!!! */
71234 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
71235 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
71236 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
71237 + &dma_rg->fmdmsr);
71238 +
71239 + /* configure mode register */
71240 + tmp_reg = 0;
71241 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
71242 + if (cfg->dma_aid_override)
71243 + tmp_reg |= DMA_MODE_AID_OR;
71244 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
71245 + tmp_reg |= DMA_MODE_BER;
71246 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
71247 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
71248 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
71249 + tmp_reg |= DMA_MODE_ECC;
71250 + if (cfg->dma_stop_on_bus_error)
71251 + tmp_reg |= DMA_MODE_SBER;
71252 + if(cfg->dma_axi_dbg_num_of_beats)
71253 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
71254 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
71255 +
71256 + if (cfg->dma_en_emergency) {
71257 + tmp_reg |= cfg->dma_emergency_bus_select;
71258 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
71259 + if (cfg->dma_en_emergency_smoother)
71260 + iowrite32be(cfg->dma_emergency_switch_counter,
71261 + &dma_rg->fmdmemsr);
71262 + }
71263 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
71264 + DMA_MODE_CEN_SHIFT;
71265 + tmp_reg |= DMA_MODE_SECURE_PROT;
71266 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
71267 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
71268 +
71269 + if (cfg->pedantic_dma)
71270 + tmp_reg |= DMA_MODE_EMER_READ;
71271 +
71272 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
71273 +
71274 + /* configure thresholds register */
71275 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
71276 + DMA_THRESH_COMMQ_SHIFT) |
71277 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
71278 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71279 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
71280 +
71281 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
71282 +
71283 + /* configure hysteresis register */
71284 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
71285 + DMA_THRESH_COMMQ_SHIFT) |
71286 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
71287 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71288 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
71289 +
71290 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
71291 +
71292 + /* configure emergency threshold */
71293 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
71294 +
71295 + /* configure Watchdog */
71296 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
71297 + &dma_rg->fmdmwcr);
71298 +
71299 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
71300 +
71301 + return 0;
71302 +}
71303 +
71304 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
71305 +{
71306 + uint32_t tmp_reg;
71307 + int i;
71308 +
71309 + /**********************/
71310 + /* Init FPM Registers */
71311 + /**********************/
71312 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
71313 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
71314 +
71315 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
71316 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
71317 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
71318 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
71319 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
71320 +
71321 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
71322 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
71323 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
71324 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
71325 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
71326 +
71327 + /* define exceptions and error behavior */
71328 + tmp_reg = 0;
71329 + /* Clear events */
71330 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
71331 + FPM_EV_MASK_SINGLE_ECC);
71332 + /* enable interrupts */
71333 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
71334 + tmp_reg |= FPM_EV_MASK_STALL_EN;
71335 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
71336 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
71337 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
71338 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
71339 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
71340 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
71341 + if (!cfg->halt_on_external_activ)
71342 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
71343 + if (!cfg->halt_on_unrecov_ecc_err)
71344 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
71345 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
71346 +
71347 + /* clear all fmCtls event registers */
71348 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
71349 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
71350 +
71351 + /* RAM ECC - enable and clear events*/
71352 + /* first we need to clear all parser memory,
71353 + * as it is uninitialized and may cause ECC errors */
71354 + /* event bits */
71355 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
71356 + /* Rams enable not effected by RCR bit, but by a COP configuration */
71357 + if (cfg->external_ecc_rams_enable)
71358 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
71359 +
71360 + /* enable test mode */
71361 + if (cfg->en_muram_test_mode)
71362 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
71363 + if (cfg->en_iram_test_mode)
71364 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
71365 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
71366 +
71367 + tmp_reg = 0;
71368 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
71369 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
71370 + fman_enable_rams_ecc(fpm_rg);
71371 + }
71372 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
71373 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
71374 + fman_enable_rams_ecc(fpm_rg);
71375 + }
71376 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
71377 +
71378 + return 0;
71379 +}
71380 +
71381 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
71382 +{
71383 + uint32_t tmp_reg;
71384 +
71385 + /**********************/
71386 + /* Init BMI Registers */
71387 + /**********************/
71388 +
71389 + /* define common resources */
71390 + tmp_reg = cfg->fifo_base_addr;
71391 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
71392 +
71393 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
71394 + BMI_CFG1_FIFO_SIZE_SHIFT);
71395 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
71396 +
71397 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
71398 + BMI_CFG2_TASKS_SHIFT);
71399 + /* num of DMA's will be dynamically updated when each port is set */
71400 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
71401 +
71402 + /* define unmaskable exceptions, enable and clear events */
71403 + tmp_reg = 0;
71404 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
71405 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
71406 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
71407 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71408 + &bmi_rg->fmbm_ievr);
71409 +
71410 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
71411 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71412 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
71413 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71414 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
71415 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71416 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
71417 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71418 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
71419 +
71420 + return 0;
71421 +}
71422 +
71423 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
71424 +{
71425 + uint32_t tmp_reg;
71426 + uint16_t period_in_fm_clocks;
71427 + uint8_t remainder;
71428 + /**********************/
71429 + /* Init QMI Registers */
71430 + /**********************/
71431 + /* Clear error interrupt events */
71432 +
71433 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71434 + &qmi_rg->fmqm_eie);
71435 + tmp_reg = 0;
71436 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
71437 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71438 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
71439 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71440 + /* enable events */
71441 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
71442 +
71443 + if (cfg->tnum_aging_period) {
71444 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
71445 + period_in_fm_clocks = (uint16_t)
71446 + (cfg->tnum_aging_period * cfg->clk_freq);
71447 + /* period_in_fm_clocks must be a 64 multiply */
71448 + remainder = (uint8_t)(period_in_fm_clocks % 64);
71449 + if (remainder)
71450 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
71451 + else{
71452 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
71453 + if (!tmp_reg)
71454 + tmp_reg = 1;
71455 + }
71456 + tmp_reg <<= QMI_TAPC_TAP;
71457 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
71458 + }
71459 + tmp_reg = 0;
71460 + /* Clear interrupt events */
71461 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
71462 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
71463 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
71464 + /* enable events */
71465 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
71466 +
71467 + return 0;
71468 +}
71469 +
71470 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71471 +{
71472 + uint32_t cfg_reg = 0;
71473 +
71474 + /**********************/
71475 + /* Enable all modules */
71476 + /**********************/
71477 + /* clear & enable global counters - calculate reg and save for later,
71478 + because it's the same reg for QMI enable */
71479 + cfg_reg = QMI_CFG_EN_COUNTERS;
71480 + if (cfg->qmi_deq_option_support)
71481 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
71482 + (uint32_t)cfg->qmi_def_tnums_thresh);
71483 +
71484 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
71485 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
71486 + &fman_rg->qmi_rg->fmqm_gc);
71487 +
71488 + return 0;
71489 +}
71490 +
71491 +void fman_free_resources(struct fman_rg *fman_rg)
71492 +{
71493 + /* disable BMI and QMI */
71494 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
71495 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
71496 +
71497 + /* release BMI resources */
71498 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
71499 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
71500 +
71501 + /* disable ECC */
71502 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
71503 +}
71504 +
71505 +/****************************************************/
71506 +/* API Run-time Control uint functions */
71507 +/****************************************************/
71508 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
71509 +{
71510 + return ioread32be(&fpm_rg->fm_npi);
71511 +}
71512 +
71513 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
71514 +{
71515 + uint32_t event;
71516 +
71517 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
71518 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
71519 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
71520 +
71521 + return event;
71522 +}
71523 +
71524 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
71525 +{
71526 + return ioread32be(&fpm_rg->fm_epi);
71527 +}
71528 +
71529 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
71530 +{
71531 + int i;
71532 + uint8_t shift;
71533 + uint32_t tmp = 0;
71534 +
71535 + for (i = 0; i < 64; i++) {
71536 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
71537 + /* Add this port to tmp_reg */
71538 + /* (each 8 ports result in one register)*/
71539 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
71540 + tmp |= ((weights[i] - 1) << shift);
71541 + }
71542 + if (i % 8 == 7) { /* last in this set */
71543 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
71544 + tmp = 0;
71545 + }
71546 + }
71547 +}
71548 +
71549 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71550 +{
71551 + uint32_t tmp;
71552 +
71553 + tmp = ioread32be(&fpm_rg->fm_rcr);
71554 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71555 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
71556 + &fpm_rg->fm_rcr);
71557 + else
71558 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
71559 + FPM_RAM_IRAM_ECC_EN,
71560 + &fpm_rg->fm_rcr);
71561 +}
71562 +
71563 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71564 +{
71565 + uint32_t tmp;
71566 +
71567 + tmp = ioread32be(&fpm_rg->fm_rcr);
71568 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71569 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
71570 + &fpm_rg->fm_rcr);
71571 + else
71572 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
71573 + &fpm_rg->fm_rcr);
71574 +}
71575 +
71576 +int fman_set_exception(struct fman_rg *fman_rg,
71577 + enum fman_exceptions exception,
71578 + bool enable)
71579 +{
71580 + uint32_t tmp;
71581 +
71582 + switch (exception) {
71583 + case(E_FMAN_EX_DMA_BUS_ERROR):
71584 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71585 + if (enable)
71586 + tmp |= DMA_MODE_BER;
71587 + else
71588 + tmp &= ~DMA_MODE_BER;
71589 + /* disable bus error */
71590 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71591 + break;
71592 + case(E_FMAN_EX_DMA_READ_ECC):
71593 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
71594 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
71595 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71596 + if (enable)
71597 + tmp |= DMA_MODE_ECC;
71598 + else
71599 + tmp &= ~DMA_MODE_ECC;
71600 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71601 + break;
71602 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
71603 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71604 + if (enable)
71605 + tmp |= FPM_EV_MASK_STALL_EN;
71606 + else
71607 + tmp &= ~FPM_EV_MASK_STALL_EN;
71608 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71609 + break;
71610 + case(E_FMAN_EX_FPM_SINGLE_ECC):
71611 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71612 + if (enable)
71613 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
71614 + else
71615 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
71616 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71617 + break;
71618 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
71619 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71620 + if (enable)
71621 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
71622 + else
71623 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
71624 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71625 + break;
71626 + case(E_FMAN_EX_QMI_SINGLE_ECC):
71627 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
71628 + if (enable)
71629 + tmp |= QMI_INTR_EN_SINGLE_ECC;
71630 + else
71631 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
71632 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
71633 + break;
71634 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
71635 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71636 + if (enable)
71637 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71638 + else
71639 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
71640 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71641 + break;
71642 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
71643 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71644 + if (enable)
71645 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71646 + else
71647 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71648 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71649 + break;
71650 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
71651 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71652 + if (enable)
71653 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71654 + else
71655 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
71656 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71657 + break;
71658 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
71659 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71660 + if (enable)
71661 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71662 + else
71663 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71664 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71665 + break;
71666 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
71667 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71668 + if (enable)
71669 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71670 + else
71671 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71672 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71673 + break;
71674 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
71675 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
71676 + if (enable)
71677 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71678 + else
71679 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71680 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
71681 + break;
71682 + case(E_FMAN_EX_IRAM_ECC):
71683 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71684 + if (enable) {
71685 + /* enable ECC if not enabled */
71686 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71687 + /* enable ECC interrupts */
71688 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
71689 + } else {
71690 + /* ECC mechanism may be disabled,
71691 + * depending on driver status */
71692 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71693 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
71694 + }
71695 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71696 + break;
71697 + case(E_FMAN_EX_MURAM_ECC):
71698 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
71699 + if (enable) {
71700 + /* enable ECC if not enabled */
71701 + fman_enable_rams_ecc(fman_rg->fpm_rg);
71702 + /* enable ECC interrupts */
71703 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
71704 + } else {
71705 + /* ECC mechanism may be disabled,
71706 + * depending on driver status */
71707 + fman_disable_rams_ecc(fman_rg->fpm_rg);
71708 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
71709 + }
71710 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
71711 + break;
71712 + default:
71713 + return -EINVAL;
71714 + }
71715 + return 0;
71716 +}
71717 +
71718 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
71719 + uint8_t *major,
71720 + uint8_t *minor)
71721 +{
71722 + uint32_t tmp;
71723 +
71724 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
71725 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
71726 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
71727 +
71728 +}
71729 +
71730 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
71731 + enum fman_counters reg_name)
71732 +{
71733 + uint32_t ret_val;
71734 +
71735 + switch (reg_name) {
71736 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71737 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
71738 + break;
71739 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71740 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
71741 + break;
71742 + case(E_FMAN_COUNTERS_DEQ_0):
71743 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
71744 + break;
71745 + case(E_FMAN_COUNTERS_DEQ_1):
71746 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
71747 + break;
71748 + case(E_FMAN_COUNTERS_DEQ_2):
71749 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
71750 + break;
71751 + case(E_FMAN_COUNTERS_DEQ_3):
71752 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
71753 + break;
71754 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71755 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
71756 + break;
71757 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71758 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
71759 + break;
71760 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71761 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
71762 + break;
71763 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71764 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
71765 + break;
71766 + default:
71767 + ret_val = 0;
71768 + }
71769 + return ret_val;
71770 +}
71771 +
71772 +int fman_modify_counter(struct fman_rg *fman_rg,
71773 + enum fman_counters reg_name,
71774 + uint32_t val)
71775 +{
71776 + /* When applicable (when there is an 'enable counters' bit,
71777 + * check that counters are enabled */
71778 + switch (reg_name) {
71779 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71780 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71781 + case(E_FMAN_COUNTERS_DEQ_0):
71782 + case(E_FMAN_COUNTERS_DEQ_1):
71783 + case(E_FMAN_COUNTERS_DEQ_2):
71784 + case(E_FMAN_COUNTERS_DEQ_3):
71785 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71786 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71787 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71788 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71789 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
71790 + QMI_CFG_EN_COUNTERS))
71791 + return -EINVAL;
71792 + break;
71793 + default:
71794 + break;
71795 + }
71796 + /* Set counter */
71797 + switch (reg_name) {
71798 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
71799 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
71800 + break;
71801 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
71802 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
71803 + break;
71804 + case(E_FMAN_COUNTERS_DEQ_0):
71805 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
71806 + break;
71807 + case(E_FMAN_COUNTERS_DEQ_1):
71808 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
71809 + break;
71810 + case(E_FMAN_COUNTERS_DEQ_2):
71811 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
71812 + break;
71813 + case(E_FMAN_COUNTERS_DEQ_3):
71814 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
71815 + break;
71816 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
71817 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
71818 + break;
71819 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
71820 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
71821 + break;
71822 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
71823 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
71824 + break;
71825 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
71826 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
71827 + break;
71828 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
71829 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
71830 + break;
71831 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
71832 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
71833 + break;
71834 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
71835 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
71836 + break;
71837 + default:
71838 + break;
71839 + }
71840 + return 0;
71841 +}
71842 +
71843 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
71844 + bool is_write,
71845 + bool enable)
71846 +{
71847 + uint32_t msk;
71848 +
71849 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
71850 +
71851 + if (enable)
71852 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
71853 + &dma_rg->fmdmmr);
71854 + else /* disable */
71855 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
71856 + &dma_rg->fmdmmr);
71857 +}
71858 +
71859 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
71860 +{
71861 + uint32_t tmp;
71862 +
71863 + tmp = ioread32be(&dma_rg->fmdmmr) |
71864 + (pri << DMA_MODE_BUS_PRI_SHIFT);
71865 +
71866 + iowrite32be(tmp, &dma_rg->fmdmmr);
71867 +}
71868 +
71869 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
71870 +{
71871 + return ioread32be(&dma_rg->fmdmsr);
71872 +}
71873 +
71874 +void fman_force_intr(struct fman_rg *fman_rg,
71875 + enum fman_exceptions exception)
71876 +{
71877 + switch (exception) {
71878 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
71879 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71880 + &fman_rg->qmi_rg->fmqm_eif);
71881 + break;
71882 + case E_FMAN_EX_QMI_SINGLE_ECC:
71883 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
71884 + &fman_rg->qmi_rg->fmqm_if);
71885 + break;
71886 + case E_FMAN_EX_QMI_DOUBLE_ECC:
71887 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
71888 + &fman_rg->qmi_rg->fmqm_eif);
71889 + break;
71890 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
71891 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
71892 + &fman_rg->bmi_rg->fmbm_ifr);
71893 + break;
71894 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
71895 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
71896 + &fman_rg->bmi_rg->fmbm_ifr);
71897 + break;
71898 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
71899 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
71900 + &fman_rg->bmi_rg->fmbm_ifr);
71901 + break;
71902 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
71903 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71904 + &fman_rg->bmi_rg->fmbm_ifr);
71905 + break;
71906 + default:
71907 + break;
71908 + }
71909 +}
71910 +
71911 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
71912 +{
71913 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
71914 +}
71915 +void fman_resume(struct fman_fpm_regs *fpm_rg)
71916 +{
71917 + uint32_t tmp;
71918 +
71919 + tmp = ioread32be(&fpm_rg->fmfp_ee);
71920 + /* clear tmp_reg event bits in order not to clear standing events */
71921 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
71922 + FPM_EV_MASK_STALL |
71923 + FPM_EV_MASK_SINGLE_ECC);
71924 + tmp |= FPM_EV_MASK_RELEASE_FM;
71925 +
71926 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
71927 +}
71928 --- /dev/null
71929 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
71930 @@ -0,0 +1,1214 @@
71931 +/*
71932 + * Copyright 2008-2012 Freescale Semiconductor Inc.
71933 + *
71934 + * Redistribution and use in source and binary forms, with or without
71935 + * modification, are permitted provided that the following conditions are met:
71936 + * * Redistributions of source code must retain the above copyright
71937 + * notice, this list of conditions and the following disclaimer.
71938 + * * Redistributions in binary form must reproduce the above copyright
71939 + * notice, this list of conditions and the following disclaimer in the
71940 + * documentation and/or other materials provided with the distribution.
71941 + * * Neither the name of Freescale Semiconductor nor the
71942 + * names of its contributors may be used to endorse or promote products
71943 + * derived from this software without specific prior written permission.
71944 + *
71945 + *
71946 + * ALTERNATIVELY, this software may be distributed under the terms of the
71947 + * GNU General Public License ("GPL") as published by the Free Software
71948 + * Foundation, either version 2 of that License or (at your option) any
71949 + * later version.
71950 + *
71951 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
71952 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
71953 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71954 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
71955 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
71956 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
71957 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
71958 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71959 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
71960 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71961 + */
71962 +
71963 +
71964 +/******************************************************************************
71965 + @File fm_common.h
71966 +
71967 + @Description FM internal structures and definitions.
71968 +*//***************************************************************************/
71969 +#ifndef __FM_COMMON_H
71970 +#define __FM_COMMON_H
71971 +
71972 +#include "error_ext.h"
71973 +#include "std_ext.h"
71974 +#include "fm_pcd_ext.h"
71975 +#include "fm_ext.h"
71976 +#include "fm_port_ext.h"
71977 +
71978 +
71979 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
71980 +
71981 +#define CLS_PLAN_NUM_PER_GRP 8
71982 +
71983 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
71984 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
71985 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
71986 +
71987 +
71988 +
71989 +/**************************************************************************//**
71990 + @Description Modules registers offsets
71991 +*//***************************************************************************/
71992 +#define FM_MM_MURAM 0x00000000
71993 +#define FM_MM_BMI 0x00080000
71994 +#define FM_MM_QMI 0x00080400
71995 +#define FM_MM_PRS 0x000c7000
71996 +#define FM_MM_KG 0x000C1000
71997 +#define FM_MM_DMA 0x000C2000
71998 +#define FM_MM_FPM 0x000C3000
71999 +#define FM_MM_PLCR 0x000C0000
72000 +#define FM_MM_IMEM 0x000C4000
72001 +#define FM_MM_CGP 0x000DB000
72002 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
72003 +#if (DPAA_VERSION >= 11)
72004 +#define FM_MM_SP 0x000dc000
72005 +#endif /* (DPAA_VERSION >= 11) */
72006 +
72007 +
72008 +/**************************************************************************//**
72009 + @Description Enum for inter-module interrupts registration
72010 +*//***************************************************************************/
72011 +typedef enum e_FmEventModules{
72012 + e_FM_MOD_PRS, /**< Parser event */
72013 + e_FM_MOD_KG, /**< Keygen event */
72014 + e_FM_MOD_PLCR, /**< Policer event */
72015 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
72016 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
72017 + e_FM_MOD_TMR, /**< Timer event */
72018 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
72019 + e_FM_MOD_MACSEC,
72020 + e_FM_MOD_DUMMY_LAST
72021 +} e_FmEventModules;
72022 +
72023 +/**************************************************************************//**
72024 + @Description Enum for interrupts types
72025 +*//***************************************************************************/
72026 +typedef enum e_FmIntrType {
72027 + e_FM_INTR_TYPE_ERR,
72028 + e_FM_INTR_TYPE_NORMAL
72029 +} e_FmIntrType;
72030 +
72031 +/**************************************************************************//**
72032 + @Description Enum for inter-module interrupts registration
72033 +*//***************************************************************************/
72034 +typedef enum e_FmInterModuleEvent
72035 +{
72036 + e_FM_EV_PRS = 0, /**< Parser event */
72037 + e_FM_EV_ERR_PRS, /**< Parser error event */
72038 + e_FM_EV_KG, /**< Keygen event */
72039 + e_FM_EV_ERR_KG, /**< Keygen error event */
72040 + e_FM_EV_PLCR, /**< Policer event */
72041 + e_FM_EV_ERR_PLCR, /**< Policer error event */
72042 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
72043 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
72044 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
72045 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
72046 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
72047 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
72048 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
72049 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
72050 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
72051 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
72052 + e_FM_EV_ERR_MACSEC_MAC0,
72053 + e_FM_EV_TMR, /**< Timer event */
72054 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
72055 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
72056 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
72057 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
72058 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
72059 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
72060 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
72061 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
72062 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
72063 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
72064 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
72065 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
72066 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
72067 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
72068 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
72069 + e_FM_EV_DUMMY_LAST
72070 +} e_FmInterModuleEvent;
72071 +
72072 +
72073 +#if defined(__MWERKS__) && !defined(__GNUC__)
72074 +#pragma pack(push,1)
72075 +#endif /* defined(__MWERKS__) && ... */
72076 +
72077 +/**************************************************************************//**
72078 + @Description PCD KG scheme registers
72079 +*//***************************************************************************/
72080 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
72081 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
72082 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
72083 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
72084 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
72085 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
72086 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
72087 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
72088 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
72089 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
72090 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
72091 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
72092 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
72093 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
72094 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
72095 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
72096 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
72097 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
72098 +} _PackedType t_FmPcdPlcrProfileRegs;
72099 +
72100 +
72101 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
72102 + volatile uint32_t portIdAndCapwapReassmTbl;
72103 + volatile uint32_t fqidForTimeOutFrames;
72104 + volatile uint32_t timeoutRequestTime;
72105 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
72106 +
72107 +/**************************************************************************//**
72108 + @Description PCD CTRL Parameters Page
72109 +*//***************************************************************************/
72110 +typedef _Packed struct t_FmPcdCtrlParamsPage {
72111 + volatile uint8_t reserved0[16];
72112 + volatile uint32_t iprIpv4Nia;
72113 + volatile uint32_t iprIpv6Nia;
72114 + volatile uint8_t reserved1[24];
72115 + volatile uint32_t ipfOptionsCounter;
72116 + volatile uint8_t reserved2[12];
72117 + volatile uint32_t misc;
72118 + volatile uint32_t errorsDiscardMask;
72119 + volatile uint32_t discardMask;
72120 + volatile uint8_t reserved3[4];
72121 + volatile uint32_t postBmiFetchNia;
72122 + volatile uint8_t reserved4[172];
72123 +} _PackedType t_FmPcdCtrlParamsPage;
72124 +
72125 +
72126 +
72127 +#if defined(__MWERKS__) && !defined(__GNUC__)
72128 +#pragma pack(pop)
72129 +#endif /* defined(__MWERKS__) && ... */
72130 +
72131 +
72132 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
72133 +typedef uint32_t t_FmFmanCtrl;
72134 +
72135 +#define FPM_PORT_FM_CTL1 0x00000001
72136 +#define FPM_PORT_FM_CTL2 0x00000002
72137 +
72138 +
72139 +
72140 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
72141 + uint32_t numOfBuffers;
72142 + uint8_t bufferPoolId;
72143 +} t_FmPcdCcFragScratchPoolCmdParams;
72144 +
72145 +typedef struct t_FmPcdCcReassmTimeoutParams {
72146 + bool activate;
72147 + uint8_t tsbs;
72148 + uint32_t iprcpt;
72149 +} t_FmPcdCcReassmTimeoutParams;
72150 +
72151 +typedef struct {
72152 + uint8_t baseEntry;
72153 + uint16_t numOfClsPlanEntries;
72154 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
72155 +} t_FmPcdKgInterModuleClsPlanSet;
72156 +
72157 +/**************************************************************************//**
72158 + @Description Structure for binding a port to keygen schemes.
72159 +*//***************************************************************************/
72160 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
72161 + uint8_t hardwarePortId;
72162 + uint8_t netEnvId;
72163 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
72164 + uint8_t numOfSchemes;
72165 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
72166 +} t_FmPcdKgInterModuleBindPortToSchemes;
72167 +
72168 +typedef struct {
72169 + uint32_t nextCcNodeInfo;
72170 + t_List node;
72171 +} t_CcNodeInfo;
72172 +
72173 +typedef struct
72174 +{
72175 + t_Handle h_CcNode;
72176 + uint16_t index;
72177 + t_List node;
72178 +}t_CcNodeInformation;
72179 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
72180 +
72181 +typedef enum e_ModifyState
72182 +{
72183 + e_MODIFY_STATE_ADD = 0,
72184 + e_MODIFY_STATE_REMOVE,
72185 + e_MODIFY_STATE_CHANGE
72186 +} e_ModifyState;
72187 +
72188 +typedef struct
72189 +{
72190 + t_Handle h_Manip;
72191 + t_List node;
72192 +}t_ManipInfo;
72193 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
72194 +
72195 +typedef struct {
72196 + uint32_t type;
72197 + uint8_t prOffset;
72198 + uint16_t dataOffset;
72199 + uint8_t internalBufferOffset;
72200 + uint8_t numOfTasks;
72201 + uint8_t numOfExtraTasks;
72202 + uint8_t hardwarePortId;
72203 + t_FmRevisionInfo revInfo;
72204 + uint32_t nia;
72205 + uint32_t discardMask;
72206 +} t_GetCcParams;
72207 +
72208 +typedef struct {
72209 + uint32_t type;
72210 + int psoSize;
72211 + uint32_t nia;
72212 + t_FmFmanCtrl orFmanCtrl;
72213 + bool overwrite;
72214 + uint8_t ofpDpde;
72215 +} t_SetCcParams;
72216 +
72217 +typedef struct {
72218 + t_GetCcParams getCcParams;
72219 + t_SetCcParams setCcParams;
72220 +} t_FmPortGetSetCcParams;
72221 +
72222 +typedef struct {
72223 + uint32_t type;
72224 + bool sleep;
72225 +} t_FmSetParams;
72226 +
72227 +typedef struct {
72228 + uint32_t type;
72229 + uint32_t fmqm_gs;
72230 + uint32_t fm_npi;
72231 + uint32_t fm_cld;
72232 + uint32_t fmfp_extc;
72233 +} t_FmGetParams;
72234 +
72235 +typedef struct {
72236 + t_FmSetParams setParams;
72237 + t_FmGetParams getParams;
72238 +} t_FmGetSetParams;
72239 +
72240 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
72241 +
72242 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
72243 +{
72244 + uint32_t intFlags;
72245 + if (h_Spinlock)
72246 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
72247 + else
72248 + intFlags = XX_DisableAllIntr();
72249 +
72250 + if (*p_Flag)
72251 + {
72252 + if (h_Spinlock)
72253 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72254 + else
72255 + XX_RestoreAllIntr(intFlags);
72256 + return FALSE;
72257 + }
72258 + *p_Flag = TRUE;
72259 +
72260 + if (h_Spinlock)
72261 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72262 + else
72263 + XX_RestoreAllIntr(intFlags);
72264 +
72265 + return TRUE;
72266 +}
72267 +
72268 +#define RELEASE_LOCK(_flag) _flag = FALSE;
72269 +
72270 +/**************************************************************************//**
72271 + @Collection Defines used for manipulation CC and BMI
72272 + @{
72273 +*//***************************************************************************/
72274 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
72275 +#define OFFSET_OF_PR 0x40000000
72276 +#define MANIP_EXTRA_SPACE 0x20000000
72277 +#define NUM_OF_TASKS 0x10000000
72278 +#define OFFSET_OF_DATA 0x08000000
72279 +#define HW_PORT_ID 0x04000000
72280 +#define FM_REV 0x02000000
72281 +#define GET_NIA_FPNE 0x01000000
72282 +#define GET_NIA_PNDN 0x00800000
72283 +#define NUM_OF_EXTRA_TASKS 0x00400000
72284 +#define DISCARD_MASK 0x00200000
72285 +
72286 +#define UPDATE_NIA_PNEN 0x80000000
72287 +#define UPDATE_PSO 0x40000000
72288 +#define UPDATE_NIA_PNDN 0x20000000
72289 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
72290 +#define UPDATE_OFP_DPTE 0x08000000
72291 +#define UPDATE_NIA_FENE 0x04000000
72292 +#define UPDATE_NIA_CMNE 0x02000000
72293 +#define UPDATE_NIA_FPNE 0x01000000
72294 +/* @} */
72295 +
72296 +/**************************************************************************//**
72297 + @Collection Defines used for manipulation CC and CC
72298 + @{
72299 +*//***************************************************************************/
72300 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
72301 +#define UPDATE_CC_WITH_TREE 0x40000000
72302 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
72303 +#define UPDATE_KG_NIA_CC_WA 0x10000000
72304 +#define UPDATE_KG_OPT_MODE 0x08000000
72305 +#define UPDATE_KG_NIA 0x04000000
72306 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
72307 +/* @} */
72308 +
72309 +#define UPDATE_FPM_BRKC_SLP 0x80000000
72310 +#define UPDATE_FPM_EXTC 0x40000000
72311 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
72312 +#define GET_FMQM_GS 0x10000000
72313 +#define GET_FM_NPI 0x08000000
72314 +#define GET_FMFP_EXTC 0x04000000
72315 +#define CLEAR_IRAM_READY 0x02000000
72316 +#define UPDATE_FM_CLD 0x01000000
72317 +#define GET_FM_CLD 0x00800000
72318 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
72319 + FM_MAX_NUM_OF_1G_RX_PORTS + \
72320 + FM_MAX_NUM_OF_10G_RX_PORTS + \
72321 + FM_MAX_NUM_OF_1G_TX_PORTS + \
72322 + FM_MAX_NUM_OF_10G_TX_PORTS)
72323 +
72324 +#define MODULE_NAME_SIZE 30
72325 +#define DUMMY_PORT_ID 0
72326 +
72327 +#define FM_LIODN_OFFSET_MASK 0x3FF
72328 +
72329 +/**************************************************************************//**
72330 + @Description NIA Description
72331 +*//***************************************************************************/
72332 +#define NIA_ENG_MASK 0x007C0000
72333 +#define NIA_AC_MASK 0x0003ffff
72334 +
72335 +#define NIA_ORDER_RESTOR 0x00800000
72336 +#define NIA_ENG_FM_CTL 0x00000000
72337 +#define NIA_ENG_PRS 0x00440000
72338 +#define NIA_ENG_KG 0x00480000
72339 +#define NIA_ENG_PLCR 0x004C0000
72340 +#define NIA_ENG_BMI 0x00500000
72341 +#define NIA_ENG_QMI_ENQ 0x00540000
72342 +#define NIA_ENG_QMI_DEQ 0x00580000
72343 +
72344 +#define NIA_FM_CTL_AC_CC 0x00000006
72345 +#define NIA_FM_CTL_AC_HC 0x0000000C
72346 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
72347 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
72348 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
72349 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
72350 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
72351 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
72352 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
72353 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
72354 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
72355 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
72356 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
72357 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
72358 +/* V3 only */
72359 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
72360 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
72361 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
72362 +
72363 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
72364 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
72365 +#define NIA_BMI_AC_RELEASE 0x000000C0
72366 +#define NIA_BMI_AC_DISCARD 0x000000C1
72367 +#define NIA_BMI_AC_TX 0x00000274
72368 +#define NIA_BMI_AC_FETCH 0x00000208
72369 +#define NIA_BMI_AC_MASK 0x000003FF
72370 +
72371 +#define NIA_KG_DIRECT 0x00000100
72372 +#define NIA_KG_CC_EN 0x00000200
72373 +#define NIA_PLCR_ABSOLUTE 0x00008000
72374 +
72375 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
72376 +
72377 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
72378 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72379 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72380 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72381 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
72382 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72383 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72384 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72385 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
72386 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72387 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
72388 +#else
72389 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72390 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72391 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72392 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
72393 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72394 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72395 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72396 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
72397 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72398 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
72399 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
72400 +
72401 +/**************************************************************************//**
72402 + @Description CTRL Parameters Page defines
72403 +*//***************************************************************************/
72404 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
72405 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
72406 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
72407 +
72408 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
72409 +
72410 +/**************************************************************************//**
72411 + @Description Port Id defines
72412 +*//***************************************************************************/
72413 +#if (DPAA_VERSION == 10)
72414 +#define BASE_OH_PORTID 1
72415 +#else
72416 +#define BASE_OH_PORTID 2
72417 +#endif /* (DPAA_VERSION == 10) */
72418 +#define BASE_1G_RX_PORTID 8
72419 +#define BASE_10G_RX_PORTID 0x10
72420 +#define BASE_1G_TX_PORTID 0x28
72421 +#define BASE_10G_TX_PORTID 0x30
72422 +
72423 +#define FM_PCD_PORT_OH_BASE_INDX 0
72424 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
72425 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
72426 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
72427 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
72428 +
72429 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
72430 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72431 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
72432 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72433 +#else
72434 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72435 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72436 +#endif
72437 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
72438 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72439 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
72440 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72441 +#else
72442 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72443 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72444 +#endif
72445 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
72446 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72447 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
72448 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72449 +#else
72450 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72451 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72452 +#endif
72453 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
72454 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72455 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
72456 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72457 +#else
72458 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72459 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72460 +#endif
72461 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
72462 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72463 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
72464 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72465 +#else
72466 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72467 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72468 +#endif
72469 +
72470 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
72471 +
72472 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
72473 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
72474 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72475 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
72476 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72477 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72478 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
72479 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72480 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72481 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
72482 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72483 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72484 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
72485 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72486 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72487 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
72488 + else { \
72489 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
72490 + ASSERT_COND(TRUE); \
72491 + } \
72492 +}
72493 +
72494 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
72495 +do { \
72496 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72497 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
72498 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72499 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72500 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
72501 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72502 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72503 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
72504 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72505 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72506 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
72507 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72508 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72509 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
72510 + else ASSERT_COND(FALSE); \
72511 +} while (0)
72512 +
72513 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
72514 +do { \
72515 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
72516 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
72517 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
72518 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
72519 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72520 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
72521 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
72522 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
72523 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72524 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
72525 + else ASSERT_COND(FALSE); \
72526 +} while (0)
72527 +
72528 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
72529 +#define BMI_FIFO_UNITS 0x100
72530 +
72531 +typedef struct {
72532 + void (*f_Isr) (t_Handle h_Arg);
72533 + t_Handle h_SrcHandle;
72534 + uint8_t guestId;
72535 +} t_FmIntrSrc;
72536 +
72537 +#define ILLEGAL_HDR_NUM 0xFF
72538 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
72539 +
72540 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
72541 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
72542 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
72543 +
72544 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
72545 +{
72546 + switch (hdr)
72547 + { case (HEADER_TYPE_ETH): return 0;
72548 + case (HEADER_TYPE_LLC_SNAP): return 1;
72549 + case (HEADER_TYPE_VLAN): return 2;
72550 + case (HEADER_TYPE_PPPoE): return 3;
72551 + case (HEADER_TYPE_PPP): return 3;
72552 + case (HEADER_TYPE_MPLS): return 4;
72553 + case (HEADER_TYPE_IPv4): return 5;
72554 + case (HEADER_TYPE_IPv6): return 6;
72555 + case (HEADER_TYPE_GRE): return 7;
72556 + case (HEADER_TYPE_MINENCAP): return 8;
72557 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
72558 + case (HEADER_TYPE_TCP): return 10;
72559 + case (HEADER_TYPE_UDP): return 11;
72560 + case (HEADER_TYPE_IPSEC_AH):
72561 + case (HEADER_TYPE_IPSEC_ESP): return 12;
72562 + case (HEADER_TYPE_SCTP): return 13;
72563 + case (HEADER_TYPE_DCCP): return 14;
72564 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
72565 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
72566 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
72567 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
72568 + default:
72569 + return ILLEGAL_HDR_NUM;
72570 + }
72571 +}
72572 +
72573 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
72574 +
72575 +
72576 +/**************************************************************************//**
72577 + @Description A structure for initializing a keygen classification plan group
72578 +*//***************************************************************************/
72579 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
72580 + uint8_t netEnvId; /* IN */
72581 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
72582 + uint8_t clsPlanGrpId; /* OUT */
72583 + bool emptyClsPlanGrp; /* OUT */
72584 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72585 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72586 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72587 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72588 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72589 +} t_FmPcdKgInterModuleClsPlanGrpParams;
72590 +
72591 +typedef struct t_FmPcdLock {
72592 + t_Handle h_Spinlock;
72593 + volatile bool flag;
72594 + t_List node;
72595 +} t_FmPcdLock;
72596 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
72597 +
72598 +
72599 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
72600 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72601 +
72602 +
72603 +/***********************************************************************/
72604 +/* Common API for FM-PCD module */
72605 +/***********************************************************************/
72606 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
72607 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
72608 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
72609 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
72610 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72611 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72612 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
72613 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
72614 +uint32_t FmPcdLock(t_Handle h_FmPcd);
72615 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
72616 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
72617 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
72618 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72619 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72620 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
72621 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
72622 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
72623 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
72624 +t_Handle FmGetPcd(t_Handle h_Fm);
72625 +/***********************************************************************/
72626 +/* Common API for FM-PCD KG module */
72627 +/***********************************************************************/
72628 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72629 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72630 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
72631 +
72632 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
72633 +#if (DPAA_VERSION >= 11)
72634 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
72635 +#endif /* (DPAA_VERSION >= 11) */
72636 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
72637 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
72638 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
72639 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
72640 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
72641 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
72642 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
72643 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
72644 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
72645 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
72646 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
72647 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
72648 +
72649 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72650 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
72651 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
72652 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
72653 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
72654 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
72655 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
72656 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
72657 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
72658 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
72659 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
72660 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
72661 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
72662 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
72663 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
72664 +
72665 +/***********************************************************************/
72666 +/* Common API for FM-PCD parser module */
72667 +/***********************************************************************/
72668 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
72669 +
72670 +/***********************************************************************/
72671 +/* Common API for FM-PCD policer module */
72672 +/***********************************************************************/
72673 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
72674 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72675 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72676 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
72677 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
72678 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
72679 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
72680 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
72681 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
72682 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
72683 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
72684 + e_FmPcdProfileTypeSelection profileType,
72685 + t_Handle h_FmPort,
72686 + uint16_t relativeProfile,
72687 + uint16_t *p_AbsoluteId);
72688 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72689 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72690 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
72691 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72692 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
72693 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
72694 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
72695 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
72696 +
72697 +/***********************************************************************/
72698 +/* Common API for FM-PCD CC module */
72699 +/***********************************************************************/
72700 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
72701 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
72702 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
72703 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
72704 +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);
72705 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
72706 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
72707 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
72708 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
72709 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
72710 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
72711 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
72712 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
72713 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
72714 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
72715 +
72716 +/***********************************************************************/
72717 +/* Common API for FM-PCD Manip module */
72718 +/***********************************************************************/
72719 +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);
72720 +
72721 +/***********************************************************************/
72722 +/* Common API for FM-Port module */
72723 +/***********************************************************************/
72724 +#if (DPAA_VERSION >= 11)
72725 +typedef enum e_FmPortGprFuncType
72726 +{
72727 + e_FM_PORT_GPR_EMPTY = 0,
72728 + e_FM_PORT_GPR_MURAM_PAGE
72729 +} e_FmPortGprFuncType;
72730 +
72731 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
72732 +#endif /* DPAA_VERSION >= 11) */
72733 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
72734 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72735 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
72736 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
72737 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
72738 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
72739 +
72740 +
72741 +#if (DPAA_VERSION >= 11)
72742 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
72743 +#endif /* (DPAA_VERSION >= 11) */
72744 +
72745 +/**************************************************************************//**
72746 + @Function FmRegisterIntr
72747 +
72748 + @Description Used to register an inter-module event handler to be processed by FM
72749 +
72750 + @Param[in] h_Fm A handle to an FM Module.
72751 + @Param[in] mod The module that causes the event
72752 + @Param[in] modId Module id - if more than 1 instansiation of this
72753 + mode exists,0 otherwise.
72754 + @Param[in] intrType Interrupt type (error/normal) selection.
72755 + @Param[in] f_Isr The interrupt service routine.
72756 + @Param[in] h_Arg Argument to be passed to f_Isr.
72757 +
72758 + @Return None.
72759 +*//***************************************************************************/
72760 +void FmRegisterIntr(t_Handle h_Fm,
72761 + e_FmEventModules mod,
72762 + uint8_t modId,
72763 + e_FmIntrType intrType,
72764 + void (*f_Isr) (t_Handle h_Arg),
72765 + t_Handle h_Arg);
72766 +
72767 +/**************************************************************************//**
72768 + @Function FmUnregisterIntr
72769 +
72770 + @Description Used to un-register an inter-module event handler that was processed by FM
72771 +
72772 + @Param[in] h_Fm A handle to an FM Module.
72773 + @Param[in] mod The module that causes the event
72774 + @Param[in] modId Module id - if more than 1 instansiation of this
72775 + mode exists,0 otherwise.
72776 + @Param[in] intrType Interrupt type (error/normal) selection.
72777 +
72778 + @Return None.
72779 +*//***************************************************************************/
72780 +void FmUnregisterIntr(t_Handle h_Fm,
72781 + e_FmEventModules mod,
72782 + uint8_t modId,
72783 + e_FmIntrType intrType);
72784 +
72785 +/**************************************************************************//**
72786 + @Function FmRegisterFmCtlIntr
72787 +
72788 + @Description Used to register to one of the fmCtl events in the FM module
72789 +
72790 + @Param[in] h_Fm A handle to an FM Module.
72791 + @Param[in] eventRegId FmCtl event id (0-7).
72792 + @Param[in] f_Isr The interrupt service routine.
72793 +
72794 + @Return E_OK on success; Error code otherwise.
72795 +
72796 + @Cautions Allowed only following FM_Init().
72797 +*//***************************************************************************/
72798 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
72799 +
72800 +
72801 +/**************************************************************************//**
72802 + @Description enum for defining MAC types
72803 +*//***************************************************************************/
72804 +typedef enum e_FmMacType {
72805 + e_FM_MAC_10G = 0, /**< 10G MAC */
72806 + e_FM_MAC_1G /**< 1G MAC */
72807 +} e_FmMacType;
72808 +
72809 +/**************************************************************************//**
72810 + @Description Structure for port-FM communication during FM_PORT_Init.
72811 + Fields commented 'IN' are passed by the port module to be used
72812 + by the FM module.
72813 + Fields commented 'OUT' will be filled by FM before returning to port.
72814 + Some fields are optional (depending on configuration) and
72815 + will be analized by the port and FM modules accordingly.
72816 +*//***************************************************************************/
72817 +typedef struct t_FmInterModulePortInitParams {
72818 + uint8_t hardwarePortId; /**< IN. port Id */
72819 + e_FmPortType portType; /**< IN. Port type */
72820 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
72821 + uint16_t liodnOffset; /**< IN. Port's requested resource */
72822 + uint8_t numOfTasks; /**< IN. Port's requested resource */
72823 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
72824 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
72825 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
72826 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
72827 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
72828 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72829 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
72830 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
72831 + LIODN base for this port, to be
72832 + used together with LIODN offset. */
72833 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
72834 +} t_FmInterModulePortInitParams;
72835 +
72836 +/**************************************************************************//**
72837 + @Description Structure for port-FM communication during FM_PORT_Free.
72838 +*//***************************************************************************/
72839 +typedef struct t_FmInterModulePortFreeParams {
72840 + uint8_t hardwarePortId; /**< IN. port Id */
72841 + e_FmPortType portType; /**< IN. Port type */
72842 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72843 +} t_FmInterModulePortFreeParams;
72844 +
72845 +/**************************************************************************//**
72846 + @Function FmGetPcdPrsBaseAddr
72847 +
72848 + @Description Get the base address of the Parser from the FM module
72849 +
72850 + @Param[in] h_Fm A handle to an FM Module.
72851 +
72852 + @Return Base address.
72853 +*//***************************************************************************/
72854 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
72855 +
72856 +/**************************************************************************//**
72857 + @Function FmGetPcdKgBaseAddr
72858 +
72859 + @Description Get the base address of the Keygen from the FM module
72860 +
72861 + @Param[in] h_Fm A handle to an FM Module.
72862 +
72863 + @Return Base address.
72864 +*//***************************************************************************/
72865 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
72866 +
72867 +/**************************************************************************//**
72868 + @Function FmGetPcdPlcrBaseAddr
72869 +
72870 + @Description Get the base address of the Policer from the FM module
72871 +
72872 + @Param[in] h_Fm A handle to an FM Module.
72873 +
72874 + @Return Base address.
72875 +*//***************************************************************************/
72876 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
72877 +
72878 +/**************************************************************************//**
72879 + @Function FmGetMuramHandle
72880 +
72881 + @Description Get the handle of the MURAM from the FM module
72882 +
72883 + @Param[in] h_Fm A handle to an FM Module.
72884 +
72885 + @Return MURAM module handle.
72886 +*//***************************************************************************/
72887 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
72888 +
72889 +/**************************************************************************//**
72890 + @Function FmGetPhysicalMuramBase
72891 +
72892 + @Description Get the physical base address of the MURAM from the FM module
72893 +
72894 + @Param[in] h_Fm A handle to an FM Module.
72895 + @Param[in] fmPhysAddr Physical MURAM base
72896 +
72897 + @Return Physical base address.
72898 +*//***************************************************************************/
72899 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
72900 +
72901 +/**************************************************************************//**
72902 + @Function FmGetTimeStampScale
72903 +
72904 + @Description Used internally by other modules in order to get the timeStamp
72905 + period as requested by the application.
72906 +
72907 + This function returns bit number that is incremented every 1 usec.
72908 + To calculate timestamp period in nsec, use
72909 + 1000 / (1 << FmGetTimeStampScale()).
72910 +
72911 + @Param[in] h_Fm A handle to an FM Module.
72912 +
72913 + @Return Bit that counts 1 usec.
72914 +
72915 + @Cautions Allowed only following FM_Init().
72916 +*//***************************************************************************/
72917 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
72918 +
72919 +/**************************************************************************//**
72920 + @Function FmResumeStalledPort
72921 +
72922 + @Description Used internally by FM port to release a stalled port.
72923 +
72924 + @Param[in] h_Fm A handle to an FM Module.
72925 + @Param[in] hardwarePortId HW port id.
72926 +
72927 + @Return E_OK on success; Error code otherwise.
72928 +
72929 + @Cautions Allowed only following FM_Init().
72930 +*//***************************************************************************/
72931 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
72932 +
72933 +/**************************************************************************//**
72934 + @Function FmIsPortStalled
72935 +
72936 + @Description Used internally by FM port to read the port's status.
72937 +
72938 + @Param[in] h_Fm A handle to an FM Module.
72939 + @Param[in] hardwarePortId HW port id.
72940 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
72941 +
72942 + @Return E_OK on success; Error code otherwise.
72943 +
72944 + @Cautions Allowed only following FM_Init().
72945 +*//***************************************************************************/
72946 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
72947 +
72948 +/**************************************************************************//**
72949 + @Function FmResetMac
72950 +
72951 + @Description Used by MAC driver to reset the MAC registers
72952 +
72953 + @Param[in] h_Fm A handle to an FM Module.
72954 + @Param[in] type MAC type.
72955 + @Param[in] macId MAC id - according to type.
72956 +
72957 + @Return E_OK on success; Error code otherwise.
72958 +
72959 + @Cautions Allowed only following FM_Init().
72960 +*//***************************************************************************/
72961 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
72962 +
72963 +/**************************************************************************//**
72964 + @Function FmGetClockFreq
72965 +
72966 + @Description Used by MAC driver to get the FM clock frequency
72967 +
72968 + @Param[in] h_Fm A handle to an FM Module.
72969 +
72970 + @Return clock-freq on success; 0 otherwise.
72971 +
72972 + @Cautions Allowed only following FM_Init().
72973 +*//***************************************************************************/
72974 +uint16_t FmGetClockFreq(t_Handle h_Fm);
72975 +
72976 +/**************************************************************************//**
72977 + @Function FmGetMacClockFreq
72978 +
72979 + @Description Used by MAC driver to get the MAC clock frequency
72980 +
72981 + @Param[in] h_Fm A handle to an FM Module.
72982 +
72983 + @Return clock-freq on success; 0 otherwise.
72984 +
72985 + @Cautions Allowed only following FM_Init().
72986 +*//***************************************************************************/
72987 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
72988 +
72989 +/**************************************************************************//**
72990 + @Function FmGetId
72991 +
72992 + @Description Used by PCD driver to read rhe FM id
72993 +
72994 + @Param[in] h_Fm A handle to an FM Module.
72995 +
72996 + @Return E_OK on success; Error code otherwise.
72997 +
72998 + @Cautions Allowed only following FM_Init().
72999 +*//***************************************************************************/
73000 +uint8_t FmGetId(t_Handle h_Fm);
73001 +
73002 +/**************************************************************************//**
73003 + @Function FmReset
73004 +
73005 + @Description Used to reset the FM
73006 +
73007 + @Param[in] h_Fm A handle to an FM Module.
73008 +
73009 + @Return E_OK on success; Error code otherwise.
73010 +*//***************************************************************************/
73011 +t_Error FmReset(t_Handle h_Fm);
73012 +
73013 +/**************************************************************************//**
73014 + @Function FmGetSetPortParams
73015 +
73016 + @Description Used by FM-PORT driver to pass and receive parameters between
73017 + PORT and FM modules.
73018 +
73019 + @Param[in] h_Fm A handle to an FM Module.
73020 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73021 +
73022 + @Return E_OK on success; Error code otherwise.
73023 +
73024 + @Cautions Allowed only following FM_Init().
73025 +*//***************************************************************************/
73026 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
73027 +
73028 +/**************************************************************************//**
73029 + @Function FmFreePortParams
73030 +
73031 + @Description Used by FM-PORT driver to free port's resources within the FM.
73032 +
73033 + @Param[in] h_Fm A handle to an FM Module.
73034 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73035 +
73036 + @Return None.
73037 +
73038 + @Cautions Allowed only following FM_Init().
73039 +*//***************************************************************************/
73040 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
73041 +
73042 +/**************************************************************************//**
73043 + @Function FmSetNumOfRiscsPerPort
73044 +
73045 + @Description Used by FM-PORT driver to pass parameter between
73046 + PORT and FM modules for working with number of RISC..
73047 +
73048 + @Param[in] h_Fm A handle to an FM Module.
73049 + @Param[in] hardwarePortId hardware port Id.
73050 + @Param[in] numOfFmanCtrls number of Fman Controllers.
73051 + @Param[in] orFmanCtrl Fman Controller for order restoration.
73052 +
73053 + @Return None.
73054 +
73055 + @Cautions Allowed only following FM_Init().
73056 +*//***************************************************************************/
73057 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
73058 +
73059 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73060 +/**************************************************************************//*
73061 + @Function FmDumpPortRegs
73062 +
73063 + @Description Dumps FM port registers which are part of FM common registers
73064 +
73065 + @Param[in] h_Fm A handle to an FM Module.
73066 + @Param[in] hardwarePortId HW port id.
73067 +
73068 + @Return E_OK on success; Error code otherwise.
73069 +
73070 + @Cautions Allowed only FM_Init().
73071 +*//***************************************************************************/
73072 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
73073 +#endif /* (defined(DEBUG_ERRORS) && ... */
73074 +
73075 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
73076 +void FmUnregisterPcd(t_Handle h_Fm);
73077 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
73078 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
73079 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
73080 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
73081 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
73082 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
73083 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
73084 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73085 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
73086 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73087 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
73088 +bool FmIsMaster(t_Handle h_Fm);
73089 +uint8_t FmGetGuestId(t_Handle h_Fm);
73090 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
73091 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
73092 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
73093 +
73094 +
73095 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
73096 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
73097 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
73098 +
73099 +void FmMuramClear(t_Handle h_FmMuram);
73100 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
73101 + uint8_t hardwarePortId,
73102 + uint8_t *p_NumOfOpenDmas,
73103 + uint8_t *p_NumOfExtraOpenDmas,
73104 + bool initialConfig);
73105 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
73106 + uint8_t hardwarePortId,
73107 + uint8_t *p_NumOfTasks,
73108 + uint8_t *p_NumOfExtraTasks,
73109 + bool initialConfig);
73110 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
73111 + uint8_t hardwarePortId,
73112 + uint32_t *p_SizeOfFifo,
73113 + uint32_t *p_ExtraSizeOfFifo,
73114 + bool initialConfig);
73115 +
73116 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
73117 + uint32_t congestionGroupId,
73118 + uint8_t priorityBitMap);
73119 +
73120 +#if (DPAA_VERSION >= 11)
73121 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
73122 + e_FmPortType portType,
73123 + uint8_t portId,
73124 + uint8_t numOfStorageProfiles);
73125 +
73126 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
73127 + e_FmPortType portType,
73128 + uint8_t portId);
73129 +
73130 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
73131 + e_FmPortType portType,
73132 + uint8_t portId,
73133 + uint16_t relativeProfile,
73134 + uint16_t *p_AbsoluteId);
73135 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
73136 + e_FmPortType portType,
73137 + uint8_t portId,
73138 + uint16_t relativeProfile);
73139 +
73140 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
73141 +#endif /* (DPAA_VERSION >= 11) */
73142 +
73143 +
73144 +#endif /* __FM_COMMON_H */
73145 --- /dev/null
73146 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73147 @@ -0,0 +1,93 @@
73148 +/*
73149 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73150 + *
73151 + * Redistribution and use in source and binary forms, with or without
73152 + * modification, are permitted provided that the following conditions are met:
73153 + * * Redistributions of source code must retain the above copyright
73154 + * notice, this list of conditions and the following disclaimer.
73155 + * * Redistributions in binary form must reproduce the above copyright
73156 + * notice, this list of conditions and the following disclaimer in the
73157 + * documentation and/or other materials provided with the distribution.
73158 + * * Neither the name of Freescale Semiconductor nor the
73159 + * names of its contributors may be used to endorse or promote products
73160 + * derived from this software without specific prior written permission.
73161 + *
73162 + *
73163 + * ALTERNATIVELY, this software may be distributed under the terms of the
73164 + * GNU General Public License ("GPL") as published by the Free Software
73165 + * Foundation, either version 2 of that License or (at your option) any
73166 + * later version.
73167 + *
73168 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73169 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73170 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73171 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73172 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73173 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73174 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73175 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73176 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73177 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73178 + */
73179 +
73180 +
73181 +#ifndef __FM_HC_H
73182 +#define __FM_HC_H
73183 +
73184 +#include "std_ext.h"
73185 +#include "error_ext.h"
73186 +#include "fsl_fman_kg.h"
73187 +
73188 +#define __ERR_MODULE__ MODULE_FM_PCD
73189 +
73190 +
73191 +typedef struct t_FmHcParams {
73192 + t_Handle h_Fm;
73193 + t_Handle h_FmPcd;
73194 + t_FmPcdHcParams params;
73195 +} t_FmHcParams;
73196 +
73197 +
73198 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
73199 +void FmHcFree(t_Handle h_FmHc);
73200 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
73201 + uint8_t memId);
73202 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
73203 +
73204 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
73205 +
73206 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
73207 + t_Handle h_Scheme,
73208 + struct fman_kg_scheme_regs *p_SchemeRegs,
73209 + bool updateCounter);
73210 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
73211 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
73212 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
73213 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
73214 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
73215 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
73216 +
73217 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
73218 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
73219 +
73220 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
73221 +
73222 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
73223 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
73224 +
73225 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
73226 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
73227 +
73228 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
73229 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
73230 +
73231 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73232 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
73233 +
73234 +t_Error FmHcPcdSync(t_Handle h_FmHc);
73235 +t_Handle FmHcGetPort(t_Handle h_FmHc);
73236 +
73237 +
73238 +
73239 +
73240 +#endif /* __FM_HC_H */
73241 --- /dev/null
73242 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73243 @@ -0,0 +1,117 @@
73244 +/*
73245 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73246 + *
73247 + * Redistribution and use in source and binary forms, with or without
73248 + * modification, are permitted provided that the following conditions are met:
73249 + * * Redistributions of source code must retain the above copyright
73250 + * notice, this list of conditions and the following disclaimer.
73251 + * * Redistributions in binary form must reproduce the above copyright
73252 + * notice, this list of conditions and the following disclaimer in the
73253 + * documentation and/or other materials provided with the distribution.
73254 + * * Neither the name of Freescale Semiconductor nor the
73255 + * names of its contributors may be used to endorse or promote products
73256 + * derived from this software without specific prior written permission.
73257 + *
73258 + *
73259 + * ALTERNATIVELY, this software may be distributed under the terms of the
73260 + * GNU General Public License ("GPL") as published by the Free Software
73261 + * Foundation, either version 2 of that License or (at your option) any
73262 + * later version.
73263 + *
73264 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73265 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73266 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73267 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73268 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73269 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73270 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73271 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73272 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73273 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73274 + */
73275 +
73276 +
73277 +/******************************************************************************
73278 + @File fm_sp_common.h
73279 +
73280 + @Description FM SP ...
73281 +*//***************************************************************************/
73282 +#ifndef __FM_SP_COMMON_H
73283 +#define __FM_SP_COMMON_H
73284 +
73285 +#include "std_ext.h"
73286 +#include "error_ext.h"
73287 +#include "list_ext.h"
73288 +
73289 +#include "fm_ext.h"
73290 +#include "fm_pcd_ext.h"
73291 +#include "fsl_fman.h"
73292 +
73293 +/**************************************************************************//**
73294 + @Description defaults
73295 +*//***************************************************************************/
73296 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
73297 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
73298 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
73299 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
73300 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
73301 +
73302 +/**************************************************************************//**
73303 + @Description structure for defining internal context copying
73304 +*//***************************************************************************/
73305 +typedef struct
73306 +{
73307 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
73308 + context is copied to (Rx) or taken from (Tx, Op). */
73309 + uint8_t intContextOffset; /**< Offset within internal context to copy from
73310 + (Rx) or to copy to (Tx, Op). */
73311 + uint16_t size; /**< Internal offset size to be copied */
73312 +} t_FmSpIntContextDataCopy;
73313 +
73314 +/**************************************************************************//**
73315 + @Description struct for defining external buffer margins
73316 +*//***************************************************************************/
73317 +typedef struct {
73318 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
73319 + of the external buffer (must be divisible by 16) */
73320 + uint16_t endMargins; /**< number of bytes to be left at the end
73321 + of the external buffer(must be divisible by 16) */
73322 +} t_FmSpBufMargins;
73323 +
73324 +typedef struct {
73325 + uint32_t dataOffset;
73326 + uint32_t prsResultOffset;
73327 + uint32_t timeStampOffset;
73328 + uint32_t hashResultOffset;
73329 + uint32_t pcdInfoOffset;
73330 + uint32_t manipOffset;
73331 +} t_FmSpBufferOffsets;
73332 +
73333 +
73334 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
73335 + t_FmBufferPrefixContent *p_BufferPrefixContent,
73336 + t_FmSpBufMargins *p_FmPortBufMargins,
73337 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
73338 + uint8_t *internalBufferOffset);
73339 +
73340 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
73341 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
73342 + t_FmBackupBmPools *p_FmBackupBmPools,
73343 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
73344 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
73345 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
73346 +
73347 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
73348 + uint8_t hardwarePortId,
73349 + uint16_t numOfStorageProfiles,
73350 + uint16_t *base,
73351 + uint8_t *log2Num);
73352 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
73353 + t_Handle h_FmPort,
73354 + uint16_t relativeProfile,
73355 + uint16_t *p_AbsoluteId);
73356 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73357 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73358 +
73359 +
73360 +#endif /* __FM_SP_COMMON_H */
73361 --- /dev/null
73362 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73363 @@ -0,0 +1,12 @@
73364 +#
73365 +# Makefile for the Freescale Ethernet controllers
73366 +#
73367 +ccflags-y += -DVERSION=\"\"
73368 +#
73369 +#Include netcomm SW specific definitions
73370 +
73371 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
73372 +
73373 +obj-y += fsl-ncsw-etc.o
73374 +
73375 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
73376 --- /dev/null
73377 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73378 @@ -0,0 +1,95 @@
73379 +/*
73380 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73381 + *
73382 + * Redistribution and use in source and binary forms, with or without
73383 + * modification, are permitted provided that the following conditions are met:
73384 + * * Redistributions of source code must retain the above copyright
73385 + * notice, this list of conditions and the following disclaimer.
73386 + * * Redistributions in binary form must reproduce the above copyright
73387 + * notice, this list of conditions and the following disclaimer in the
73388 + * documentation and/or other materials provided with the distribution.
73389 + * * Neither the name of Freescale Semiconductor nor the
73390 + * names of its contributors may be used to endorse or promote products
73391 + * derived from this software without specific prior written permission.
73392 + *
73393 + *
73394 + * ALTERNATIVELY, this software may be distributed under the terms of the
73395 + * GNU General Public License ("GPL") as published by the Free Software
73396 + * Foundation, either version 2 of that License or (at your option) any
73397 + * later version.
73398 + *
73399 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73400 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73401 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73402 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73403 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73404 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73405 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73406 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73407 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73408 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73409 + */
73410 +
73411 +
73412 +/*
73413 +
73414 + @File error.c
73415 +
73416 + @Description General errors and events reporting utilities.
73417 +*//***************************************************************************/
73418 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73419 +#include "error_ext.h"
73420 +
73421 +
73422 +const char *dbgLevelStrings[] =
73423 +{
73424 + "CRITICAL"
73425 + ,"MAJOR"
73426 + ,"MINOR"
73427 + ,"WARNING"
73428 + ,"INFO"
73429 + ,"TRACE"
73430 +};
73431 +
73432 +
73433 +char * ErrTypeStrings (e_ErrorType err)
73434 +{
73435 + switch (err)
73436 + {
73437 + case (E_OK): return "OK";
73438 + case (E_WRITE_FAILED): return "Write Access Failed";
73439 + case (E_NO_DEVICE): return "No Device";
73440 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
73441 + case (E_NO_MEMORY): return "Memory Allocation Failed";
73442 + case (E_INVALID_ADDRESS): return "Invalid Address";
73443 + case (E_BUSY): return "Resource Is Busy";
73444 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
73445 + case (E_INVALID_OPERATION): return "Invalid Operation";
73446 + case (E_INVALID_VALUE): return "Invalid Value";
73447 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
73448 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
73449 + case (E_INVALID_STATE): return "Invalid State";
73450 + case (E_INVALID_HANDLE): return "Invalid Handle";
73451 + case (E_INVALID_ID): return "Invalid ID";
73452 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
73453 + case (E_INVALID_SELECTION): return "Invalid Selection";
73454 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
73455 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
73456 + case (E_INVALID_CLOCK): return "Invalid Clock";
73457 + case (E_CONFLICT): return "Conflict In Settings";
73458 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
73459 + case (E_NOT_FOUND): return "Resource Not Found";
73460 + case (E_FULL): return "Resource Is Full";
73461 + case (E_EMPTY): return "Resource Is Empty";
73462 + case (E_ALREADY_FREE): return "Resource Already Free";
73463 + case (E_READ_FAILED): return "Read Access Failed";
73464 + case (E_INVALID_FRAME): return "Invalid Frame";
73465 + case (E_SEND_FAILED): return "Send Operation Failed";
73466 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
73467 + case (E_TIMEOUT): return "Operation Timed Out";
73468 + default:
73469 + break;
73470 + }
73471 + return NULL;
73472 +}
73473 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
73474 --- /dev/null
73475 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73476 @@ -0,0 +1,71 @@
73477 +/*
73478 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73479 + *
73480 + * Redistribution and use in source and binary forms, with or without
73481 + * modification, are permitted provided that the following conditions are met:
73482 + * * Redistributions of source code must retain the above copyright
73483 + * notice, this list of conditions and the following disclaimer.
73484 + * * Redistributions in binary form must reproduce the above copyright
73485 + * notice, this list of conditions and the following disclaimer in the
73486 + * documentation and/or other materials provided with the distribution.
73487 + * * Neither the name of Freescale Semiconductor nor the
73488 + * names of its contributors may be used to endorse or promote products
73489 + * derived from this software without specific prior written permission.
73490 + *
73491 + *
73492 + * ALTERNATIVELY, this software may be distributed under the terms of the
73493 + * GNU General Public License ("GPL") as published by the Free Software
73494 + * Foundation, either version 2 of that License or (at your option) any
73495 + * later version.
73496 + *
73497 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73498 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73499 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73500 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73501 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73502 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73503 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73504 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73505 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73506 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73507 + */
73508 +
73509 +
73510 +/**************************************************************************//**
73511 +
73512 + @File list.c
73513 +
73514 + @Description Implementation of list.
73515 +*//***************************************************************************/
73516 +#include "std_ext.h"
73517 +#include "list_ext.h"
73518 +
73519 +
73520 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
73521 +{
73522 + t_List *p_First = LIST_FIRST(p_NewList);
73523 +
73524 + if (p_First != p_NewList)
73525 + {
73526 + t_List *p_Last = LIST_LAST(p_NewList);
73527 + t_List *p_Cur = LIST_NEXT(p_Head);
73528 +
73529 + LIST_PREV(p_First) = p_Head;
73530 + LIST_FIRST(p_Head) = p_First;
73531 + LIST_NEXT(p_Last) = p_Cur;
73532 + LIST_LAST(p_Cur) = p_Last;
73533 + }
73534 +}
73535 +
73536 +
73537 +int LIST_NumOfObjs(t_List *p_List)
73538 +{
73539 + t_List *p_Tmp;
73540 + int numOfObjs = 0;
73541 +
73542 + if (!LIST_IsEmpty(p_List))
73543 + LIST_FOR_EACH(p_Tmp, p_List)
73544 + numOfObjs++;
73545 +
73546 + return numOfObjs;
73547 +}
73548 --- /dev/null
73549 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73550 @@ -0,0 +1,620 @@
73551 +/*
73552 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73553 + *
73554 + * Redistribution and use in source and binary forms, with or without
73555 + * modification, are permitted provided that the following conditions are met:
73556 + * * Redistributions of source code must retain the above copyright
73557 + * notice, this list of conditions and the following disclaimer.
73558 + * * Redistributions in binary form must reproduce the above copyright
73559 + * notice, this list of conditions and the following disclaimer in the
73560 + * documentation and/or other materials provided with the distribution.
73561 + * * Neither the name of Freescale Semiconductor nor the
73562 + * names of its contributors may be used to endorse or promote products
73563 + * derived from this software without specific prior written permission.
73564 + *
73565 + *
73566 + * ALTERNATIVELY, this software may be distributed under the terms of the
73567 + * GNU General Public License ("GPL") as published by the Free Software
73568 + * Foundation, either version 2 of that License or (at your option) any
73569 + * later version.
73570 + *
73571 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73572 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73573 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73574 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73575 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73576 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73577 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73578 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73579 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73580 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73581 + */
73582 +
73583 +
73584 +
73585 +#include "std_ext.h"
73586 +#include "xx_ext.h"
73587 +#include "memcpy_ext.h"
73588 +
73589 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
73590 +{
73591 + int i;
73592 +
73593 + for(i = 0; i < size; ++i)
73594 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
73595 +
73596 + return pDst;
73597 +}
73598 +
73599 +void * MemSet8(void* pDst, int c, uint32_t size)
73600 +{
73601 + int i;
73602 +
73603 + for(i = 0; i < size; ++i)
73604 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
73605 +
73606 + return pDst;
73607 +}
73608 +
73609 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
73610 +{
73611 + uint32_t leftAlign;
73612 + uint32_t rightAlign;
73613 + uint32_t lastWord;
73614 + uint32_t currWord;
73615 + uint32_t *p_Src32;
73616 + uint32_t *p_Dst32;
73617 + uint8_t *p_Src8;
73618 + uint8_t *p_Dst8;
73619 +
73620 + p_Src8 = (uint8_t*)(pSrc);
73621 + p_Dst8 = (uint8_t*)(pDst);
73622 + /* first copy byte by byte till the source first alignment
73623 + * this step is necessary to ensure we do not even try to access
73624 + * data which is before the source buffer, hence it is not ours.
73625 + */
73626 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73627 + {
73628 + *p_Dst8++ = *p_Src8++;
73629 + size--;
73630 + }
73631 +
73632 + /* align destination (possibly disaligning source)*/
73633 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73634 + {
73635 + *p_Dst8++ = *p_Src8++;
73636 + size--;
73637 + }
73638 +
73639 + /* dest is aligned and source is not necessarily aligned */
73640 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73641 + rightAlign = 32 - leftAlign;
73642 +
73643 +
73644 + if (leftAlign == 0)
73645 + {
73646 + /* source is also aligned */
73647 + p_Src32 = (uint32_t*)(p_Src8);
73648 + p_Dst32 = (uint32_t*)(p_Dst8);
73649 + while (size >> 2) /* size >= 4 */
73650 + {
73651 + *p_Dst32++ = *p_Src32++;
73652 + size -= 4;
73653 + }
73654 + p_Src8 = (uint8_t*)(p_Src32);
73655 + p_Dst8 = (uint8_t*)(p_Dst32);
73656 + }
73657 + else
73658 + {
73659 + /* source is not aligned (destination is aligned)*/
73660 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73661 + p_Dst32 = (uint32_t*)(p_Dst8);
73662 + lastWord = *p_Src32++;
73663 + while(size >> 3) /* size >= 8 */
73664 + {
73665 + currWord = *p_Src32;
73666 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
73667 + lastWord = currWord;
73668 + p_Src32++;
73669 + p_Dst32++;
73670 + size -= 4;
73671 + }
73672 + p_Dst8 = (uint8_t*)(p_Dst32);
73673 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73674 + }
73675 +
73676 + /* complete the left overs */
73677 + while (size--)
73678 + *p_Dst8++ = *p_Src8++;
73679 +
73680 + return pDst;
73681 +}
73682 +
73683 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73684 +{
73685 + uint32_t leftAlign;
73686 + uint32_t rightAlign;
73687 + uint32_t lastWord;
73688 + uint32_t currWord;
73689 + uint32_t *p_Src32;
73690 + uint32_t *p_Dst32;
73691 + uint8_t *p_Src8;
73692 + uint8_t *p_Dst8;
73693 +
73694 + p_Src8 = (uint8_t*)(pSrc);
73695 + p_Dst8 = (uint8_t*)(pDst);
73696 + /* first copy byte by byte till the source first alignment
73697 + * this step is necessary to ensure we do not even try to access
73698 + * data which is before the source buffer, hence it is not ours.
73699 + */
73700 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73701 + {
73702 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73703 + p_Dst8++;p_Src8++;
73704 + size--;
73705 + }
73706 +
73707 + /* align destination (possibly disaligning source)*/
73708 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73709 + {
73710 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73711 + p_Dst8++;p_Src8++;
73712 + size--;
73713 + }
73714 +
73715 + /* dest is aligned and source is not necessarily aligned */
73716 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73717 + rightAlign = 32 - leftAlign;
73718 +
73719 + if (leftAlign == 0)
73720 + {
73721 + /* source is also aligned */
73722 + p_Src32 = (uint32_t*)(p_Src8);
73723 + p_Dst32 = (uint32_t*)(p_Dst8);
73724 + while (size >> 2) /* size >= 4 */
73725 + {
73726 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
73727 + p_Dst32++;p_Src32++;
73728 + size -= 4;
73729 + }
73730 + p_Src8 = (uint8_t*)(p_Src32);
73731 + p_Dst8 = (uint8_t*)(p_Dst32);
73732 + }
73733 + else
73734 + {
73735 + /* source is not aligned (destination is aligned)*/
73736 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73737 + p_Dst32 = (uint32_t*)(p_Dst8);
73738 + lastWord = GET_UINT32(*p_Src32);
73739 + p_Src32++;
73740 + while(size >> 3) /* size >= 8 */
73741 + {
73742 + currWord = GET_UINT32(*p_Src32);
73743 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
73744 + lastWord = currWord;
73745 + p_Src32++;p_Dst32++;
73746 + size -= 4;
73747 + }
73748 + p_Dst8 = (uint8_t*)(p_Dst32);
73749 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73750 + }
73751 +
73752 + /* complete the left overs */
73753 + while (size--)
73754 + {
73755 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
73756 + p_Dst8++;p_Src8++;
73757 + }
73758 +
73759 + return pDst;
73760 +}
73761 +
73762 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
73763 +{
73764 + uint32_t leftAlign;
73765 + uint32_t rightAlign;
73766 + uint32_t lastWord;
73767 + uint32_t currWord;
73768 + uint32_t *p_Src32;
73769 + uint32_t *p_Dst32;
73770 + uint8_t *p_Src8;
73771 + uint8_t *p_Dst8;
73772 +
73773 + p_Src8 = (uint8_t*)(pSrc);
73774 + p_Dst8 = (uint8_t*)(pDst);
73775 + /* first copy byte by byte till the source first alignment
73776 + * this step is necessary to ensure we do not even try to access
73777 + * data which is before the source buffer, hence it is not ours.
73778 + */
73779 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73780 + {
73781 + WRITE_UINT8(*p_Dst8, *p_Src8);
73782 + p_Dst8++;p_Src8++;
73783 + size--;
73784 + }
73785 +
73786 + /* align destination (possibly disaligning source)*/
73787 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73788 + {
73789 + WRITE_UINT8(*p_Dst8, *p_Src8);
73790 + p_Dst8++;p_Src8++;
73791 + size--;
73792 + }
73793 +
73794 + /* dest is aligned and source is not necessarily aligned */
73795 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73796 + rightAlign = 32 - leftAlign;
73797 +
73798 + if (leftAlign == 0)
73799 + {
73800 + /* source is also aligned */
73801 + p_Src32 = (uint32_t*)(p_Src8);
73802 + p_Dst32 = (uint32_t*)(p_Dst8);
73803 + while (size >> 2) /* size >= 4 */
73804 + {
73805 + WRITE_UINT32(*p_Dst32, *p_Src32);
73806 + p_Dst32++;p_Src32++;
73807 + size -= 4;
73808 + }
73809 + p_Src8 = (uint8_t*)(p_Src32);
73810 + p_Dst8 = (uint8_t*)(p_Dst32);
73811 + }
73812 + else
73813 + {
73814 + /* source is not aligned (destination is aligned)*/
73815 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73816 + p_Dst32 = (uint32_t*)(p_Dst8);
73817 + lastWord = *p_Src32++;
73818 + while(size >> 3) /* size >= 8 */
73819 + {
73820 + currWord = *p_Src32;
73821 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
73822 + lastWord = currWord;
73823 + p_Src32++;p_Dst32++;
73824 + size -= 4;
73825 + }
73826 + p_Dst8 = (uint8_t*)(p_Dst32);
73827 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73828 + }
73829 +
73830 + /* complete the left overs */
73831 + while (size--)
73832 + {
73833 + WRITE_UINT8(*p_Dst8, *p_Src8);
73834 + p_Dst8++;p_Src8++;
73835 + }
73836 +
73837 + return pDst;
73838 +}
73839 +
73840 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
73841 +{
73842 + uint32_t leftAlign;
73843 + uint32_t rightAlign;
73844 + uint32_t lastWord;
73845 + uint32_t currWord;
73846 + uint32_t *p_Src32;
73847 + uint32_t *p_Dst32;
73848 + uint8_t *p_Src8;
73849 + uint8_t *p_Dst8;
73850 +
73851 + p_Src8 = (uint8_t*)(pSrc);
73852 + p_Dst8 = (uint8_t*)(pDst);
73853 + /* first copy byte by byte till the source first alignment
73854 + * this step is necessary to ensure we do not even try to access
73855 + * data which is before the source buffer, hence it is not ours.
73856 + */
73857 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73858 + {
73859 + *p_Dst8 = GET_UINT8(*p_Src8);
73860 + p_Dst8++;p_Src8++;
73861 + size--;
73862 + }
73863 +
73864 + /* align destination (possibly disaligning source)*/
73865 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73866 + {
73867 + *p_Dst8 = GET_UINT8(*p_Src8);
73868 + p_Dst8++;p_Src8++;
73869 + size--;
73870 + }
73871 +
73872 + /* dest is aligned and source is not necessarily aligned */
73873 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73874 + rightAlign = 32 - leftAlign;
73875 +
73876 + if (leftAlign == 0)
73877 + {
73878 + /* source is also aligned */
73879 + p_Src32 = (uint32_t*)(p_Src8);
73880 + p_Dst32 = (uint32_t*)(p_Dst8);
73881 + while (size >> 2) /* size >= 4 */
73882 + {
73883 + *p_Dst32 = GET_UINT32(*p_Src32);
73884 + p_Dst32++;p_Src32++;
73885 + size -= 4;
73886 + }
73887 + p_Src8 = (uint8_t*)(p_Src32);
73888 + p_Dst8 = (uint8_t*)(p_Dst32);
73889 + }
73890 + else
73891 + {
73892 + /* source is not aligned (destination is aligned)*/
73893 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
73894 + p_Dst32 = (uint32_t*)(p_Dst8);
73895 + lastWord = GET_UINT32(*p_Src32);
73896 + p_Src32++;
73897 + while(size >> 3) /* size >= 8 */
73898 + {
73899 + currWord = GET_UINT32(*p_Src32);
73900 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
73901 + lastWord = currWord;
73902 + p_Src32++;p_Dst32++;
73903 + size -= 4;
73904 + }
73905 + p_Dst8 = (uint8_t*)(p_Dst32);
73906 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
73907 + }
73908 +
73909 + /* complete the left overs */
73910 + while (size--)
73911 + {
73912 + *p_Dst8 = GET_UINT8(*p_Src8);
73913 + p_Dst8++;p_Src8++;
73914 + }
73915 +
73916 + return pDst;
73917 +}
73918 +
73919 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
73920 +{
73921 + uint32_t leftAlign;
73922 + uint32_t rightAlign;
73923 + uint64_t lastWord;
73924 + uint64_t currWord;
73925 + uint64_t *pSrc64;
73926 + uint64_t *pDst64;
73927 + uint8_t *p_Src8;
73928 + uint8_t *p_Dst8;
73929 +
73930 + p_Src8 = (uint8_t*)(pSrc);
73931 + p_Dst8 = (uint8_t*)(pDst);
73932 + /* first copy byte by byte till the source first alignment
73933 + * this step is necessarily to ensure we do not even try to access
73934 + * data which is before the source buffer, hence it is not ours.
73935 + */
73936 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
73937 + {
73938 + *p_Dst8++ = *p_Src8++;
73939 + size--;
73940 + }
73941 +
73942 + /* align destination (possibly disaligning source)*/
73943 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
73944 + {
73945 + *p_Dst8++ = *p_Src8++;
73946 + size--;
73947 + }
73948 +
73949 + /* dest is aligned and source is not necessarily aligned */
73950 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
73951 + rightAlign = 64 - leftAlign;
73952 +
73953 +
73954 + if (leftAlign == 0)
73955 + {
73956 + /* source is also aligned */
73957 + pSrc64 = (uint64_t*)(p_Src8);
73958 + pDst64 = (uint64_t*)(p_Dst8);
73959 + while (size >> 3) /* size >= 8 */
73960 + {
73961 + *pDst64++ = *pSrc64++;
73962 + size -= 8;
73963 + }
73964 + p_Src8 = (uint8_t*)(pSrc64);
73965 + p_Dst8 = (uint8_t*)(pDst64);
73966 + }
73967 + else
73968 + {
73969 + /* source is not aligned (destination is aligned)*/
73970 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
73971 + pDst64 = (uint64_t*)(p_Dst8);
73972 + lastWord = *pSrc64++;
73973 + while(size >> 4) /* size >= 16 */
73974 + {
73975 + currWord = *pSrc64;
73976 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
73977 + lastWord = currWord;
73978 + pSrc64++;
73979 + pDst64++;
73980 + size -= 8;
73981 + }
73982 + p_Dst8 = (uint8_t*)(pDst64);
73983 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
73984 + }
73985 +
73986 + /* complete the left overs */
73987 + while (size--)
73988 + *p_Dst8++ = *p_Src8++;
73989 +
73990 + return pDst;
73991 +}
73992 +
73993 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
73994 +{
73995 + uint32_t val32;
73996 + uint32_t *p_Dst32;
73997 + uint8_t *p_Dst8;
73998 +
73999 + p_Dst8 = (uint8_t*)(pDst);
74000 +
74001 + /* generate four 8-bit val's in 32-bit container */
74002 + val32 = (uint32_t) val;
74003 + val32 |= (val32 << 8);
74004 + val32 |= (val32 << 16);
74005 +
74006 + /* align destination to 32 */
74007 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74008 + {
74009 + *p_Dst8++ = val;
74010 + size--;
74011 + }
74012 +
74013 + /* 32-bit chunks */
74014 + p_Dst32 = (uint32_t*)(p_Dst8);
74015 + while (size >> 2) /* size >= 4 */
74016 + {
74017 + *p_Dst32++ = val32;
74018 + size -= 4;
74019 + }
74020 +
74021 + /* complete the leftovers */
74022 + p_Dst8 = (uint8_t*)(p_Dst32);
74023 + while (size--)
74024 + *p_Dst8++ = val;
74025 +
74026 + return pDst;
74027 +}
74028 +
74029 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
74030 +{
74031 + uint32_t val32;
74032 + uint32_t *p_Dst32;
74033 + uint8_t *p_Dst8;
74034 +
74035 + p_Dst8 = (uint8_t*)(pDst);
74036 +
74037 + /* generate four 8-bit val's in 32-bit container */
74038 + val32 = (uint32_t) val;
74039 + val32 |= (val32 << 8);
74040 + val32 |= (val32 << 16);
74041 +
74042 + /* align destination to 32 */
74043 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74044 + {
74045 + WRITE_UINT8(*p_Dst8, val);
74046 + p_Dst8++;
74047 + size--;
74048 + }
74049 +
74050 + /* 32-bit chunks */
74051 + p_Dst32 = (uint32_t*)(p_Dst8);
74052 + while (size >> 2) /* size >= 4 */
74053 + {
74054 + WRITE_UINT32(*p_Dst32, val32);
74055 + p_Dst32++;
74056 + size -= 4;
74057 + }
74058 +
74059 + /* complete the leftovers */
74060 + p_Dst8 = (uint8_t*)(p_Dst32);
74061 + while (size--)
74062 + {
74063 + WRITE_UINT8(*p_Dst8, val);
74064 + p_Dst8++;
74065 + }
74066 +
74067 + return pDst;
74068 +}
74069 +
74070 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
74071 +{
74072 + uint64_t val64;
74073 + uint64_t *pDst64;
74074 + uint8_t *p_Dst8;
74075 +
74076 + p_Dst8 = (uint8_t*)(pDst);
74077 +
74078 + /* generate four 8-bit val's in 32-bit container */
74079 + val64 = (uint64_t) val;
74080 + val64 |= (val64 << 8);
74081 + val64 |= (val64 << 16);
74082 + val64 |= (val64 << 24);
74083 + val64 |= (val64 << 32);
74084 +
74085 + /* align destination to 64 */
74086 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74087 + {
74088 + *p_Dst8++ = val;
74089 + size--;
74090 + }
74091 +
74092 + /* 64-bit chunks */
74093 + pDst64 = (uint64_t*)(p_Dst8);
74094 + while (size >> 4) /* size >= 8 */
74095 + {
74096 + *pDst64++ = val64;
74097 + size -= 8;
74098 + }
74099 +
74100 + /* complete the leftovers */
74101 + p_Dst8 = (uint8_t*)(pDst64);
74102 + while (size--)
74103 + *p_Dst8++ = val;
74104 +
74105 + return pDst;
74106 +}
74107 +
74108 +void MemDisp(uint8_t *p, int size)
74109 +{
74110 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
74111 + uint8_t *p_Limit;
74112 +
74113 + if (space)
74114 + {
74115 + p_Limit = (p - space + 4);
74116 +
74117 + XX_Print("0x%08X: ", (p - space));
74118 +
74119 + while (space--)
74120 + {
74121 + XX_Print("--");
74122 + }
74123 + while (size && (p < p_Limit))
74124 + {
74125 + XX_Print("%02x", *(uint8_t*)p);
74126 + size--;
74127 + p++;
74128 + }
74129 +
74130 + XX_Print(" ");
74131 + p_Limit += 12;
74132 +
74133 + while ((size > 3) && (p < p_Limit))
74134 + {
74135 + XX_Print("%08x ", *(uint32_t*)p);
74136 + size -= 4;
74137 + p += 4;
74138 + }
74139 + XX_Print("\r\n");
74140 + }
74141 +
74142 + while (size > 15)
74143 + {
74144 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
74145 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
74146 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
74147 + size -= 16;
74148 + p += 16;
74149 + }
74150 +
74151 + if (size)
74152 + {
74153 + XX_Print("0x%08X: ", p);
74154 +
74155 + while (size > 3)
74156 + {
74157 + XX_Print("%08x ", *(uint32_t *)p);
74158 + size -= 4;
74159 + p += 4;
74160 + }
74161 + while (size)
74162 + {
74163 + XX_Print("%02x", *(uint8_t *)p);
74164 + size--;
74165 + p++;
74166 + }
74167 +
74168 + XX_Print("\r\n");
74169 + }
74170 +}
74171 --- /dev/null
74172 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74173 @@ -0,0 +1,1155 @@
74174 +/*
74175 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74176 + *
74177 + * Redistribution and use in source and binary forms, with or without
74178 + * modification, are permitted provided that the following conditions are met:
74179 + * * Redistributions of source code must retain the above copyright
74180 + * notice, this list of conditions and the following disclaimer.
74181 + * * Redistributions in binary form must reproduce the above copyright
74182 + * notice, this list of conditions and the following disclaimer in the
74183 + * documentation and/or other materials provided with the distribution.
74184 + * * Neither the name of Freescale Semiconductor nor the
74185 + * names of its contributors may be used to endorse or promote products
74186 + * derived from this software without specific prior written permission.
74187 + *
74188 + *
74189 + * ALTERNATIVELY, this software may be distributed under the terms of the
74190 + * GNU General Public License ("GPL") as published by the Free Software
74191 + * Foundation, either version 2 of that License or (at your option) any
74192 + * later version.
74193 + *
74194 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74195 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74196 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74197 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74198 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74199 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74200 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74201 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74202 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74203 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74204 + */
74205 +
74206 +
74207 +#include "string_ext.h"
74208 +#include "error_ext.h"
74209 +#include "std_ext.h"
74210 +#include "part_ext.h"
74211 +#include "xx_ext.h"
74212 +
74213 +#include "mm.h"
74214 +
74215 +
74216 +
74217 +
74218 +/**********************************************************************
74219 + * MM internal routines set *
74220 + **********************************************************************/
74221 +
74222 +/****************************************************************
74223 + * Routine: CreateBusyBlock
74224 + *
74225 + * Description:
74226 + * Initializes a new busy block of "size" bytes and started
74227 + * rom "base" address. Each busy block has a name that
74228 + * specified the purpose of the memory allocation.
74229 + *
74230 + * Arguments:
74231 + * base - base address of the busy block
74232 + * size - size of the busy block
74233 + * name - name that specified the busy block
74234 + *
74235 + * Return value:
74236 + * A pointer to new created structure returned on success;
74237 + * Otherwise, NULL.
74238 + ****************************************************************/
74239 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
74240 +{
74241 + t_BusyBlock *p_BusyBlock;
74242 + uint32_t n;
74243 +
74244 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
74245 + if ( !p_BusyBlock )
74246 + {
74247 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74248 + return NULL;
74249 + }
74250 +
74251 + p_BusyBlock->base = base;
74252 + p_BusyBlock->end = base + size;
74253 +
74254 + n = strlen(name);
74255 + if (n >= MM_MAX_NAME_LEN)
74256 + n = MM_MAX_NAME_LEN - 1;
74257 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
74258 + p_BusyBlock->name[n] = '\0';
74259 + p_BusyBlock->p_Next = 0;
74260 +
74261 + return p_BusyBlock;
74262 +}
74263 +
74264 +/****************************************************************
74265 + * Routine: CreateNewBlock
74266 + *
74267 + * Description:
74268 + * Initializes a new memory block of "size" bytes and started
74269 + * from "base" address.
74270 + *
74271 + * Arguments:
74272 + * base - base address of the memory block
74273 + * size - size of the memory block
74274 + *
74275 + * Return value:
74276 + * A pointer to new created structure returned on success;
74277 + * Otherwise, NULL.
74278 + ****************************************************************/
74279 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
74280 +{
74281 + t_MemBlock *p_MemBlock;
74282 +
74283 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
74284 + if ( !p_MemBlock )
74285 + {
74286 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74287 + return NULL;
74288 + }
74289 +
74290 + p_MemBlock->base = base;
74291 + p_MemBlock->end = base+size;
74292 + p_MemBlock->p_Next = 0;
74293 +
74294 + return p_MemBlock;
74295 +}
74296 +
74297 +/****************************************************************
74298 + * Routine: CreateFreeBlock
74299 + *
74300 + * Description:
74301 + * Initializes a new free block of of "size" bytes and
74302 + * started from "base" address.
74303 + *
74304 + * Arguments:
74305 + * base - base address of the free block
74306 + * size - size of the free block
74307 + *
74308 + * Return value:
74309 + * A pointer to new created structure returned on success;
74310 + * Otherwise, NULL.
74311 + ****************************************************************/
74312 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
74313 +{
74314 + t_FreeBlock *p_FreeBlock;
74315 +
74316 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
74317 + if ( !p_FreeBlock )
74318 + {
74319 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74320 + return NULL;
74321 + }
74322 +
74323 + p_FreeBlock->base = base;
74324 + p_FreeBlock->end = base + size;
74325 + p_FreeBlock->p_Next = 0;
74326 +
74327 + return p_FreeBlock;
74328 +}
74329 +
74330 +/****************************************************************
74331 + * Routine: AddFree
74332 + *
74333 + * Description:
74334 + * Adds a new free block to the free lists. It updates each
74335 + * free list to include a new free block.
74336 + * Note, that all free block in each free list are ordered
74337 + * by their base address.
74338 + *
74339 + * Arguments:
74340 + * p_MM - pointer to the MM object
74341 + * base - base address of a given free block
74342 + * end - end address of a given free block
74343 + *
74344 + * Return value:
74345 + *
74346 + *
74347 + ****************************************************************/
74348 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
74349 +{
74350 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74351 + uint64_t alignment;
74352 + uint64_t alignBase;
74353 + int i;
74354 +
74355 + /* Updates free lists to include a just released block */
74356 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74357 + {
74358 + p_PrevB = p_NewB = 0;
74359 + p_CurrB = p_MM->freeBlocks[i];
74360 +
74361 + alignment = (uint64_t)(0x1 << i);
74362 + alignBase = MAKE_ALIGNED(base, alignment);
74363 +
74364 + /* Goes to the next free list if there is no block to free */
74365 + if (alignBase >= end)
74366 + continue;
74367 +
74368 + /* Looks for a free block that should be updated */
74369 + while ( p_CurrB )
74370 + {
74371 + if ( alignBase <= p_CurrB->end )
74372 + {
74373 + if ( end > p_CurrB->end )
74374 + {
74375 + t_FreeBlock *p_NextB;
74376 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
74377 + {
74378 + p_NextB = p_CurrB->p_Next;
74379 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74380 + XX_Free(p_NextB);
74381 + }
74382 +
74383 + p_NextB = p_CurrB->p_Next;
74384 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
74385 + {
74386 + p_CurrB->end = end;
74387 + }
74388 + else
74389 + {
74390 + p_CurrB->end = p_NextB->end;
74391 + p_CurrB->p_Next = p_NextB->p_Next;
74392 + XX_Free(p_NextB);
74393 + }
74394 + }
74395 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
74396 + {
74397 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74398 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74399 +
74400 + p_NewB->p_Next = p_CurrB;
74401 + if (p_PrevB)
74402 + p_PrevB->p_Next = p_NewB;
74403 + else
74404 + p_MM->freeBlocks[i] = p_NewB;
74405 + break;
74406 + }
74407 +
74408 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
74409 + {
74410 + p_CurrB->base = alignBase;
74411 + }
74412 +
74413 + /* if size of the free block is less then alignment
74414 + * deletes that free block from the free list. */
74415 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
74416 + {
74417 + if ( p_PrevB )
74418 + p_PrevB->p_Next = p_CurrB->p_Next;
74419 + else
74420 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74421 + XX_Free(p_CurrB);
74422 + p_CurrB = NULL;
74423 + }
74424 + break;
74425 + }
74426 + else
74427 + {
74428 + p_PrevB = p_CurrB;
74429 + p_CurrB = p_CurrB->p_Next;
74430 + }
74431 + }
74432 +
74433 + /* If no free block found to be updated, insert a new free block
74434 + * to the end of the free list.
74435 + */
74436 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
74437 + {
74438 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
74439 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74440 +
74441 + if (p_PrevB)
74442 + p_PrevB->p_Next = p_NewB;
74443 + else
74444 + p_MM->freeBlocks[i] = p_NewB;
74445 + }
74446 +
74447 + /* Update boundaries of the new free block */
74448 + if ((alignment == 1) && !p_NewB)
74449 + {
74450 + if ( p_CurrB && base > p_CurrB->base )
74451 + base = p_CurrB->base;
74452 + if ( p_CurrB && end < p_CurrB->end )
74453 + end = p_CurrB->end;
74454 + }
74455 + }
74456 +
74457 + return (E_OK);
74458 +}
74459 +
74460 +/****************************************************************
74461 + * Routine: CutFree
74462 + *
74463 + * Description:
74464 + * Cuts a free block from holdBase to holdEnd from the free lists.
74465 + * That is, it updates all free lists of the MM object do
74466 + * not include a block of memory from holdBase to holdEnd.
74467 + * For each free lists it seek for a free block that holds
74468 + * either holdBase or holdEnd. If such block is found it updates it.
74469 + *
74470 + * Arguments:
74471 + * p_MM - pointer to the MM object
74472 + * holdBase - base address of the allocated block
74473 + * holdEnd - end address of the allocated block
74474 + *
74475 + * Return value:
74476 + * E_OK is returned on success,
74477 + * otherwise returns an error code.
74478 + *
74479 + ****************************************************************/
74480 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
74481 +{
74482 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74483 + uint64_t alignBase, base, end;
74484 + uint64_t alignment;
74485 + int i;
74486 +
74487 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74488 + {
74489 + p_PrevB = p_NewB = 0;
74490 + p_CurrB = p_MM->freeBlocks[i];
74491 +
74492 + alignment = (uint64_t)(0x1 << i);
74493 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
74494 +
74495 + while ( p_CurrB )
74496 + {
74497 + base = p_CurrB->base;
74498 + end = p_CurrB->end;
74499 +
74500 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
74501 + {
74502 + if ( alignBase >= end ||
74503 + (alignBase < end && ((end-alignBase) < alignment)) )
74504 + {
74505 + if (p_PrevB)
74506 + p_PrevB->p_Next = p_CurrB->p_Next;
74507 + else
74508 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74509 + XX_Free(p_CurrB);
74510 + }
74511 + else
74512 + {
74513 + p_CurrB->base = alignBase;
74514 + }
74515 + break;
74516 + }
74517 + else if ( (holdBase > base) && (holdEnd <= end) )
74518 + {
74519 + if ( (holdBase-base) >= alignment )
74520 + {
74521 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74522 + {
74523 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74524 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74525 + p_NewB->p_Next = p_CurrB->p_Next;
74526 + p_CurrB->p_Next = p_NewB;
74527 + }
74528 + p_CurrB->end = holdBase;
74529 + }
74530 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74531 + {
74532 + p_CurrB->base = alignBase;
74533 + }
74534 + else
74535 + {
74536 + if (p_PrevB)
74537 + p_PrevB->p_Next = p_CurrB->p_Next;
74538 + else
74539 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74540 + XX_Free(p_CurrB);
74541 + }
74542 + break;
74543 + }
74544 + else
74545 + {
74546 + p_PrevB = p_CurrB;
74547 + p_CurrB = p_CurrB->p_Next;
74548 + }
74549 + }
74550 + }
74551 +
74552 + return (E_OK);
74553 +}
74554 +
74555 +/****************************************************************
74556 + * Routine: AddBusy
74557 + *
74558 + * Description:
74559 + * Adds a new busy block to the list of busy blocks. Note,
74560 + * that all busy blocks are ordered by their base address in
74561 + * the busy list.
74562 + *
74563 + * Arguments:
74564 + * MM - handler to the MM object
74565 + * p_NewBusyB - pointer to the a busy block
74566 + *
74567 + * Return value:
74568 + * None.
74569 + *
74570 + ****************************************************************/
74571 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
74572 +{
74573 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
74574 +
74575 + /* finds a place of a new busy block in the list of busy blocks */
74576 + p_PrevBusyB = 0;
74577 + p_CurrBusyB = p_MM->busyBlocks;
74578 +
74579 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
74580 + {
74581 + p_PrevBusyB = p_CurrBusyB;
74582 + p_CurrBusyB = p_CurrBusyB->p_Next;
74583 + }
74584 +
74585 + /* insert the new busy block into the list of busy blocks */
74586 + if ( p_CurrBusyB )
74587 + p_NewBusyB->p_Next = p_CurrBusyB;
74588 + if ( p_PrevBusyB )
74589 + p_PrevBusyB->p_Next = p_NewBusyB;
74590 + else
74591 + p_MM->busyBlocks = p_NewBusyB;
74592 +}
74593 +
74594 +/****************************************************************
74595 + * Routine: CutBusy
74596 + *
74597 + * Description:
74598 + * Cuts a block from base to end from the list of busy blocks.
74599 + * This is done by updating the list of busy blocks do not
74600 + * include a given block, that block is going to be free. If a
74601 + * given block is a part of some other busy block, so that
74602 + * busy block is updated. If there are number of busy blocks
74603 + * included in the given block, so all that blocks are removed
74604 + * from the busy list and the end blocks are updated.
74605 + * If the given block devides some block into two parts, a new
74606 + * busy block is added to the busy list.
74607 + *
74608 + * Arguments:
74609 + * p_MM - pointer to the MM object
74610 + * base - base address of a given busy block
74611 + * end - end address of a given busy block
74612 + *
74613 + * Return value:
74614 + * E_OK on success, E_NOMEMORY otherwise.
74615 + *
74616 + ****************************************************************/
74617 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
74618 +{
74619 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
74620 +
74621 + p_CurrB = p_MM->busyBlocks;
74622 + p_PrevB = p_NewB = 0;
74623 +
74624 + while ( p_CurrB )
74625 + {
74626 + if ( base < p_CurrB->end )
74627 + {
74628 + if ( end > p_CurrB->end )
74629 + {
74630 + t_BusyBlock *p_NextB;
74631 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
74632 + {
74633 + p_NextB = p_CurrB->p_Next;
74634 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74635 + XX_Free(p_NextB);
74636 + }
74637 +
74638 + p_NextB = p_CurrB->p_Next;
74639 + if ( p_NextB && end > p_NextB->base )
74640 + {
74641 + p_NextB->base = end;
74642 + }
74643 + }
74644 +
74645 + if ( base <= p_CurrB->base )
74646 + {
74647 + if ( end < p_CurrB->end && end > p_CurrB->base )
74648 + {
74649 + p_CurrB->base = end;
74650 + }
74651 + else if ( end >= p_CurrB->end )
74652 + {
74653 + if ( p_PrevB )
74654 + p_PrevB->p_Next = p_CurrB->p_Next;
74655 + else
74656 + p_MM->busyBlocks = p_CurrB->p_Next;
74657 + XX_Free(p_CurrB);
74658 + }
74659 + }
74660 + else
74661 + {
74662 + if ( end < p_CurrB->end && end > p_CurrB->base )
74663 + {
74664 + if ((p_NewB = CreateBusyBlock(end,
74665 + p_CurrB->end-end,
74666 + p_CurrB->name)) == NULL)
74667 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74668 + p_NewB->p_Next = p_CurrB->p_Next;
74669 + p_CurrB->p_Next = p_NewB;
74670 + }
74671 + p_CurrB->end = base;
74672 + }
74673 + break;
74674 + }
74675 + else
74676 + {
74677 + p_PrevB = p_CurrB;
74678 + p_CurrB = p_CurrB->p_Next;
74679 + }
74680 + }
74681 +
74682 + return (E_OK);
74683 +}
74684 +
74685 +/****************************************************************
74686 + * Routine: MmGetGreaterAlignment
74687 + *
74688 + * Description:
74689 + * Allocates a block of memory according to the given size
74690 + * and the alignment. That routine is called from the MM_Get
74691 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
74692 + * In that case, it goes over free blocks of 64 byte align list
74693 + * and checks if it has the required size of bytes of the required
74694 + * alignment. If no blocks found returns ILLEGAL_BASE.
74695 + * After the block is found and data is allocated, it calls
74696 + * the internal CutFree routine to update all free lists
74697 + * do not include a just allocated block. Of course, each
74698 + * free list contains a free blocks with the same alignment.
74699 + * It is also creates a busy block that holds
74700 + * information about an allocated block.
74701 + *
74702 + * Arguments:
74703 + * MM - handle to the MM object
74704 + * size - size of the MM
74705 + * alignment - index as a power of two defines
74706 + * a required alignment that is greater then 64.
74707 + * name - the name that specifies an allocated block.
74708 + *
74709 + * Return value:
74710 + * base address of an allocated block.
74711 + * ILLEGAL_BASE if can't allocate a block
74712 + *
74713 + ****************************************************************/
74714 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
74715 +{
74716 + t_FreeBlock *p_FreeB;
74717 + t_BusyBlock *p_NewBusyB;
74718 + uint64_t holdBase, holdEnd, alignBase = 0;
74719 +
74720 + /* goes over free blocks of the 64 byte alignment list
74721 + and look for a block of the suitable size and
74722 + base address according to the alignment. */
74723 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
74724 +
74725 + while ( p_FreeB )
74726 + {
74727 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
74728 +
74729 + /* the block is found if the aligned base inside the block
74730 + * and has the anough size. */
74731 + if ( alignBase >= p_FreeB->base &&
74732 + alignBase < p_FreeB->end &&
74733 + size <= (p_FreeB->end - alignBase) )
74734 + break;
74735 + else
74736 + p_FreeB = p_FreeB->p_Next;
74737 + }
74738 +
74739 + /* If such block isn't found */
74740 + if ( !p_FreeB )
74741 + return (uint64_t)(ILLEGAL_BASE);
74742 +
74743 + holdBase = alignBase;
74744 + holdEnd = alignBase + size;
74745 +
74746 + /* init a new busy block */
74747 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
74748 + return (uint64_t)(ILLEGAL_BASE);
74749 +
74750 + /* calls Update routine to update a lists of free blocks */
74751 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
74752 + {
74753 + XX_Free(p_NewBusyB);
74754 + return (uint64_t)(ILLEGAL_BASE);
74755 + }
74756 +
74757 + /* insert the new busy block into the list of busy blocks */
74758 + AddBusy ( p_MM, p_NewBusyB );
74759 +
74760 + return (holdBase);
74761 +}
74762 +
74763 +
74764 +/**********************************************************************
74765 + * MM API routines set *
74766 + **********************************************************************/
74767 +
74768 +/*****************************************************************************/
74769 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
74770 +{
74771 + t_MM *p_MM;
74772 + uint64_t newBase, newSize;
74773 + int i;
74774 +
74775 + if (!size)
74776 + {
74777 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
74778 + }
74779 +
74780 + /* Initializes a new MM object */
74781 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
74782 + if (!p_MM)
74783 + {
74784 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74785 + }
74786 +
74787 + p_MM->h_Spinlock = XX_InitSpinlock();
74788 + if (!p_MM->h_Spinlock)
74789 + {
74790 + XX_Free(p_MM);
74791 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
74792 + }
74793 +
74794 + /* Initializes counter of free memory to total size */
74795 + p_MM->freeMemSize = size;
74796 +
74797 + /* A busy list is empty */
74798 + p_MM->busyBlocks = 0;
74799 +
74800 + /* Initializes a new memory block */
74801 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
74802 + {
74803 + MM_Free(p_MM);
74804 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74805 + }
74806 +
74807 + /* Initializes a new free block for each free list*/
74808 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74809 + {
74810 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
74811 + newSize = size - (newBase - base);
74812 +
74813 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
74814 + {
74815 + MM_Free(p_MM);
74816 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74817 + }
74818 + }
74819 +
74820 + *h_MM = p_MM;
74821 +
74822 + return (E_OK);
74823 +}
74824 +
74825 +/*****************************************************************************/
74826 +void MM_Free(t_Handle h_MM)
74827 +{
74828 + t_MM *p_MM = (t_MM *)h_MM;
74829 + t_MemBlock *p_MemBlock;
74830 + t_BusyBlock *p_BusyBlock;
74831 + t_FreeBlock *p_FreeBlock;
74832 + void *p_Block;
74833 + int i;
74834 +
74835 + ASSERT_COND(p_MM);
74836 +
74837 + /* release memory allocated for busy blocks */
74838 + p_BusyBlock = p_MM->busyBlocks;
74839 + while ( p_BusyBlock )
74840 + {
74841 + p_Block = p_BusyBlock;
74842 + p_BusyBlock = p_BusyBlock->p_Next;
74843 + XX_Free(p_Block);
74844 + }
74845 +
74846 + /* release memory allocated for free blocks */
74847 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74848 + {
74849 + p_FreeBlock = p_MM->freeBlocks[i];
74850 + while ( p_FreeBlock )
74851 + {
74852 + p_Block = p_FreeBlock;
74853 + p_FreeBlock = p_FreeBlock->p_Next;
74854 + XX_Free(p_Block);
74855 + }
74856 + }
74857 +
74858 + /* release memory allocated for memory blocks */
74859 + p_MemBlock = p_MM->memBlocks;
74860 + while ( p_MemBlock )
74861 + {
74862 + p_Block = p_MemBlock;
74863 + p_MemBlock = p_MemBlock->p_Next;
74864 + XX_Free(p_Block);
74865 + }
74866 +
74867 + if (p_MM->h_Spinlock)
74868 + XX_FreeSpinlock(p_MM->h_Spinlock);
74869 +
74870 + /* release memory allocated for MM object itself */
74871 + XX_Free(p_MM);
74872 +}
74873 +
74874 +/*****************************************************************************/
74875 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
74876 +{
74877 + t_MM *p_MM = (t_MM *)h_MM;
74878 + t_FreeBlock *p_FreeB;
74879 + t_BusyBlock *p_NewBusyB;
74880 + uint64_t holdBase, holdEnd, j, i = 0;
74881 + uint32_t intFlags;
74882 +
74883 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
74884 +
74885 + /* checks that alignment value is greater then zero */
74886 + if (alignment == 0)
74887 + {
74888 + alignment = 1;
74889 + }
74890 +
74891 + j = alignment;
74892 +
74893 + /* checks if alignment is a power of two, if it correct and if the
74894 + required size is multiple of the given alignment. */
74895 + while ((j & 0x1) == 0)
74896 + {
74897 + i++;
74898 + j = j >> 1;
74899 + }
74900 +
74901 + /* if the given alignment isn't power of two, returns an error */
74902 + if (j != 1)
74903 + {
74904 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
74905 + return (uint64_t)ILLEGAL_BASE;
74906 + }
74907 +
74908 + if (i > MM_MAX_ALIGNMENT)
74909 + {
74910 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
74911 + }
74912 +
74913 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
74914 + /* look for a block of the size greater or equal to the required size. */
74915 + p_FreeB = p_MM->freeBlocks[i];
74916 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
74917 + p_FreeB = p_FreeB->p_Next;
74918 +
74919 + /* If such block is found */
74920 + if ( !p_FreeB )
74921 + {
74922 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74923 + return (uint64_t)(ILLEGAL_BASE);
74924 + }
74925 +
74926 + holdBase = p_FreeB->base;
74927 + holdEnd = holdBase + size;
74928 +
74929 + /* init a new busy block */
74930 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
74931 + {
74932 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74933 + return (uint64_t)(ILLEGAL_BASE);
74934 + }
74935 +
74936 + /* calls Update routine to update a lists of free blocks */
74937 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
74938 + {
74939 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74940 + XX_Free(p_NewBusyB);
74941 + return (uint64_t)(ILLEGAL_BASE);
74942 + }
74943 +
74944 + /* Decreasing the allocated memory size from free memory size */
74945 + p_MM->freeMemSize -= size;
74946 +
74947 + /* insert the new busy block into the list of busy blocks */
74948 + AddBusy ( p_MM, p_NewBusyB );
74949 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74950 +
74951 + return (holdBase);
74952 +}
74953 +
74954 +/*****************************************************************************/
74955 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
74956 +{
74957 + t_MM *p_MM = (t_MM *)h_MM;
74958 + t_FreeBlock *p_FreeB;
74959 + t_BusyBlock *p_NewBusyB;
74960 + uint32_t intFlags;
74961 + bool blockIsFree = FALSE;
74962 +
74963 + ASSERT_COND(p_MM);
74964 +
74965 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
74966 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
74967 + free list with alignment 1 */
74968 +
74969 + while ( p_FreeB )
74970 + {
74971 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
74972 + {
74973 + blockIsFree = TRUE;
74974 + break;
74975 + }
74976 + else
74977 + p_FreeB = p_FreeB->p_Next;
74978 + }
74979 +
74980 + if ( !blockIsFree )
74981 + {
74982 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74983 + return (uint64_t)(ILLEGAL_BASE);
74984 + }
74985 +
74986 + /* init a new busy block */
74987 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
74988 + {
74989 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74990 + return (uint64_t)(ILLEGAL_BASE);
74991 + }
74992 +
74993 + /* calls Update routine to update a lists of free blocks */
74994 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
74995 + {
74996 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
74997 + XX_Free(p_NewBusyB);
74998 + return (uint64_t)(ILLEGAL_BASE);
74999 + }
75000 +
75001 + /* Decreasing the allocated memory size from free memory size */
75002 + p_MM->freeMemSize -= size;
75003 +
75004 + /* insert the new busy block into the list of busy blocks */
75005 + AddBusy ( p_MM, p_NewBusyB );
75006 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75007 +
75008 + return (base);
75009 +}
75010 +
75011 +/*****************************************************************************/
75012 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
75013 +{
75014 + t_MM *p_MM = (t_MM *)h_MM;
75015 + t_FreeBlock *p_FreeB;
75016 + t_BusyBlock *p_NewBusyB;
75017 + uint64_t holdBase, holdEnd, j = alignment, i=0;
75018 + uint32_t intFlags;
75019 +
75020 + ASSERT_COND(p_MM);
75021 +
75022 + /* checks if alignment is a power of two, if it correct and if the
75023 + required size is multiple of the given alignment. */
75024 + while ((j & 0x1) == 0)
75025 + {
75026 + i++;
75027 + j = j >> 1;
75028 + }
75029 +
75030 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
75031 + {
75032 + return (uint64_t)(ILLEGAL_BASE);
75033 + }
75034 +
75035 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75036 + p_FreeB = p_MM->freeBlocks[i];
75037 +
75038 + /* look for the first block that contains the minimum
75039 + base address. If the whole required size may be fit
75040 + into it, use that block, otherwise look for the next
75041 + block of size greater or equal to the required size. */
75042 + while ( p_FreeB && (min >= p_FreeB->end))
75043 + p_FreeB = p_FreeB->p_Next;
75044 +
75045 + /* If such block is found */
75046 + if ( !p_FreeB )
75047 + {
75048 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75049 + return (uint64_t)(ILLEGAL_BASE);
75050 + }
75051 +
75052 + /* if this block is large enough, use this block */
75053 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
75054 + if ((holdBase + size) <= p_FreeB->end )
75055 + {
75056 + holdEnd = holdBase + size;
75057 + }
75058 + else
75059 + {
75060 + p_FreeB = p_FreeB->p_Next;
75061 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
75062 + p_FreeB = p_FreeB->p_Next;
75063 +
75064 + /* If such block is found */
75065 + if ( !p_FreeB )
75066 + {
75067 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75068 + return (uint64_t)(ILLEGAL_BASE);
75069 + }
75070 +
75071 + holdBase = p_FreeB->base;
75072 + holdEnd = holdBase + size;
75073 + }
75074 +
75075 + /* init a new busy block */
75076 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75077 + {
75078 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75079 + return (uint64_t)(ILLEGAL_BASE);
75080 + }
75081 +
75082 + /* calls Update routine to update a lists of free blocks */
75083 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
75084 + {
75085 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75086 + XX_Free(p_NewBusyB);
75087 + return (uint64_t)(ILLEGAL_BASE);
75088 + }
75089 +
75090 + /* Decreasing the allocated memory size from free memory size */
75091 + p_MM->freeMemSize -= size;
75092 +
75093 + /* insert the new busy block into the list of busy blocks */
75094 + AddBusy( p_MM, p_NewBusyB );
75095 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75096 +
75097 + return (holdBase);
75098 +}
75099 +
75100 +/*****************************************************************************/
75101 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
75102 +{
75103 + t_MM *p_MM = (t_MM *)h_MM;
75104 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
75105 + uint64_t size;
75106 + uint32_t intFlags;
75107 +
75108 + ASSERT_COND(p_MM);
75109 +
75110 + /* Look for a busy block that have the given base value.
75111 + * That block will be returned back to the memory.
75112 + */
75113 + p_PrevBusyB = 0;
75114 +
75115 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75116 + p_BusyB = p_MM->busyBlocks;
75117 + while ( p_BusyB && base != p_BusyB->base )
75118 + {
75119 + p_PrevBusyB = p_BusyB;
75120 + p_BusyB = p_BusyB->p_Next;
75121 + }
75122 +
75123 + if ( !p_BusyB )
75124 + {
75125 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75126 + return (uint64_t)(0);
75127 + }
75128 +
75129 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
75130 + {
75131 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75132 + return (uint64_t)(0);
75133 + }
75134 +
75135 + /* removes a busy block form the list of busy blocks */
75136 + if ( p_PrevBusyB )
75137 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
75138 + else
75139 + p_MM->busyBlocks = p_BusyB->p_Next;
75140 +
75141 + size = p_BusyB->end - p_BusyB->base;
75142 +
75143 + /* Adding the deallocated memory size to free memory size */
75144 + p_MM->freeMemSize += size;
75145 +
75146 + XX_Free(p_BusyB);
75147 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75148 +
75149 + return (size);
75150 +}
75151 +
75152 +/*****************************************************************************/
75153 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
75154 +{
75155 + t_MM *p_MM = (t_MM *)h_MM;
75156 + uint64_t end = base + size;
75157 + uint32_t intFlags;
75158 +
75159 + ASSERT_COND(p_MM);
75160 +
75161 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75162 +
75163 + if ( CutBusy( p_MM, base, end ) != E_OK )
75164 + {
75165 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75166 + return (uint64_t)(0);
75167 + }
75168 +
75169 + if ( AddFree ( p_MM, base, end ) != E_OK )
75170 + {
75171 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75172 + return (uint64_t)(0);
75173 + }
75174 +
75175 + /* Adding the deallocated memory size to free memory size */
75176 + p_MM->freeMemSize += size;
75177 +
75178 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75179 +
75180 + return (size);
75181 +}
75182 +
75183 +/*****************************************************************************/
75184 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
75185 +{
75186 + t_MM *p_MM = (t_MM *)h_MM;
75187 + t_MemBlock *p_MemB, *p_NewMemB;
75188 + t_Error errCode;
75189 + uint32_t intFlags;
75190 +
75191 + ASSERT_COND(p_MM);
75192 +
75193 + /* find a last block in the list of memory blocks to insert a new
75194 + * memory block
75195 + */
75196 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75197 +
75198 + p_MemB = p_MM->memBlocks;
75199 + while ( p_MemB->p_Next )
75200 + {
75201 + if ( base >= p_MemB->base && base < p_MemB->end )
75202 + {
75203 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75204 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75205 + }
75206 + p_MemB = p_MemB->p_Next;
75207 + }
75208 + /* check for a last memory block */
75209 + if ( base >= p_MemB->base && base < p_MemB->end )
75210 + {
75211 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75212 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75213 + }
75214 +
75215 + /* create a new memory block */
75216 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
75217 + {
75218 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75219 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75220 + }
75221 +
75222 + /* append a new memory block to the end of the list of memory blocks */
75223 + p_MemB->p_Next = p_NewMemB;
75224 +
75225 + /* add a new free block to the free lists */
75226 + errCode = AddFree(p_MM, base, base+size);
75227 + if (errCode)
75228 + {
75229 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75230 + p_MemB->p_Next = 0;
75231 + XX_Free(p_NewMemB);
75232 + return ((t_Error)errCode);
75233 + }
75234 +
75235 + /* Adding the new block size to free memory size */
75236 + p_MM->freeMemSize += size;
75237 +
75238 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75239 +
75240 + return (E_OK);
75241 +}
75242 +
75243 +/*****************************************************************************/
75244 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
75245 +{
75246 + t_MM *p_MM = (t_MM*)h_MM;
75247 + t_MemBlock *p_MemBlock;
75248 + int i;
75249 +
75250 + ASSERT_COND(p_MM);
75251 +
75252 + p_MemBlock = p_MM->memBlocks;
75253 + for (i=0; i < index; i++)
75254 + p_MemBlock = p_MemBlock->p_Next;
75255 +
75256 + if ( p_MemBlock )
75257 + return (p_MemBlock->base);
75258 + else
75259 + return (uint64_t)ILLEGAL_BASE;
75260 +}
75261 +
75262 +/*****************************************************************************/
75263 +uint64_t MM_GetBase(t_Handle h_MM)
75264 +{
75265 + t_MM *p_MM = (t_MM*)h_MM;
75266 + t_MemBlock *p_MemBlock;
75267 +
75268 + ASSERT_COND(p_MM);
75269 +
75270 + p_MemBlock = p_MM->memBlocks;
75271 + return p_MemBlock->base;
75272 +}
75273 +
75274 +/*****************************************************************************/
75275 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
75276 +{
75277 + t_MM *p_MM = (t_MM*)h_MM;
75278 + t_MemBlock *p_MemBlock;
75279 +
75280 + ASSERT_COND(p_MM);
75281 +
75282 + p_MemBlock = p_MM->memBlocks;
75283 +
75284 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
75285 + return TRUE;
75286 + else
75287 + return FALSE;
75288 +}
75289 +
75290 +/*****************************************************************************/
75291 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
75292 +{
75293 + t_MM *p_MM = (t_MM*)h_MM;
75294 +
75295 + ASSERT_COND(p_MM);
75296 +
75297 + return p_MM->freeMemSize;
75298 +}
75299 +
75300 +/*****************************************************************************/
75301 +void MM_Dump(t_Handle h_MM)
75302 +{
75303 + t_MM *p_MM = (t_MM *)h_MM;
75304 + t_FreeBlock *p_FreeB;
75305 + t_BusyBlock *p_BusyB;
75306 + int i;
75307 +
75308 + p_BusyB = p_MM->busyBlocks;
75309 + XX_Print("List of busy blocks:\n");
75310 + while (p_BusyB)
75311 + {
75312 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
75313 + p_BusyB = p_BusyB->p_Next;
75314 + }
75315 +
75316 + XX_Print("\nLists of free blocks according to alignment:\n");
75317 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75318 + {
75319 + XX_Print("%d alignment:\n", (0x1 << i));
75320 + p_FreeB = p_MM->freeBlocks[i];
75321 + while (p_FreeB)
75322 + {
75323 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
75324 + p_FreeB = p_FreeB->p_Next;
75325 + }
75326 + XX_Print("\n");
75327 + }
75328 +}
75329 --- /dev/null
75330 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75331 @@ -0,0 +1,105 @@
75332 +/*
75333 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75334 + *
75335 + * Redistribution and use in source and binary forms, with or without
75336 + * modification, are permitted provided that the following conditions are met:
75337 + * * Redistributions of source code must retain the above copyright
75338 + * notice, this list of conditions and the following disclaimer.
75339 + * * Redistributions in binary form must reproduce the above copyright
75340 + * notice, this list of conditions and the following disclaimer in the
75341 + * documentation and/or other materials provided with the distribution.
75342 + * * Neither the name of Freescale Semiconductor nor the
75343 + * names of its contributors may be used to endorse or promote products
75344 + * derived from this software without specific prior written permission.
75345 + *
75346 + *
75347 + * ALTERNATIVELY, this software may be distributed under the terms of the
75348 + * GNU General Public License ("GPL") as published by the Free Software
75349 + * Foundation, either version 2 of that License or (at your option) any
75350 + * later version.
75351 + *
75352 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75353 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75354 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75355 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75356 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75357 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75358 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75359 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75360 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75361 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75362 + */
75363 +
75364 +
75365 +/****************************************************************
75366 + *
75367 + * File: mm.h
75368 + *
75369 + *
75370 + * Description:
75371 + * MM (Memory Management) object definitions.
75372 + * It also includes definitions of the Free Block, Busy Block
75373 + * and Memory Block structures used by the MM object.
75374 + *
75375 + ****************************************************************/
75376 +
75377 +#ifndef __MM_H
75378 +#define __MM_H
75379 +
75380 +
75381 +#include "mm_ext.h"
75382 +
75383 +#define __ERR_MODULE__ MODULE_MM
75384 +
75385 +
75386 +#define MAKE_ALIGNED(addr, align) \
75387 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
75388 +
75389 +
75390 +/* t_MemBlock data structure defines parameters of the Memory Block */
75391 +typedef struct t_MemBlock
75392 +{
75393 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
75394 +
75395 + uint64_t base; /* Base address of the memory block */
75396 + uint64_t end; /* End address of the memory block */
75397 +} t_MemBlock;
75398 +
75399 +
75400 +/* t_FreeBlock data structure defines parameters of the Free Block */
75401 +typedef struct t_FreeBlock
75402 +{
75403 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
75404 +
75405 + uint64_t base; /* Base address of the block */
75406 + uint64_t end; /* End address of the block */
75407 +} t_FreeBlock;
75408 +
75409 +
75410 +/* t_BusyBlock data structure defines parameters of the Busy Block */
75411 +typedef struct t_BusyBlock
75412 +{
75413 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
75414 +
75415 + uint64_t base; /* Base address of the block */
75416 + uint64_t end; /* End address of the block */
75417 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
75418 + something specified by the Name */
75419 +} t_BusyBlock;
75420 +
75421 +
75422 +/* t_MM data structure defines parameters of the MM object */
75423 +typedef struct t_MM
75424 +{
75425 + t_Handle h_Spinlock;
75426 +
75427 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
75428 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
75429 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
75430 + /* Alignment lists of free blocks (Free lists) */
75431 +
75432 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
75433 +} t_MM;
75434 +
75435 +
75436 +#endif /* __MM_H */
75437 --- /dev/null
75438 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75439 @@ -0,0 +1,81 @@
75440 +/*
75441 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75442 + *
75443 + * Redistribution and use in source and binary forms, with or without
75444 + * modification, are permitted provided that the following conditions are met:
75445 + * * Redistributions of source code must retain the above copyright
75446 + * notice, this list of conditions and the following disclaimer.
75447 + * * Redistributions in binary form must reproduce the above copyright
75448 + * notice, this list of conditions and the following disclaimer in the
75449 + * documentation and/or other materials provided with the distribution.
75450 + * * Neither the name of Freescale Semiconductor nor the
75451 + * names of its contributors may be used to endorse or promote products
75452 + * derived from this software without specific prior written permission.
75453 + *
75454 + *
75455 + * ALTERNATIVELY, this software may be distributed under the terms of the
75456 + * GNU General Public License ("GPL") as published by the Free Software
75457 + * Foundation, either version 2 of that License or (at your option) any
75458 + * later version.
75459 + *
75460 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75461 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75462 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75463 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75464 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75465 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75466 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75467 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75468 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75469 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75470 + */
75471 +
75472 +
75473 +/*------------------------------------------------------*/
75474 +/* File: sprint.c */
75475 +/* */
75476 +/* Description: */
75477 +/* Debug routines (externals) */
75478 +/*------------------------------------------------------*/
75479 +#include "string_ext.h"
75480 +#include "stdlib_ext.h"
75481 +#include "stdarg_ext.h"
75482 +#include "sprint_ext.h"
75483 +#include "std_ext.h"
75484 +#include "xx_ext.h"
75485 +
75486 +
75487 +int Sprint(char * buf, const char *fmt, ...)
75488 +{
75489 + va_list args;
75490 + int i;
75491 +
75492 + va_start(args, fmt);
75493 + i=vsprintf(buf,fmt,args);
75494 + va_end(args);
75495 + return i;
75496 +}
75497 +
75498 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
75499 +{
75500 + va_list args;
75501 + int i;
75502 +
75503 + va_start(args, fmt);
75504 + i=vsnprintf(buf,size,fmt,args);
75505 + va_end(args);
75506 + return i;
75507 +}
75508 +
75509 +#ifndef NCSW_VXWORKS
75510 +int Sscan(const char * buf, const char * fmt, ...)
75511 +{
75512 + va_list args;
75513 + int i;
75514 +
75515 + va_start(args,fmt);
75516 + i = vsscanf(buf,fmt,args);
75517 + va_end(args);
75518 + return i;
75519 +}
75520 +#endif /* NCSW_VXWORKS */
75521 --- /dev/null
75522 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75523 @@ -0,0 +1,57 @@
75524 +/*
75525 + * Copyright 2012 Freescale Semiconductor Inc.
75526 + *
75527 + * Redistribution and use in source and binary forms, with or without
75528 + * modification, are permitted provided that the following conditions are met:
75529 + * * Redistributions of source code must retain the above copyright
75530 + * notice, this list of conditions and the following disclaimer.
75531 + * * Redistributions in binary form must reproduce the above copyright
75532 + * notice, this list of conditions and the following disclaimer in the
75533 + * documentation and/or other materials provided with the distribution.
75534 + * * Neither the name of Freescale Semiconductor nor the
75535 + * names of its contributors may be used to endorse or promote products
75536 + * derived from this software without specific prior written permission.
75537 + *
75538 + *
75539 + * ALTERNATIVELY, this software may be distributed under the terms of the
75540 + * GNU General Public License ("GPL") as published by the Free Software
75541 + * Foundation, either version 2 of that License or (at your option) any
75542 + * later version.
75543 + *
75544 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75545 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75546 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75547 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75548 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75549 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75550 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75551 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75552 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75553 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75554 + */
75555 +
75556 +#ifndef __dflags_h
75557 +#define __dflags_h
75558 +
75559 +
75560 +#define NCSW_LINUX
75561 +
75562 +#define T4240
75563 +#define NCSW_PPC_CORE
75564 +
75565 +#define DEBUG_ERRORS 1
75566 +
75567 +#if defined(DEBUG)
75568 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75569 +
75570 +#define DEBUG_XX_MALLOC
75571 +#define DEBUG_MEM_LEAKS
75572 +
75573 +#else
75574 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75575 +#endif /* (DEBUG) */
75576 +
75577 +#define REPORT_EVENTS 1
75578 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75579 +
75580 +#endif /* __dflags_h */
75581 --- /dev/null
75582 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
75583 @@ -0,0 +1,56 @@
75584 +/*
75585 + * Copyright 2012 Freescale Semiconductor Inc.
75586 + *
75587 + * Redistribution and use in source and binary forms, with or without
75588 + * modification, are permitted provided that the following conditions are met:
75589 + * * Redistributions of source code must retain the above copyright
75590 + * notice, this list of conditions and the following disclaimer.
75591 + * * Redistributions in binary form must reproduce the above copyright
75592 + * notice, this list of conditions and the following disclaimer in the
75593 + * documentation and/or other materials provided with the distribution.
75594 + * * Neither the name of Freescale Semiconductor nor the
75595 + * names of its contributors may be used to endorse or promote products
75596 + * derived from this software without specific prior written permission.
75597 + *
75598 + *
75599 + * ALTERNATIVELY, this software may be distributed under the terms of the
75600 + * GNU General Public License ("GPL") as published by the Free Software
75601 + * Foundation, either version 2 of that License or (at your option) any
75602 + * later version.
75603 + *
75604 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75605 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75606 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75607 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75608 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75609 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75610 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75611 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75612 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75613 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75614 + */
75615 +
75616 +#ifndef __dflags_h
75617 +#define __dflags_h
75618 +
75619 +
75620 +#define NCSW_LINUX
75621 +
75622 +#define NCSW_PPC_CORE
75623 +
75624 +#define DEBUG_ERRORS 1
75625 +
75626 +#if defined(DEBUG)
75627 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75628 +
75629 +#define DEBUG_XX_MALLOC
75630 +#define DEBUG_MEM_LEAKS
75631 +
75632 +#else
75633 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75634 +#endif /* (DEBUG) */
75635 +
75636 +#define REPORT_EVENTS 1
75637 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75638 +
75639 +#endif /* __dflags_h */
75640 --- /dev/null
75641 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
75642 @@ -0,0 +1,364 @@
75643 +/*
75644 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75645 + *
75646 + * Redistribution and use in source and binary forms, with or without
75647 + * modification, are permitted provided that the following conditions are met:
75648 + * * Redistributions of source code must retain the above copyright
75649 + * notice, this list of conditions and the following disclaimer.
75650 + * * Redistributions in binary form must reproduce the above copyright
75651 + * notice, this list of conditions and the following disclaimer in the
75652 + * documentation and/or other materials provided with the distribution.
75653 + * * Neither the name of Freescale Semiconductor nor the
75654 + * names of its contributors may be used to endorse or promote products
75655 + * derived from this software without specific prior written permission.
75656 + *
75657 + *
75658 + * ALTERNATIVELY, this software may be distributed under the terms of the
75659 + * GNU General Public License ("GPL") as published by the Free Software
75660 + * Foundation, either version 2 of that License or (at your option) any
75661 + * later version.
75662 + *
75663 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75664 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75665 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75666 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75667 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75668 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75670 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75671 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75672 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75673 + */
75674 +
75675 +
75676 +/*------------------------------------------------------*/
75677 +/* */
75678 +/* File: crc_mac_addr_ext.h */
75679 +/* */
75680 +/* Description: */
75681 +/* Define a macro that calculate the crc value of */
75682 +/* an Ethernet MAC address (48 bitd address */
75683 +/*------------------------------------------------------*/
75684 +
75685 +#ifndef __crc_mac_addr_ext_h
75686 +#define __crc_mac_addr_ext_h
75687 +
75688 +#include "std_ext.h"
75689 +
75690 +
75691 +static uint32_t crc_table[256] =
75692 +{
75693 + 0x00000000,
75694 + 0x77073096,
75695 + 0xee0e612c,
75696 + 0x990951ba,
75697 + 0x076dc419,
75698 + 0x706af48f,
75699 + 0xe963a535,
75700 + 0x9e6495a3,
75701 + 0x0edb8832,
75702 + 0x79dcb8a4,
75703 + 0xe0d5e91e,
75704 + 0x97d2d988,
75705 + 0x09b64c2b,
75706 + 0x7eb17cbd,
75707 + 0xe7b82d07,
75708 + 0x90bf1d91,
75709 + 0x1db71064,
75710 + 0x6ab020f2,
75711 + 0xf3b97148,
75712 + 0x84be41de,
75713 + 0x1adad47d,
75714 + 0x6ddde4eb,
75715 + 0xf4d4b551,
75716 + 0x83d385c7,
75717 + 0x136c9856,
75718 + 0x646ba8c0,
75719 + 0xfd62f97a,
75720 + 0x8a65c9ec,
75721 + 0x14015c4f,
75722 + 0x63066cd9,
75723 + 0xfa0f3d63,
75724 + 0x8d080df5,
75725 + 0x3b6e20c8,
75726 + 0x4c69105e,
75727 + 0xd56041e4,
75728 + 0xa2677172,
75729 + 0x3c03e4d1,
75730 + 0x4b04d447,
75731 + 0xd20d85fd,
75732 + 0xa50ab56b,
75733 + 0x35b5a8fa,
75734 + 0x42b2986c,
75735 + 0xdbbbc9d6,
75736 + 0xacbcf940,
75737 + 0x32d86ce3,
75738 + 0x45df5c75,
75739 + 0xdcd60dcf,
75740 + 0xabd13d59,
75741 + 0x26d930ac,
75742 + 0x51de003a,
75743 + 0xc8d75180,
75744 + 0xbfd06116,
75745 + 0x21b4f4b5,
75746 + 0x56b3c423,
75747 + 0xcfba9599,
75748 + 0xb8bda50f,
75749 + 0x2802b89e,
75750 + 0x5f058808,
75751 + 0xc60cd9b2,
75752 + 0xb10be924,
75753 + 0x2f6f7c87,
75754 + 0x58684c11,
75755 + 0xc1611dab,
75756 + 0xb6662d3d,
75757 + 0x76dc4190,
75758 + 0x01db7106,
75759 + 0x98d220bc,
75760 + 0xefd5102a,
75761 + 0x71b18589,
75762 + 0x06b6b51f,
75763 + 0x9fbfe4a5,
75764 + 0xe8b8d433,
75765 + 0x7807c9a2,
75766 + 0x0f00f934,
75767 + 0x9609a88e,
75768 + 0xe10e9818,
75769 + 0x7f6a0dbb,
75770 + 0x086d3d2d,
75771 + 0x91646c97,
75772 + 0xe6635c01,
75773 + 0x6b6b51f4,
75774 + 0x1c6c6162,
75775 + 0x856530d8,
75776 + 0xf262004e,
75777 + 0x6c0695ed,
75778 + 0x1b01a57b,
75779 + 0x8208f4c1,
75780 + 0xf50fc457,
75781 + 0x65b0d9c6,
75782 + 0x12b7e950,
75783 + 0x8bbeb8ea,
75784 + 0xfcb9887c,
75785 + 0x62dd1ddf,
75786 + 0x15da2d49,
75787 + 0x8cd37cf3,
75788 + 0xfbd44c65,
75789 + 0x4db26158,
75790 + 0x3ab551ce,
75791 + 0xa3bc0074,
75792 + 0xd4bb30e2,
75793 + 0x4adfa541,
75794 + 0x3dd895d7,
75795 + 0xa4d1c46d,
75796 + 0xd3d6f4fb,
75797 + 0x4369e96a,
75798 + 0x346ed9fc,
75799 + 0xad678846,
75800 + 0xda60b8d0,
75801 + 0x44042d73,
75802 + 0x33031de5,
75803 + 0xaa0a4c5f,
75804 + 0xdd0d7cc9,
75805 + 0x5005713c,
75806 + 0x270241aa,
75807 + 0xbe0b1010,
75808 + 0xc90c2086,
75809 + 0x5768b525,
75810 + 0x206f85b3,
75811 + 0xb966d409,
75812 + 0xce61e49f,
75813 + 0x5edef90e,
75814 + 0x29d9c998,
75815 + 0xb0d09822,
75816 + 0xc7d7a8b4,
75817 + 0x59b33d17,
75818 + 0x2eb40d81,
75819 + 0xb7bd5c3b,
75820 + 0xc0ba6cad,
75821 + 0xedb88320,
75822 + 0x9abfb3b6,
75823 + 0x03b6e20c,
75824 + 0x74b1d29a,
75825 + 0xead54739,
75826 + 0x9dd277af,
75827 + 0x04db2615,
75828 + 0x73dc1683,
75829 + 0xe3630b12,
75830 + 0x94643b84,
75831 + 0x0d6d6a3e,
75832 + 0x7a6a5aa8,
75833 + 0xe40ecf0b,
75834 + 0x9309ff9d,
75835 + 0x0a00ae27,
75836 + 0x7d079eb1,
75837 + 0xf00f9344,
75838 + 0x8708a3d2,
75839 + 0x1e01f268,
75840 + 0x6906c2fe,
75841 + 0xf762575d,
75842 + 0x806567cb,
75843 + 0x196c3671,
75844 + 0x6e6b06e7,
75845 + 0xfed41b76,
75846 + 0x89d32be0,
75847 + 0x10da7a5a,
75848 + 0x67dd4acc,
75849 + 0xf9b9df6f,
75850 + 0x8ebeeff9,
75851 + 0x17b7be43,
75852 + 0x60b08ed5,
75853 + 0xd6d6a3e8,
75854 + 0xa1d1937e,
75855 + 0x38d8c2c4,
75856 + 0x4fdff252,
75857 + 0xd1bb67f1,
75858 + 0xa6bc5767,
75859 + 0x3fb506dd,
75860 + 0x48b2364b,
75861 + 0xd80d2bda,
75862 + 0xaf0a1b4c,
75863 + 0x36034af6,
75864 + 0x41047a60,
75865 + 0xdf60efc3,
75866 + 0xa867df55,
75867 + 0x316e8eef,
75868 + 0x4669be79,
75869 + 0xcb61b38c,
75870 + 0xbc66831a,
75871 + 0x256fd2a0,
75872 + 0x5268e236,
75873 + 0xcc0c7795,
75874 + 0xbb0b4703,
75875 + 0x220216b9,
75876 + 0x5505262f,
75877 + 0xc5ba3bbe,
75878 + 0xb2bd0b28,
75879 + 0x2bb45a92,
75880 + 0x5cb36a04,
75881 + 0xc2d7ffa7,
75882 + 0xb5d0cf31,
75883 + 0x2cd99e8b,
75884 + 0x5bdeae1d,
75885 + 0x9b64c2b0,
75886 + 0xec63f226,
75887 + 0x756aa39c,
75888 + 0x026d930a,
75889 + 0x9c0906a9,
75890 + 0xeb0e363f,
75891 + 0x72076785,
75892 + 0x05005713,
75893 + 0x95bf4a82,
75894 + 0xe2b87a14,
75895 + 0x7bb12bae,
75896 + 0x0cb61b38,
75897 + 0x92d28e9b,
75898 + 0xe5d5be0d,
75899 + 0x7cdcefb7,
75900 + 0x0bdbdf21,
75901 + 0x86d3d2d4,
75902 + 0xf1d4e242,
75903 + 0x68ddb3f8,
75904 + 0x1fda836e,
75905 + 0x81be16cd,
75906 + 0xf6b9265b,
75907 + 0x6fb077e1,
75908 + 0x18b74777,
75909 + 0x88085ae6,
75910 + 0xff0f6a70,
75911 + 0x66063bca,
75912 + 0x11010b5c,
75913 + 0x8f659eff,
75914 + 0xf862ae69,
75915 + 0x616bffd3,
75916 + 0x166ccf45,
75917 + 0xa00ae278,
75918 + 0xd70dd2ee,
75919 + 0x4e048354,
75920 + 0x3903b3c2,
75921 + 0xa7672661,
75922 + 0xd06016f7,
75923 + 0x4969474d,
75924 + 0x3e6e77db,
75925 + 0xaed16a4a,
75926 + 0xd9d65adc,
75927 + 0x40df0b66,
75928 + 0x37d83bf0,
75929 + 0xa9bcae53,
75930 + 0xdebb9ec5,
75931 + 0x47b2cf7f,
75932 + 0x30b5ffe9,
75933 + 0xbdbdf21c,
75934 + 0xcabac28a,
75935 + 0x53b39330,
75936 + 0x24b4a3a6,
75937 + 0xbad03605,
75938 + 0xcdd70693,
75939 + 0x54de5729,
75940 + 0x23d967bf,
75941 + 0xb3667a2e,
75942 + 0xc4614ab8,
75943 + 0x5d681b02,
75944 + 0x2a6f2b94,
75945 + 0xb40bbe37,
75946 + 0xc30c8ea1,
75947 + 0x5a05df1b,
75948 + 0x2d02ef8d
75949 +};
75950 +
75951 +
75952 +#define GET_MAC_ADDR_CRC(addr, crc) \
75953 +{ \
75954 + uint32_t i; \
75955 + uint8_t data; \
75956 + \
75957 + /* CRC calculation */ \
75958 + crc = 0xffffffff; \
75959 + for (i=0; i < 6; i++) \
75960 + { \
75961 + data = (uint8_t)(addr >> ((5-i)*8)); \
75962 + crc = crc^data; \
75963 + crc = crc_table[crc&0xff] ^ (crc>>8); \
75964 + } \
75965 +} \
75966 +
75967 +/* Define a macro for getting the mirrored value of */
75968 +/* a byte size number. (0x11010011 --> 0x11001011) */
75969 +/* Sometimes the mirrored value of the CRC is required */
75970 +static __inline__ uint8_t GetMirror(uint8_t n)
75971 +{
75972 + uint8_t mirror[16] =
75973 + {
75974 + 0x00,
75975 + 0x08,
75976 + 0x04,
75977 + 0x0c,
75978 + 0x02,
75979 + 0x0a,
75980 + 0x06,
75981 + 0x0e,
75982 + 0x01,
75983 + 0x09,
75984 + 0x05,
75985 + 0x0d,
75986 + 0x03,
75987 + 0x0b,
75988 + 0x07,
75989 + 0x0f
75990 + };
75991 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
75992 +}
75993 +
75994 +static __inline__ uint32_t GetMirror32(uint32_t n)
75995 +{
75996 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
75997 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
75998 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
75999 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
76000 +}
76001 +
76002 +#define MIRROR GetMirror
76003 +#define MIRROR_32 GetMirror32
76004 +
76005 +
76006 +#endif /* __crc_mac_addr_ext_h */
76007 --- /dev/null
76008 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76009 @@ -0,0 +1,210 @@
76010 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76011 + * All rights reserved.
76012 + *
76013 + * Redistribution and use in source and binary forms, with or without
76014 + * modification, are permitted provided that the following conditions are met:
76015 + * * Redistributions of source code must retain the above copyright
76016 + * notice, this list of conditions and the following disclaimer.
76017 + * * Redistributions in binary form must reproduce the above copyright
76018 + * notice, this list of conditions and the following disclaimer in the
76019 + * documentation and/or other materials provided with the distribution.
76020 + * * Neither the name of Freescale Semiconductor nor the
76021 + * names of its contributors may be used to endorse or promote products
76022 + * derived from this software without specific prior written permission.
76023 + *
76024 + *
76025 + * ALTERNATIVELY, this software may be distributed under the terms of the
76026 + * GNU General Public License ("GPL") as published by the Free Software
76027 + * Foundation, either version 2 of that License or (at your option) any
76028 + * later version.
76029 + *
76030 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76031 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76032 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76033 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76034 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76035 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76036 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76037 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76038 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76039 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76040 + */
76041 +
76042 +
76043 +/**************************************************************************//**
76044 + @File dpaa_ext.h
76045 +
76046 + @Description DPAA Application Programming Interface.
76047 +*//***************************************************************************/
76048 +#ifndef __DPAA_EXT_H
76049 +#define __DPAA_EXT_H
76050 +
76051 +#include "std_ext.h"
76052 +#include "error_ext.h"
76053 +
76054 +
76055 +/**************************************************************************//**
76056 + @Group DPAA_grp Data Path Acceleration Architecture API
76057 +
76058 + @Description DPAA API functions, definitions and enums.
76059 +
76060 + @{
76061 +*//***************************************************************************/
76062 +
76063 +#if defined(__MWERKS__) && !defined(__GNUC__)
76064 +#pragma pack(push,1)
76065 +#endif /* defined(__MWERKS__) && ... */
76066 +
76067 +/**************************************************************************//**
76068 + @Description Frame descriptor
76069 +*//***************************************************************************/
76070 +typedef _Packed struct t_DpaaFD {
76071 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
76072 + volatile uint8_t liodn;
76073 + volatile uint8_t bpid;
76074 + volatile uint8_t elion;
76075 + volatile uint8_t addrh;
76076 + volatile uint32_t addrl;
76077 +#else
76078 + volatile uint32_t addrl;
76079 + volatile uint8_t addrh;
76080 + volatile uint8_t elion;
76081 + volatile uint8_t bpid;
76082 + volatile uint8_t liodn;
76083 + #endif
76084 + volatile uint32_t length; /**< Frame length */
76085 + volatile uint32_t status; /**< FD status */
76086 +} _PackedType t_DpaaFD;
76087 +
76088 +/**************************************************************************//**
76089 + @Description enum for defining frame format
76090 +*//***************************************************************************/
76091 +typedef enum e_DpaaFDFormatType {
76092 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
76093 + small length (9b OFFSET, 20b LENGTH) */
76094 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
76095 + (29b LENGTH ,No OFFSET) */
76096 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
76097 + and small length (9b OFFSET, 20b LENGTH) */
76098 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
76099 + big length (29b LENGTH ,No OFFSET) */
76100 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
76101 + No LENGTH or OFFSET) */
76102 + e_DPAA_FD_FORMAT_TYPE_DUMMY
76103 +} e_DpaaFDFormatType;
76104 +
76105 +/**************************************************************************//**
76106 + @Collection Frame descriptor macros
76107 +*//***************************************************************************/
76108 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
76109 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
76110 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
76111 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
76112 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
76113 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
76114 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
76115 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
76116 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
76117 +
76118 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
76119 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
76120 +#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 */
76121 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
76122 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
76123 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
76124 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
76125 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
76126 +
76127 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
76128 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
76129 +#define DPAA_FD_SET_ADDR(fd,val) \
76130 +do { \
76131 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76132 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
76133 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
76134 +} while (0) /**< Macro to set FD ADDR field */
76135 +#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 */
76136 +#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 */
76137 +#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 */
76138 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
76139 +/* @} */
76140 +
76141 +/**************************************************************************//**
76142 + @Description Frame Scatter/Gather Table Entry
76143 +*//***************************************************************************/
76144 +typedef _Packed struct t_DpaaSGTE {
76145 + volatile uint32_t addrh; /**< Buffer Address high */
76146 + volatile uint32_t addrl; /**< Buffer Address low */
76147 + volatile uint32_t length; /**< Buffer length */
76148 + volatile uint32_t offset; /**< SGTE offset */
76149 +} _PackedType t_DpaaSGTE;
76150 +
76151 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
76152 +
76153 +/**************************************************************************//**
76154 + @Description Frame Scatter/Gather Table
76155 +*//***************************************************************************/
76156 +typedef _Packed struct t_DpaaSGT {
76157 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
76158 + /**< Structure that holds information about
76159 + a single S/G entry. */
76160 +} _PackedType t_DpaaSGT;
76161 +
76162 +/**************************************************************************//**
76163 + @Description Compound Frame Table
76164 +*//***************************************************************************/
76165 +typedef _Packed struct t_DpaaCompTbl {
76166 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
76167 + the compound-frame output buffer;
76168 + NOTE: this may point to a S/G table */
76169 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
76170 + the compound-frame input buffer;
76171 + NOTE: this may point to a S/G table */
76172 +} _PackedType t_DpaaCompTbl;
76173 +
76174 +/**************************************************************************//**
76175 + @Collection Frame Scatter/Gather Table Entry macros
76176 +*//***************************************************************************/
76177 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
76178 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
76179 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
76180 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
76181 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
76182 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
76183 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
76184 +
76185 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
76186 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
76187 +#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 */
76188 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
76189 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
76190 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
76191 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
76192 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
76193 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
76194 +
76195 +#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 */
76196 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
76197 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
76198 +do { \
76199 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76200 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
76201 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
76202 +} while (0) /**< Macro to set SGTE ADDR field */
76203 +#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 */
76204 +#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 */
76205 +#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 */
76206 +#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 */
76207 +#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 */
76208 +/* @} */
76209 +
76210 +#if defined(__MWERKS__) && !defined(__GNUC__)
76211 +#pragma pack(pop)
76212 +#endif /* defined(__MWERKS__) && ... */
76213 +
76214 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
76215 +
76216 +/** @} */ /* end of DPAA_grp group */
76217 +
76218 +
76219 +#endif /* __DPAA_EXT_H */
76220 --- /dev/null
76221 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76222 @@ -0,0 +1,1731 @@
76223 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76224 + * All rights reserved.
76225 + *
76226 + * Redistribution and use in source and binary forms, with or without
76227 + * modification, are permitted provided that the following conditions are met:
76228 + * * Redistributions of source code must retain the above copyright
76229 + * notice, this list of conditions and the following disclaimer.
76230 + * * Redistributions in binary form must reproduce the above copyright
76231 + * notice, this list of conditions and the following disclaimer in the
76232 + * documentation and/or other materials provided with the distribution.
76233 + * * Neither the name of Freescale Semiconductor nor the
76234 + * names of its contributors may be used to endorse or promote products
76235 + * derived from this software without specific prior written permission.
76236 + *
76237 + *
76238 + * ALTERNATIVELY, this software may be distributed under the terms of the
76239 + * GNU General Public License ("GPL") as published by the Free Software
76240 + * Foundation, either version 2 of that License or (at your option) any
76241 + * later version.
76242 + *
76243 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76244 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76245 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76246 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76247 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76248 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76249 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76250 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76251 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76252 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76253 + */
76254 +
76255 +
76256 +/**************************************************************************//**
76257 + @File fm_ext.h
76258 +
76259 + @Description FM Application Programming Interface.
76260 +*//***************************************************************************/
76261 +#ifndef __FM_EXT
76262 +#define __FM_EXT
76263 +
76264 +#include "error_ext.h"
76265 +#include "std_ext.h"
76266 +#include "dpaa_ext.h"
76267 +#include "fsl_fman_sp.h"
76268 +
76269 +/**************************************************************************//**
76270 + @Group FM_grp Frame Manager API
76271 +
76272 + @Description FM API functions, definitions and enums.
76273 +
76274 + @{
76275 +*//***************************************************************************/
76276 +
76277 +/**************************************************************************//**
76278 + @Group FM_lib_grp FM library
76279 +
76280 + @Description FM API functions, definitions and enums.
76281 +
76282 + The FM module is the main driver module and is a mandatory module
76283 + for FM driver users. This module must be initialized first prior
76284 + to any other drivers modules.
76285 + The FM is a "singleton" module. It is responsible of the common
76286 + HW modules: FPM, DMA, common QMI and common BMI initializations and
76287 + run-time control routines. This module must be initialized always
76288 + when working with any of the FM modules.
76289 + NOTE - We assume that the FM library will be initialized only by core No. 0!
76290 +
76291 + @{
76292 +*//***************************************************************************/
76293 +
76294 +/**************************************************************************//**
76295 + @Description Enum for defining port types
76296 +*//***************************************************************************/
76297 +typedef enum e_FmPortType {
76298 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
76299 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
76300 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
76301 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
76302 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
76303 + e_FM_PORT_TYPE_DUMMY
76304 +} e_FmPortType;
76305 +
76306 +/**************************************************************************//**
76307 + @Collection General FM defines
76308 +*//***************************************************************************/
76309 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
76310 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
76311 +/* @} */
76312 +
76313 +
76314 +#if defined(__MWERKS__) && !defined(__GNUC__)
76315 +#pragma pack(push,1)
76316 +#endif /* defined(__MWERKS__) && ... */
76317 +
76318 +/**************************************************************************//**
76319 + @Description FM physical Address
76320 +*//***************************************************************************/
76321 +typedef _Packed struct t_FmPhysAddr {
76322 + volatile uint8_t high; /**< High part of the physical address */
76323 + volatile uint32_t low; /**< Low part of the physical address */
76324 +} _PackedType t_FmPhysAddr;
76325 +
76326 +/**************************************************************************//**
76327 + @Description Parse results memory layout
76328 +*//***************************************************************************/
76329 +typedef _Packed struct t_FmPrsResult {
76330 + volatile uint8_t lpid; /**< Logical port id */
76331 + volatile uint8_t shimr; /**< Shim header result */
76332 + volatile uint16_t l2r; /**< Layer 2 result */
76333 + volatile uint16_t l3r; /**< Layer 3 result */
76334 + volatile uint8_t l4r; /**< Layer 4 result */
76335 + volatile uint8_t cplan; /**< Classification plan id */
76336 + volatile uint16_t nxthdr; /**< Next Header */
76337 + volatile uint16_t cksum; /**< Running-sum */
76338 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
76339 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
76340 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
76341 + volatile uint8_t shim_off[2]; /**< Shim offset */
76342 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
76343 + volatile uint8_t eth_off; /**< ETH offset */
76344 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
76345 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
76346 + volatile uint8_t etype_off; /**< ETYPE offset */
76347 + volatile uint8_t pppoe_off; /**< PPP offset */
76348 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
76349 + volatile uint8_t ip_off[2]; /**< IP offset */
76350 + volatile uint8_t gre_off; /**< GRE offset */
76351 + volatile uint8_t l4_off; /**< Layer 4 offset */
76352 + volatile uint8_t nxthdr_off; /**< Parser end point */
76353 +} _PackedType t_FmPrsResult;
76354 +
76355 +/**************************************************************************//**
76356 + @Collection FM Parser results
76357 +*//***************************************************************************/
76358 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
76359 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
76360 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
76361 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
76362 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
76363 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
76364 +/* @} */
76365 +
76366 +/**************************************************************************//**
76367 + @Collection FM Frame descriptor macros
76368 +*//***************************************************************************/
76369 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
76370 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
76371 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
76372 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
76373 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
76374 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
76375 +
76376 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
76377 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
76378 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
76379 +
76380 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
76381 +
76382 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
76383 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
76384 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
76385 +
76386 +#ifdef FM_CAPWAP_SUPPORT
76387 +#define FM_FD_ERR_CRE 0x00200000
76388 +#define FM_FD_ERR_CHE 0x00100000
76389 +#endif /* FM_CAPWAP_SUPPORT */
76390 +
76391 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
76392 + error (SGMII and TBI modes), FIFO parity error. PHY
76393 + Sequence error, PHY error control character detected. */
76394 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
76395 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
76396 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
76397 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
76398 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
76399 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
76400 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
76401 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
76402 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
76403 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
76404 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
76405 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
76406 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
76407 +
76408 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76409 + FM_FD_ERR_LENGTH | \
76410 + FM_FD_ERR_DMA) /**< TX Error FD bits */
76411 +
76412 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76413 + FM_FD_ERR_LENGTH | \
76414 + FM_FD_ERR_DMA | \
76415 + FM_FD_ERR_IPR | \
76416 + FM_FD_ERR_IPR_TO | \
76417 + FM_FD_ERR_IPR_NCSP | \
76418 + FM_FD_ERR_PHYSICAL | \
76419 + FM_FD_ERR_SIZE | \
76420 + FM_FD_ERR_CLS_DISCARD | \
76421 + FM_FD_ERR_COLOR_RED | \
76422 + FM_FD_ERR_COLOR_YELLOW | \
76423 + FM_FD_ERR_ILL_PLCR | \
76424 + FM_FD_ERR_PLCR_FRAME_LEN | \
76425 + FM_FD_ERR_EXTRACTION | \
76426 + FM_FD_ERR_NO_SCHEME | \
76427 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
76428 + FM_FD_ERR_PRS_TIMEOUT | \
76429 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
76430 + FM_FD_ERR_PRS_HDR_ERR | \
76431 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
76432 +
76433 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
76434 +/* @} */
76435 +
76436 +/**************************************************************************//**
76437 + @Description Context A
76438 +*//***************************************************************************/
76439 +typedef _Packed struct t_FmContextA {
76440 + volatile uint32_t command; /**< ContextA Command */
76441 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
76442 +} _PackedType t_FmContextA;
76443 +
76444 +/**************************************************************************//**
76445 + @Description Context B
76446 +*//***************************************************************************/
76447 +typedef uint32_t t_FmContextB;
76448 +
76449 +/**************************************************************************//**
76450 + @Collection Special Operation options
76451 +*//***************************************************************************/
76452 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
76453 +
76454 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
76455 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
76456 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
76457 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
76458 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
76459 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
76460 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
76461 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
76462 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
76463 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
76464 +/* @} */
76465 +
76466 +/**************************************************************************//**
76467 + @Collection Context A macros
76468 +*//***************************************************************************/
76469 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
76470 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
76471 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
76472 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
76473 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
76474 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
76475 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
76476 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
76477 +
76478 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
76479 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
76480 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
76481 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
76482 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
76483 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
76484 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
76485 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
76486 +
76487 +#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) ))
76488 +#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) ))
76489 +#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) ))
76490 +#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) ))
76491 +#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) ))
76492 +#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) ))
76493 +#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) ))
76494 +#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) ))
76495 +/* @} */
76496 +
76497 +/**************************************************************************//**
76498 + @Collection Context B macros
76499 +*//***************************************************************************/
76500 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
76501 +
76502 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
76503 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
76504 +/* @} */
76505 +
76506 +#if defined(__MWERKS__) && !defined(__GNUC__)
76507 +#pragma pack(pop)
76508 +#endif /* defined(__MWERKS__) && ... */
76509 +
76510 +
76511 +/**************************************************************************//**
76512 + @Description FM Exceptions
76513 +*//***************************************************************************/
76514 +typedef enum e_FmExceptions {
76515 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
76516 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
76517 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
76518 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
76519 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
76520 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
76521 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
76522 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
76523 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
76524 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
76525 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
76526 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
76527 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
76528 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
76529 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
76530 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
76531 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
76532 +} e_FmExceptions;
76533 +
76534 +/**************************************************************************//**
76535 + @Description Enum for defining port DMA swap mode
76536 +*//***************************************************************************/
76537 +typedef enum e_FmDmaSwapOption {
76538 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
76539 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
76540 + in PowerPc Little Endian mode. */
76541 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
76542 + in Big Endian mode */
76543 +} e_FmDmaSwapOption;
76544 +
76545 +/**************************************************************************//**
76546 + @Description Enum for defining port DMA cache attributes
76547 +*//***************************************************************************/
76548 +typedef enum e_FmDmaCacheOption {
76549 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
76550 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
76551 +} e_FmDmaCacheOption;
76552 +
76553 +
76554 +/**************************************************************************//**
76555 + @Group FM_init_grp FM Initialization Unit
76556 +
76557 + @Description FM Initialization Unit
76558 +
76559 + Initialization Flow
76560 + Initialization of the FM Module will be carried out by the application
76561 + according to the following sequence:
76562 + - Calling the configuration routine with basic parameters.
76563 + - Calling the advance initialization routines to change driver's defaults.
76564 + - Calling the initialization routine.
76565 +
76566 + @{
76567 +*//***************************************************************************/
76568 +
76569 +/**************************************************************************//**
76570 + @Function t_FmExceptionsCallback
76571 +
76572 + @Description Exceptions user callback routine, will be called upon an
76573 + exception passing the exception identification.
76574 +
76575 + @Param[in] h_App - User's application descriptor.
76576 + @Param[in] exception - The exception.
76577 +*//***************************************************************************/
76578 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
76579 + e_FmExceptions exception);
76580 +
76581 +
76582 +/**************************************************************************//**
76583 + @Function t_FmBusErrorCallback
76584 +
76585 + @Description Bus error user callback routine, will be called upon a
76586 + bus error, passing parameters describing the errors and the owner.
76587 +
76588 + @Param[in] h_App - User's application descriptor.
76589 + @Param[in] portType - Port type (e_FmPortType)
76590 + @Param[in] portId - Port id - relative to type.
76591 + @Param[in] addr - Address that caused the error
76592 + @Param[in] tnum - Owner of error
76593 + @Param[in] liodn - Logical IO device number
76594 +*//***************************************************************************/
76595 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
76596 + e_FmPortType portType,
76597 + uint8_t portId,
76598 + uint64_t addr,
76599 + uint8_t tnum,
76600 + uint16_t liodn);
76601 +
76602 +/**************************************************************************//**
76603 + @Description A structure for defining buffer prefix area content.
76604 +*//***************************************************************************/
76605 +typedef struct t_FmBufferPrefixContent {
76606 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
76607 + of the external buffer; Note that the private-area will
76608 + start from the base of the buffer address. */
76609 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
76610 + User may use FM_PORT_GetBufferPrsResult() in order to
76611 + get the parser-result from a buffer. */
76612 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
76613 + User may use FM_PORT_GetBufferTimeStamp() in order to
76614 + get the parser-result from a buffer. */
76615 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
76616 + User may use FM_PORT_GetBufferHashResult() in order to
76617 + get the parser-result from a buffer. */
76618 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
76619 + AD, hash-result, key, etc. */
76620 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
76621 + other value for selecting a data alignment (must be a power of 2);
76622 + if write optimization is used, must be >= 16. */
76623 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
76624 + Note that this field impacts the size of the buffer-prefix
76625 + (i.e. it pushes the data offset);
76626 + This field is irrelevant if DPAA_VERSION==10 */
76627 +} t_FmBufferPrefixContent;
76628 +
76629 +/**************************************************************************//**
76630 + @Description A structure of information about each of the external
76631 + buffer pools used by a port or storage-profile.
76632 +*//***************************************************************************/
76633 +typedef struct t_FmExtPoolParams {
76634 + uint8_t id; /**< External buffer pool id */
76635 + uint16_t size; /**< External buffer pool buffer size */
76636 +} t_FmExtPoolParams;
76637 +
76638 +/**************************************************************************//**
76639 + @Description A structure for informing the driver about the external
76640 + buffer pools allocated in the BM and used by a port or a
76641 + storage-profile.
76642 +*//***************************************************************************/
76643 +typedef struct t_FmExtPools {
76644 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
76645 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76646 + /**< Parameters for each port */
76647 +} t_FmExtPools;
76648 +
76649 +/**************************************************************************//**
76650 + @Description A structure for defining backup BM Pools.
76651 +*//***************************************************************************/
76652 +typedef struct t_FmBackupBmPools {
76653 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
76654 + must be smaller than the total number of
76655 + pools defined for the specified port.*/
76656 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
76657 + /**< numOfBackupPools pool id's, specifying which
76658 + pools should be used only as backup. Pool
76659 + id's specified here must be a subset of the
76660 + pools used by the specified port.*/
76661 +} t_FmBackupBmPools;
76662 +
76663 +/**************************************************************************//**
76664 + @Description A structure for defining BM pool depletion criteria
76665 +*//***************************************************************************/
76666 +typedef struct t_FmBufPoolDepletion {
76667 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
76668 + a number of pools (all together!) are depleted */
76669 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
76670 + pause frames transmission. */
76671 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
76672 + /**< For each pool, TRUE if it should be considered for
76673 + depletion (Note - this pool must be used by this port!). */
76674 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
76675 + a single-pool is depleted; */
76676 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
76677 + /**< For each pool, TRUE if it should be considered for
76678 + depletion (Note - this pool must be used by this port!) */
76679 +#if (DPAA_VERSION >= 11)
76680 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
76681 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
76682 +#endif /* (DPAA_VERSION >= 11) */
76683 +} t_FmBufPoolDepletion;
76684 +
76685 +/**************************************************************************//**
76686 + @Description A Structure for defining Ucode patch for loading.
76687 +*//***************************************************************************/
76688 +typedef struct t_FmFirmwareParams {
76689 + uint32_t size; /**< Size of uCode */
76690 + uint32_t *p_Code; /**< A pointer to the uCode */
76691 +} t_FmFirmwareParams;
76692 +
76693 +/**************************************************************************//**
76694 + @Description A Structure for defining FM initialization parameters
76695 +*//***************************************************************************/
76696 +typedef struct t_FmParams {
76697 + uint8_t fmId; /**< Index of the FM */
76698 + uint8_t guestId; /**< FM Partition Id */
76699 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
76700 + this field is optional when the FM runs in "guest-mode"
76701 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
76702 + use the memory-map instead of calling the IPC where possible;
76703 + NOTE that this should include ALL common registers of the FM including
76704 + the PCD registers area (i.e. until the VSP pages - 880KB). */
76705 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
76706 + to be used by the FM. */
76707 + uint16_t fmClkFreq; /**< In Mhz;
76708 + Relevant when FM not runs in "guest-mode". */
76709 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
76710 + when fmMacClkRatio = 0, ratio is 2:1
76711 + when fmMacClkRatio = 1, ratio is 1:1 */
76712 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
76713 + Relevant when FM not runs in "guest-mode". */
76714 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
76715 + Relevant when FM not runs in "guest-mode". */
76716 + t_Handle h_App; /**< A handle to an application layer object; This handle will
76717 + be passed by the driver upon calling the above callbacks;
76718 + Relevant when FM not runs in "guest-mode". */
76719 + int irq; /**< FM interrupt source for normal events;
76720 + Relevant when FM not runs in "guest-mode". */
76721 + int errIrq; /**< FM interrupt source for errors;
76722 + Relevant when FM not runs in "guest-mode". */
76723 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
76724 + Relevant when FM not runs in "guest-mode". */
76725 +
76726 +#if (DPAA_VERSION >= 11)
76727 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
76728 + i.e. up to 24KB, depending on the specific chip. */
76729 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
76730 + NOTE: this parameter relevant only when working with multiple partitions. */
76731 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
76732 + NOTE: this parameter relevant only when working with multiple partitions. */
76733 +#endif /* (DPAA_VERSION >= 11) */
76734 +} t_FmParams;
76735 +
76736 +
76737 +/**************************************************************************//**
76738 + @Function FM_Config
76739 +
76740 + @Description Creates the FM module and returns its handle (descriptor).
76741 + This descriptor must be passed as first parameter to all other
76742 + FM function calls.
76743 +
76744 + No actual initialization or configuration of FM hardware is
76745 + done by this routine. All FM parameters get default values that
76746 + may be changed by calling one or more of the advance config routines.
76747 +
76748 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
76749 +
76750 + @Return A handle to the FM object, or NULL for Failure.
76751 +*//***************************************************************************/
76752 +t_Handle FM_Config(t_FmParams *p_FmParams);
76753 +
76754 +/**************************************************************************//**
76755 + @Function FM_Init
76756 +
76757 + @Description Initializes the FM module by defining the software structure
76758 + and configuring the hardware registers.
76759 +
76760 + @Param[in] h_Fm - FM module descriptor
76761 +
76762 + @Return E_OK on success; Error code otherwise.
76763 +*//***************************************************************************/
76764 +t_Error FM_Init(t_Handle h_Fm);
76765 +
76766 +/**************************************************************************//**
76767 + @Function FM_Free
76768 +
76769 + @Description Frees all resources that were assigned to FM module.
76770 +
76771 + Calling this routine invalidates the descriptor.
76772 +
76773 + @Param[in] h_Fm - FM module descriptor
76774 +
76775 + @Return E_OK on success; Error code otherwise.
76776 +*//***************************************************************************/
76777 +t_Error FM_Free(t_Handle h_Fm);
76778 +
76779 +
76780 +/**************************************************************************//**
76781 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
76782 +
76783 + @Description Advanced configuration routines are optional routines that may
76784 + be called in order to change the default driver settings.
76785 +
76786 + Note: Advanced configuration routines are not available for guest partition.
76787 + @{
76788 +*//***************************************************************************/
76789 +
76790 +/**************************************************************************//**
76791 + @Description Enum for selecting DMA debug mode
76792 +*//***************************************************************************/
76793 +typedef enum e_FmDmaDbgCntMode {
76794 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
76795 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
76796 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
76797 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
76798 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
76799 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
76800 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
76801 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
76802 +} e_FmDmaDbgCntMode;
76803 +
76804 +/**************************************************************************//**
76805 + @Description Enum for selecting DMA Cache Override
76806 +*//***************************************************************************/
76807 +typedef enum e_FmDmaCacheOverride {
76808 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
76809 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
76810 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
76811 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
76812 +} e_FmDmaCacheOverride;
76813 +
76814 +/**************************************************************************//**
76815 + @Description Enum for selecting DMA External Bus Priority
76816 +*//***************************************************************************/
76817 +typedef enum e_FmDmaExtBusPri {
76818 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
76819 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
76820 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
76821 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
76822 +} e_FmDmaExtBusPri;
76823 +
76824 +/**************************************************************************//**
76825 + @Description Enum for choosing the field that will be output on AID
76826 +*//***************************************************************************/
76827 +typedef enum e_FmDmaAidMode {
76828 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
76829 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
76830 +} e_FmDmaAidMode;
76831 +
76832 +/**************************************************************************//**
76833 + @Description Enum for selecting FPM Catastrophic error behavior
76834 +*//***************************************************************************/
76835 +typedef enum e_FmCatastrophicErr {
76836 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
76837 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
76838 +} e_FmCatastrophicErr;
76839 +
76840 +/**************************************************************************//**
76841 + @Description Enum for selecting FPM DMA Error behavior
76842 +*//***************************************************************************/
76843 +typedef enum e_FmDmaErr {
76844 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
76845 + error (e_FmCatastrophicErr)*/
76846 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
76847 +} e_FmDmaErr;
76848 +
76849 +/**************************************************************************//**
76850 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
76851 +*//***************************************************************************/
76852 +typedef enum e_FmDmaEmergencyLevel {
76853 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
76854 + e_FM_DMA_EM_SOS /**< SOS emergency */
76855 +} e_FmDmaEmergencyLevel;
76856 +
76857 +/**************************************************************************//**
76858 + @Collection Enum for selecting DMA Emergency options
76859 +*//***************************************************************************/
76860 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
76861 +
76862 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
76863 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
76864 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
76865 +/* @} */
76866 +
76867 +/**************************************************************************//**
76868 + @Description A structure for defining DMA emergency level
76869 +*//***************************************************************************/
76870 +typedef struct t_FmDmaEmergency {
76871 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
76872 + should be enabled */
76873 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
76874 +} t_FmDmaEmergency;
76875 +
76876 +/**************************************************************************//*
76877 + @Description structure for defining FM threshold
76878 +*//***************************************************************************/
76879 +typedef struct t_FmThresholds {
76880 + uint8_t dispLimit; /**< The number of times a frames may
76881 + be passed in the FM before assumed to
76882 + be looping. */
76883 + uint8_t prsDispTh; /**< This is the number pf packets that may be
76884 + queued in the parser dispatch queue*/
76885 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
76886 + queued in the policer dispatch queue*/
76887 + uint8_t kgDispTh; /**< This is the number pf packets that may be
76888 + queued in the keygen dispatch queue*/
76889 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
76890 + queued in the BMI dispatch queue*/
76891 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
76892 + queued in the QMI enqueue dispatch queue*/
76893 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
76894 + queued in the QMI dequeue dispatch queue*/
76895 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
76896 + queued in fmCtl1 dispatch queue*/
76897 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
76898 + queued in fmCtl2 dispatch queue*/
76899 +} t_FmThresholds;
76900 +
76901 +/**************************************************************************//*
76902 + @Description structure for defining DMA thresholds
76903 +*//***************************************************************************/
76904 +typedef struct t_FmDmaThresholds {
76905 + uint8_t assertEmergency; /**< When this value is reached,
76906 + assert emergency (Threshold)*/
76907 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
76908 + until this value is reached (Hystheresis) */
76909 +} t_FmDmaThresholds;
76910 +
76911 +/**************************************************************************//**
76912 + @Function t_FmResetOnInitOverrideCallback
76913 +
76914 + @Description FMan specific reset on init user callback routine,
76915 + will be used to override the standard FMan reset on init procedure
76916 +
76917 + @Param[in] h_Fm - FMan handler
76918 +*//***************************************************************************/
76919 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
76920 +
76921 +/**************************************************************************//**
76922 + @Function FM_ConfigResetOnInit
76923 +
76924 + @Description Define whether to reset the FM before initialization.
76925 + Change the default configuration [DEFAULT_resetOnInit].
76926 +
76927 + @Param[in] h_Fm A handle to an FM Module.
76928 + @Param[in] enable When TRUE, FM will be reset before any initialization.
76929 +
76930 + @Return E_OK on success; Error code otherwise.
76931 +
76932 + @Cautions Allowed only following FM_Config() and before FM_Init().
76933 + This routine should NOT be called from guest-partition
76934 + (i.e. guestId != NCSW_MASTER_ID)
76935 +*//***************************************************************************/
76936 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
76937 +
76938 +/**************************************************************************//**
76939 + @Function FM_ConfigResetOnInitOverrideCallback
76940 +
76941 + @Description Define a special reset of FM before initialization.
76942 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
76943 +
76944 + @Param[in] h_Fm A handle to an FM Module.
76945 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
76946 +
76947 + @Return E_OK on success; Error code otherwise.
76948 +
76949 + @Cautions Allowed only following FM_Config() and before FM_Init().
76950 + This routine should NOT be called from guest-partition
76951 + (i.e. guestId != NCSW_MASTER_ID)
76952 +*//***************************************************************************/
76953 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
76954 +
76955 +/**************************************************************************//**
76956 + @Function FM_ConfigTotalFifoSize
76957 +
76958 + @Description Define Total FIFO size for the whole FM.
76959 + Calling this routine changes the total Fifo size in the internal driver
76960 + data base from its default configuration [DEFAULT_totalFifoSize]
76961 +
76962 + @Param[in] h_Fm A handle to an FM Module.
76963 + @Param[in] totalFifoSize The selected new value.
76964 +
76965 + @Return E_OK on success; Error code otherwise.
76966 +
76967 + @Cautions Allowed only following FM_Config() and before FM_Init().
76968 + This routine should NOT be called from guest-partition
76969 + (i.e. guestId != NCSW_MASTER_ID)
76970 +*//***************************************************************************/
76971 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
76972 +
76973 + /**************************************************************************//**
76974 + @Function FM_ConfigDmaCacheOverride
76975 +
76976 + @Description Define cache override mode.
76977 + Calling this routine changes the cache override mode
76978 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
76979 +
76980 + @Param[in] h_Fm A handle to an FM Module.
76981 + @Param[in] cacheOverride The selected new value.
76982 +
76983 + @Return E_OK on success; Error code otherwise.
76984 +
76985 + @Cautions Allowed only following FM_Config() and before FM_Init().
76986 + This routine should NOT be called from guest-partition
76987 + (i.e. guestId != NCSW_MASTER_ID)
76988 +*//***************************************************************************/
76989 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
76990 +
76991 +/**************************************************************************//**
76992 + @Function FM_ConfigDmaAidOverride
76993 +
76994 + @Description Define DMA AID override mode.
76995 + Calling this routine changes the AID override mode
76996 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
76997 +
76998 + @Param[in] h_Fm A handle to an FM Module.
76999 + @Param[in] aidOverride The selected new value.
77000 +
77001 + @Return E_OK on success; Error code otherwise.
77002 +
77003 + @Cautions Allowed only following FM_Config() and before FM_Init().
77004 + This routine should NOT be called from guest-partition
77005 + (i.e. guestId != NCSW_MASTER_ID)
77006 +*//***************************************************************************/
77007 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
77008 +
77009 +/**************************************************************************//**
77010 + @Function FM_ConfigDmaAidMode
77011 +
77012 + @Description Define DMA AID mode.
77013 + Calling this routine changes the AID mode in the internal
77014 + driver data base from its default configuration [DEFAULT_aidMode]
77015 +
77016 + @Param[in] h_Fm A handle to an FM Module.
77017 + @Param[in] aidMode The selected new value.
77018 +
77019 + @Return E_OK on success; Error code otherwise.
77020 +
77021 + @Cautions Allowed only following FM_Config() and before FM_Init().
77022 + This routine should NOT be called from guest-partition
77023 + (i.e. guestId != NCSW_MASTER_ID)
77024 +*//***************************************************************************/
77025 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
77026 +
77027 +/**************************************************************************//**
77028 + @Function FM_ConfigDmaAxiDbgNumOfBeats
77029 +
77030 + @Description Define DMA AXI number of beats.
77031 + Calling this routine changes the AXI number of beats in the internal
77032 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
77033 +
77034 + @Param[in] h_Fm A handle to an FM Module.
77035 + @Param[in] axiDbgNumOfBeats The selected new value.
77036 +
77037 + @Return E_OK on success; Error code otherwise.
77038 +
77039 + @Cautions Allowed only following FM_Config() and before FM_Init().
77040 + This routine should NOT be called from guest-partition
77041 + (i.e. guestId != NCSW_MASTER_ID)
77042 +*//***************************************************************************/
77043 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
77044 +
77045 +/**************************************************************************//**
77046 + @Function FM_ConfigDmaCamNumOfEntries
77047 +
77048 + @Description Define number of CAM entries.
77049 + Calling this routine changes the number of CAM entries in the internal
77050 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
77051 +
77052 + @Param[in] h_Fm A handle to an FM Module.
77053 + @Param[in] numOfEntries The selected new value.
77054 +
77055 + @Return E_OK on success; Error code otherwise.
77056 +
77057 + @Cautions Allowed only following FM_Config() and before FM_Init().
77058 + This routine should NOT be called from guest-partition
77059 + (i.e. guestId != NCSW_MASTER_ID)
77060 +*//***************************************************************************/
77061 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
77062 +
77063 +/**************************************************************************//**
77064 + @Function FM_ConfigEnableCounters
77065 +
77066 + @Description Obsolete, always return E_OK.
77067 +
77068 + @Param[in] h_Fm A handle to an FM Module.
77069 +
77070 + @Return E_OK on success; Error code otherwise.
77071 +*//***************************************************************************/
77072 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
77073 +
77074 +/**************************************************************************//**
77075 + @Function FM_ConfigDmaDbgCounter
77076 +
77077 + @Description Define DMA debug counter.
77078 + Calling this routine changes the number of the DMA debug counter in the internal
77079 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
77080 +
77081 + @Param[in] h_Fm A handle to an FM Module.
77082 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
77083 +
77084 + @Return E_OK on success; Error code otherwise.
77085 +
77086 + @Cautions Allowed only following FM_Config() and before FM_Init().
77087 + This routine should NOT be called from guest-partition
77088 + (i.e. guestId != NCSW_MASTER_ID)
77089 +*//***************************************************************************/
77090 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
77091 +
77092 +/**************************************************************************//**
77093 + @Function FM_ConfigDmaStopOnBusErr
77094 +
77095 + @Description Define bus error behavior.
77096 + Calling this routine changes the bus error behavior definition
77097 + in the internal driver data base from its default
77098 + configuration [DEFAULT_dmaStopOnBusError].
77099 +
77100 + @Param[in] h_Fm A handle to an FM Module.
77101 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
77102 +
77103 + @Return E_OK on success; Error code otherwise.
77104 +
77105 + @Cautions Allowed only following FM_Config() and before FM_Init().
77106 + Only if bus error is enabled.
77107 + This routine should NOT be called from guest-partition
77108 + (i.e. guestId != NCSW_MASTER_ID)
77109 +*//***************************************************************************/
77110 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
77111 +
77112 +/**************************************************************************//**
77113 + @Function FM_ConfigDmaEmergency
77114 +
77115 + @Description Define DMA emergency.
77116 + Calling this routine changes the DMA emergency definition
77117 + in the internal driver data base from its default
77118 + configuration where's it's disabled.
77119 +
77120 + @Param[in] h_Fm A handle to an FM Module.
77121 + @Param[in] p_Emergency An OR mask of all required options.
77122 +
77123 + @Return E_OK on success; Error code otherwise.
77124 +
77125 + @Cautions Allowed only following FM_Config() and before FM_Init().
77126 + This routine should NOT be called from guest-partition
77127 + (i.e. guestId != NCSW_MASTER_ID)
77128 +*//***************************************************************************/
77129 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
77130 +
77131 +/**************************************************************************//**
77132 + @Function FM_ConfigDmaErr
77133 +
77134 + @Description DMA error treatment.
77135 + Calling this routine changes the DMA error treatment
77136 + in the internal driver data base from its default
77137 + configuration [DEFAULT_dmaErr].
77138 +
77139 + @Param[in] h_Fm A handle to an FM Module.
77140 + @Param[in] dmaErr The selected new choice.
77141 +
77142 + @Return E_OK on success; Error code otherwise.
77143 +
77144 + @Cautions Allowed only following FM_Config() and before FM_Init().
77145 + This routine should NOT be called from guest-partition
77146 + (i.e. guestId != NCSW_MASTER_ID)
77147 +*//***************************************************************************/
77148 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
77149 +
77150 +/**************************************************************************//**
77151 + @Function FM_ConfigCatastrophicErr
77152 +
77153 + @Description Define FM behavior on catastrophic error.
77154 + Calling this routine changes the FM behavior on catastrophic
77155 + error in the internal driver data base from its default
77156 + [DEFAULT_catastrophicErr].
77157 +
77158 + @Param[in] h_Fm A handle to an FM Module.
77159 + @Param[in] catastrophicErr The selected new choice.
77160 +
77161 + @Return E_OK on success; Error code otherwise.
77162 +
77163 + @Cautions Allowed only following FM_Config() and before FM_Init().
77164 + This routine should NOT be called from guest-partition
77165 + (i.e. guestId != NCSW_MASTER_ID)
77166 +*//***************************************************************************/
77167 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
77168 +
77169 +/**************************************************************************//**
77170 + @Function FM_ConfigEnableMuramTestMode
77171 +
77172 + @Description Enable MURAM test mode.
77173 + Calling this routine changes the internal driver data base
77174 + from its default selection of test mode where it's disabled.
77175 + This routine is only avaiable on old FM revisions (FMan v2).
77176 +
77177 + @Param[in] h_Fm A handle to an FM Module.
77178 +
77179 + @Return E_OK on success; Error code otherwise.
77180 +
77181 + @Cautions Allowed only following FM_Config() and before FM_Init().
77182 + This routine should NOT be called from guest-partition
77183 + (i.e. guestId != NCSW_MASTER_ID)
77184 +*//***************************************************************************/
77185 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
77186 +
77187 +/**************************************************************************//**
77188 + @Function FM_ConfigEnableIramTestMode
77189 +
77190 + @Description Enable IRAM test mode.
77191 + Calling this routine changes the internal driver data base
77192 + from its default selection of test mode where it's disabled.
77193 + This routine is only avaiable on old FM revisions (FMan v2).
77194 +
77195 + @Param[in] h_Fm A handle to an FM Module.
77196 +
77197 + @Return E_OK on success; Error code otherwise.
77198 +
77199 + @Cautions Allowed only following FM_Config() and before FM_Init().
77200 + This routine should NOT be called from guest-partition
77201 + (i.e. guestId != NCSW_MASTER_ID)
77202 +*//***************************************************************************/
77203 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
77204 +
77205 +/**************************************************************************//**
77206 + @Function FM_ConfigHaltOnExternalActivation
77207 +
77208 + @Description Define FM behavior on external halt activation.
77209 + Calling this routine changes the FM behavior on external halt
77210 + activation in the internal driver data base from its default
77211 + [DEFAULT_haltOnExternalActivation].
77212 +
77213 + @Param[in] h_Fm A handle to an FM Module.
77214 + @Param[in] enable TRUE to enable halt on external halt
77215 + activation.
77216 +
77217 + @Return E_OK on success; Error code otherwise.
77218 +
77219 + @Cautions Allowed only following FM_Config() and before FM_Init().
77220 + This routine should NOT be called from guest-partition
77221 + (i.e. guestId != NCSW_MASTER_ID)
77222 +*//***************************************************************************/
77223 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
77224 +
77225 +/**************************************************************************//**
77226 + @Function FM_ConfigHaltOnUnrecoverableEccError
77227 +
77228 + @Description Define FM behavior on external halt activation.
77229 + Calling this routine changes the FM behavior on unrecoverable
77230 + ECC error in the internal driver data base from its default
77231 + [DEFAULT_haltOnUnrecoverableEccError].
77232 + This routine is only avaiable on old FM revisions (FMan v2).
77233 +
77234 + @Param[in] h_Fm A handle to an FM Module.
77235 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
77236 +
77237 + @Return E_OK on success; Error code otherwise.
77238 +
77239 + @Cautions Allowed only following FM_Config() and before FM_Init().
77240 + This routine should NOT be called from guest-partition
77241 + (i.e. guestId != NCSW_MASTER_ID)
77242 +*//***************************************************************************/
77243 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
77244 +
77245 +/**************************************************************************//**
77246 + @Function FM_ConfigException
77247 +
77248 + @Description Define FM exceptions.
77249 + Calling this routine changes the exceptions defaults in the
77250 + internal driver data base where all exceptions are enabled.
77251 +
77252 + @Param[in] h_Fm A handle to an FM Module.
77253 + @Param[in] exception The exception to be selected.
77254 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77255 +
77256 + @Return E_OK on success; Error code otherwise.
77257 +
77258 + @Cautions Allowed only following FM_Config() and before FM_Init().
77259 + This routine should NOT be called from guest-partition
77260 + (i.e. guestId != NCSW_MASTER_ID)
77261 +*//***************************************************************************/
77262 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77263 +
77264 +/**************************************************************************//**
77265 + @Function FM_ConfigExternalEccRamsEnable
77266 +
77267 + @Description Select external ECC enabling.
77268 + Calling this routine changes the ECC enabling control in the internal
77269 + driver data base from its default [DEFAULT_externalEccRamsEnable].
77270 + When this option is enabled Rams ECC enabling is not effected
77271 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
77272 +
77273 + @Param[in] h_Fm A handle to an FM Module.
77274 + @Param[in] enable TRUE to enable this option.
77275 +
77276 + @Return E_OK on success; Error code otherwise.
77277 +
77278 + @Cautions Allowed only following FM_Config() and before FM_Init().
77279 + This routine should NOT be called from guest-partition
77280 + (i.e. guestId != NCSW_MASTER_ID)
77281 +*//***************************************************************************/
77282 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
77283 +
77284 +/**************************************************************************//**
77285 + @Function FM_ConfigTnumAgingPeriod
77286 +
77287 + @Description Define Tnum aging period.
77288 + Calling this routine changes the Tnum aging of dequeue TNUMs
77289 + in the QMI in the internal driver data base from its default
77290 + [DEFAULT_tnumAgingPeriod].
77291 +
77292 + @Param[in] h_Fm A handle to an FM Module.
77293 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
77294 + Note that period is recalculated in units of
77295 + 64 FM clocks. Driver will pick the closest
77296 + possible period.
77297 +
77298 + @Return E_OK on success; Error code otherwise.
77299 +
77300 + @Cautions Allowed only following FM_Config() and before FM_Init().
77301 + This routine should NOT be called from guest-partition
77302 + (i.e. guestId != NCSW_MASTER_ID)
77303 + NOTE that if some MAC is configured for PFC, '0' value is NOT
77304 + allowed.
77305 +*//***************************************************************************/
77306 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
77307 +
77308 +/**************************************************************************//*
77309 + @Function FM_ConfigDmaEmergencySmoother
77310 +
77311 + @Description Define DMA emergency smoother.
77312 + Calling this routine changes the definition of the minimum
77313 + amount of DATA beats transferred on the AXI READ and WRITE
77314 + ports before lowering the emergency level.
77315 + By default smoother is disabled.
77316 +
77317 + @Param[in] h_Fm A handle to an FM Module.
77318 + @Param[in] emergencyCnt emergency switching counter.
77319 +
77320 + @Return E_OK on success; Error code otherwise.
77321 +
77322 + @Cautions Allowed only following FM_Config() and before FM_Init().
77323 + This routine should NOT be called from guest-partition
77324 + (i.e. guestId != NCSW_MASTER_ID)
77325 +*//***************************************************************************/
77326 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
77327 +
77328 +/**************************************************************************//*
77329 + @Function FM_ConfigThresholds
77330 +
77331 + @Description Calling this routine changes the internal driver data base
77332 + from its default FM threshold configuration:
77333 + dispLimit: [DEFAULT_dispLimit]
77334 + prsDispTh: [DEFAULT_prsDispTh]
77335 + plcrDispTh: [DEFAULT_plcrDispTh]
77336 + kgDispTh: [DEFAULT_kgDispTh]
77337 + bmiDispTh: [DEFAULT_bmiDispTh]
77338 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
77339 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
77340 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
77341 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
77342 +
77343 +
77344 + @Param[in] h_Fm A handle to an FM Module.
77345 + @Param[in] p_FmThresholds A structure of threshold parameters.
77346 +
77347 + @Return E_OK on success; Error code otherwise.
77348 +
77349 + @Cautions Allowed only following FM_Config() and before FM_Init().
77350 + This routine should NOT be called from guest-partition
77351 + (i.e. guestId != NCSW_MASTER_ID)
77352 +*//***************************************************************************/
77353 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
77354 +
77355 +/**************************************************************************//*
77356 + @Function FM_ConfigDmaSosEmergencyThreshold
77357 +
77358 + @Description Calling this routine changes the internal driver data base
77359 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
77360 +
77361 + @Param[in] h_Fm A handle to an FM Module.
77362 + @Param[in] dmaSosEmergency The selected new value.
77363 +
77364 + @Return E_OK on success; Error code otherwise.
77365 +
77366 + @Cautions Allowed only following FM_Config() and before FM_Init().
77367 + This routine should NOT be called from guest-partition
77368 + (i.e. guestId != NCSW_MASTER_ID)
77369 +*//***************************************************************************/
77370 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
77371 +
77372 +/**************************************************************************//*
77373 + @Function FM_ConfigDmaWriteBufThresholds
77374 +
77375 + @Description Calling this routine changes the internal driver data base
77376 + from its default configuration of DMA write buffer threshold
77377 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
77378 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
77379 + This routine is only avaiable on old FM revisions (FMan v2).
77380 +
77381 + @Param[in] h_Fm A handle to an FM Module.
77382 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77383 + When 'assertEmergency' value is reached, emergency is asserted,
77384 + then it is held until 'clearEmergency' value is reached.
77385 +
77386 + @Return E_OK on success; Error code otherwise.
77387 +
77388 + @Cautions Allowed only following FM_Config() and before FM_Init().
77389 + This routine should NOT be called from guest-partition
77390 + (i.e. guestId != NCSW_MASTER_ID)
77391 +*//***************************************************************************/
77392 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77393 +
77394 + /**************************************************************************//*
77395 + @Function FM_ConfigDmaCommQThresholds
77396 +
77397 + @Description Calling this routine changes the internal driver data base
77398 + from its default configuration of DMA command queue threshold
77399 + assertEmergency: [DEFAULT_dmaCommQLow]
77400 + clearEmergency: [DEFAULT_dmaCommQHigh]
77401 +
77402 + @Param[in] h_Fm A handle to an FM Module.
77403 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77404 + When 'assertEmergency' value is reached, emergency is asserted,
77405 + then it is held until 'clearEmergency' value is reached..
77406 +
77407 + @Return E_OK on success; Error code otherwise.
77408 +
77409 + @Cautions Allowed only following FM_Config() and before FM_Init().
77410 + This routine should NOT be called from guest-partition
77411 + (i.e. guestId != NCSW_MASTER_ID)
77412 +*//***************************************************************************/
77413 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77414 +
77415 +/**************************************************************************//*
77416 + @Function FM_ConfigDmaReadBufThresholds
77417 +
77418 + @Description Calling this routine changes the internal driver data base
77419 + from its default configuration of DMA read buffer threshold
77420 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
77421 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
77422 + This routine is only avaiable on old FM revisions (FMan v2).
77423 +
77424 + @Param[in] h_Fm A handle to an FM Module.
77425 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77426 + When 'assertEmergency' value is reached, emergency is asserted,
77427 + then it is held until 'clearEmergency' value is reached..
77428 +
77429 + @Return E_OK on success; Error code otherwise.
77430 +
77431 + @Cautions Allowed only following FM_Config() and before FM_Init().
77432 + This routine should NOT be called from guest-partition
77433 + (i.e. guestId != NCSW_MASTER_ID)
77434 +*//***************************************************************************/
77435 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77436 +
77437 +/**************************************************************************//*
77438 + @Function FM_ConfigDmaWatchdog
77439 +
77440 + @Description Calling this routine changes the internal driver data base
77441 + from its default watchdog configuration, which is disabled
77442 + [DEFAULT_dmaWatchdog].
77443 +
77444 + @Param[in] h_Fm A handle to an FM Module.
77445 + @Param[in] watchDogValue The selected new value - in microseconds.
77446 +
77447 + @Return E_OK on success; Error code otherwise.
77448 +
77449 + @Cautions Allowed only following FM_Config() and before FM_Init().
77450 + This routine should NOT be called from guest-partition
77451 + (i.e. guestId != NCSW_MASTER_ID)
77452 +*//***************************************************************************/
77453 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
77454 +
77455 +/** @} */ /* end of FM_advanced_init_grp group */
77456 +/** @} */ /* end of FM_init_grp group */
77457 +
77458 +
77459 +/**************************************************************************//**
77460 + @Group FM_runtime_control_grp FM Runtime Control Unit
77461 +
77462 + @Description FM Runtime control unit API functions, definitions and enums.
77463 + The FM driver provides a set of control routines.
77464 + These routines may only be called after the module was fully
77465 + initialized (both configuration and initialization routines were
77466 + called). They are typically used to get information from hardware
77467 + (status, counters/statistics, revision etc.), to modify a current
77468 + state or to force/enable a required action. Run-time control may
77469 + be called whenever necessary and as many times as needed.
77470 + @{
77471 +*//***************************************************************************/
77472 +
77473 +/**************************************************************************//**
77474 + @Collection General FM defines.
77475 +*//***************************************************************************/
77476 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
77477 + FM_MAX_NUM_OF_1G_RX_PORTS + \
77478 + FM_MAX_NUM_OF_10G_RX_PORTS + \
77479 + FM_MAX_NUM_OF_1G_TX_PORTS + \
77480 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
77481 +/* @} */
77482 +
77483 +/**************************************************************************//*
77484 + @Description A Structure for Port bandwidth requirement. Port is identified
77485 + by type and relative id.
77486 +*//***************************************************************************/
77487 +typedef struct t_FmPortBandwidth {
77488 + e_FmPortType type; /**< FM port type */
77489 + uint8_t relativePortId; /**< Type relative port id */
77490 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
77491 +} t_FmPortBandwidth;
77492 +
77493 +/**************************************************************************//*
77494 + @Description A Structure containing an array of Port bandwidth requirements.
77495 + The user should state the ports requiring bandwidth in terms of
77496 + percentage - i.e. all port's bandwidths in the array must add
77497 + up to 100.
77498 +*//***************************************************************************/
77499 +typedef struct t_FmPortsBandwidthParams {
77500 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
77501 + number of valid entries in the array below */
77502 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
77503 + /**< for each port, it's bandwidth (all port's
77504 + bandwidths must add up to 100.*/
77505 +} t_FmPortsBandwidthParams;
77506 +
77507 +/**************************************************************************//**
77508 + @Description DMA Emergency control on MURAM
77509 +*//***************************************************************************/
77510 +typedef enum e_FmDmaMuramPort {
77511 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
77512 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
77513 +} e_FmDmaMuramPort;
77514 +
77515 +/**************************************************************************//**
77516 + @Description Enum for defining FM counters
77517 +*//***************************************************************************/
77518 +typedef enum e_FmCounters {
77519 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
77520 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
77521 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
77522 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
77523 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
77524 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
77525 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
77526 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
77527 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
77528 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
77529 +} e_FmCounters;
77530 +
77531 +/**************************************************************************//**
77532 + @Description A Structure for returning FM revision information
77533 +*//***************************************************************************/
77534 +typedef struct t_FmRevisionInfo {
77535 + uint8_t majorRev; /**< Major revision */
77536 + uint8_t minorRev; /**< Minor revision */
77537 +} t_FmRevisionInfo;
77538 +
77539 +/**************************************************************************//**
77540 + @Description A Structure for returning FM ctrl code revision information
77541 +*//***************************************************************************/
77542 +typedef struct t_FmCtrlCodeRevisionInfo {
77543 + uint16_t packageRev; /**< Package revision */
77544 + uint8_t majorRev; /**< Major revision */
77545 + uint8_t minorRev; /**< Minor revision */
77546 +} t_FmCtrlCodeRevisionInfo;
77547 +
77548 +/**************************************************************************//**
77549 + @Description A Structure for defining DMA status
77550 +*//***************************************************************************/
77551 +typedef struct t_FmDmaStatus {
77552 + bool cmqNotEmpty; /**< Command queue is not empty */
77553 + bool busError; /**< Bus error occurred */
77554 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
77555 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
77556 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
77557 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
77558 +} t_FmDmaStatus;
77559 +
77560 +/**************************************************************************//**
77561 + @Description A Structure for obtaining FM controller monitor values
77562 +*//***************************************************************************/
77563 +typedef struct t_FmCtrlMon {
77564 + uint8_t percentCnt[2]; /**< Percentage value */
77565 +} t_FmCtrlMon;
77566 +
77567 +
77568 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
77569 +/**************************************************************************//**
77570 + @Function FM_DumpRegs
77571 +
77572 + @Description Dumps all FM registers
77573 +
77574 + @Param[in] h_Fm A handle to an FM Module.
77575 +
77576 + @Return E_OK on success;
77577 +
77578 + @Cautions Allowed only following FM_Init().
77579 +*//***************************************************************************/
77580 +t_Error FM_DumpRegs(t_Handle h_Fm);
77581 +#endif /* (defined(DEBUG_ERRORS) && ... */
77582 +
77583 +/**************************************************************************//**
77584 + @Function FM_SetException
77585 +
77586 + @Description Calling this routine enables/disables the specified exception.
77587 +
77588 + @Param[in] h_Fm A handle to an FM Module.
77589 + @Param[in] exception The exception to be selected.
77590 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77591 +
77592 + @Return E_OK on success; Error code otherwise.
77593 +
77594 + @Cautions Allowed only following FM_Init().
77595 + This routine should NOT be called from guest-partition
77596 + (i.e. guestId != NCSW_MASTER_ID)
77597 +*//***************************************************************************/
77598 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77599 +
77600 +/**************************************************************************//**
77601 + @Function FM_EnableRamsEcc
77602 +
77603 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77604 + MURAM, Parser, Keygen, Policer, etc.
77605 + Note:
77606 + If FM_ConfigExternalEccRamsEnable was called to enable external
77607 + setting of ECC, this routine effects IRAM ECC only.
77608 + This routine is also called by the driver if an ECC exception is
77609 + enabled.
77610 +
77611 + @Param[in] h_Fm A handle to an FM Module.
77612 +
77613 + @Return E_OK on success; Error code otherwise.
77614 +
77615 + @Cautions Allowed only following FM_Config() and before FM_Init().
77616 + This routine should NOT be called from guest-partition
77617 + (i.e. guestId != NCSW_MASTER_ID)
77618 +*//***************************************************************************/
77619 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
77620 +
77621 +/**************************************************************************//**
77622 + @Function FM_DisableRamsEcc
77623 +
77624 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77625 + MURAM, Parser, Keygen, Policer, etc.
77626 + Note:
77627 + If FM_ConfigExternalEccRamsEnable was called to enable external
77628 + setting of ECC, this routine effects IRAM ECC only.
77629 + In opposed to FM_EnableRamsEcc, this routine must be called
77630 + explicitly to disable all Rams ECC.
77631 +
77632 + @Param[in] h_Fm A handle to an FM Module.
77633 +
77634 + @Return E_OK on success; Error code otherwise.
77635 +
77636 + @Cautions Allowed only following FM_Config() and before FM_Init().
77637 + This routine should NOT be called from guest-partition
77638 + (i.e. guestId != NCSW_MASTER_ID)
77639 +*//***************************************************************************/
77640 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
77641 +
77642 +/**************************************************************************//**
77643 + @Function FM_GetRevision
77644 +
77645 + @Description Returns the FM revision
77646 +
77647 + @Param[in] h_Fm A handle to an FM Module.
77648 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
77649 +
77650 + @Return E_OK on success; Error code otherwise.
77651 +
77652 + @Cautions Allowed only following FM_Init().
77653 +*//***************************************************************************/
77654 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
77655 +
77656 +/**************************************************************************//**
77657 + @Function FM_GetFmanCtrlCodeRevision
77658 +
77659 + @Description Returns the Fman controller code revision
77660 +
77661 + @Param[in] h_Fm A handle to an FM Module.
77662 + @Param[out] p_RevisionInfo A structure of revision information parameters.
77663 +
77664 + @Return E_OK on success; Error code otherwise.
77665 +
77666 + @Cautions Allowed only following FM_Init().
77667 +*//***************************************************************************/
77668 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
77669 +
77670 +/**************************************************************************//**
77671 + @Function FM_GetCounter
77672 +
77673 + @Description Reads one of the FM counters.
77674 +
77675 + @Param[in] h_Fm A handle to an FM Module.
77676 + @Param[in] counter The requested counter.
77677 +
77678 + @Return Counter's current value.
77679 +
77680 + @Cautions Allowed only following FM_Init().
77681 + Note that it is user's responsibility to call this routine only
77682 + for enabled counters, and there will be no indication if a
77683 + disabled counter is accessed.
77684 +*//***************************************************************************/
77685 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
77686 +
77687 +/**************************************************************************//**
77688 + @Function FM_ModifyCounter
77689 +
77690 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
77691 +
77692 + @Param[in] h_Fm A handle to an FM Module.
77693 + @Param[in] counter The requested counter.
77694 + @Param[in] val The requested value to be written into the counter.
77695 +
77696 + @Return E_OK on success; Error code otherwise.
77697 +
77698 + @Cautions Allowed only following FM_Init().
77699 + This routine should NOT be called from guest-partition
77700 + (i.e. guestId != NCSW_MASTER_ID)
77701 +*//***************************************************************************/
77702 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
77703 +
77704 +/**************************************************************************//**
77705 + @Function FM_Resume
77706 +
77707 + @Description Release FM after halt FM command or after unrecoverable ECC error.
77708 +
77709 + @Param[in] h_Fm A handle to an FM Module.
77710 +
77711 + @Return E_OK on success; Error code otherwise.
77712 +
77713 + @Cautions Allowed only following FM_Init().
77714 + This routine should NOT be called from guest-partition
77715 + (i.e. guestId != NCSW_MASTER_ID)
77716 +*//***************************************************************************/
77717 +void FM_Resume(t_Handle h_Fm);
77718 +
77719 +/**************************************************************************//**
77720 + @Function FM_SetDmaEmergency
77721 +
77722 + @Description Manual emergency set
77723 +
77724 + @Param[in] h_Fm A handle to an FM Module.
77725 + @Param[in] muramPort MURAM direction select.
77726 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
77727 +
77728 + @Return None.
77729 +
77730 + @Cautions Allowed only following FM_Init().
77731 + This routine should NOT be called from guest-partition
77732 + (i.e. guestId != NCSW_MASTER_ID)
77733 +*//***************************************************************************/
77734 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
77735 +
77736 +/**************************************************************************//**
77737 + @Function FM_SetDmaExtBusPri
77738 +
77739 + @Description Set the DMA external bus priority
77740 +
77741 + @Param[in] h_Fm A handle to an FM Module.
77742 + @Param[in] pri External bus priority select
77743 +
77744 + @Return None.
77745 +
77746 + @Cautions Allowed only following FM_Init().
77747 + This routine should NOT be called from guest-partition
77748 + (i.e. guestId != NCSW_MASTER_ID)
77749 +*//***************************************************************************/
77750 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
77751 +
77752 +/**************************************************************************//**
77753 + @Function FM_GetDmaStatus
77754 +
77755 + @Description Reads the DMA current status
77756 +
77757 + @Param[in] h_Fm A handle to an FM Module.
77758 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
77759 +
77760 + @Cautions Allowed only following FM_Init().
77761 +*//***************************************************************************/
77762 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
77763 +
77764 +/**************************************************************************//**
77765 + @Function FM_ErrorIsr
77766 +
77767 + @Description FM interrupt-service-routine for errors.
77768 +
77769 + @Param[in] h_Fm A handle to an FM Module.
77770 +
77771 + @Return E_OK on success; E_EMPTY if no errors found in register, other
77772 + error code otherwise.
77773 +
77774 + @Cautions Allowed only following FM_Init().
77775 + This routine should NOT be called from guest-partition
77776 + (i.e. guestId != NCSW_MASTER_ID)
77777 +*//***************************************************************************/
77778 +t_Error FM_ErrorIsr(t_Handle h_Fm);
77779 +
77780 +/**************************************************************************//**
77781 + @Function FM_EventIsr
77782 +
77783 + @Description FM interrupt-service-routine for normal events.
77784 +
77785 + @Param[in] h_Fm A handle to an FM Module.
77786 +
77787 + @Cautions Allowed only following FM_Init().
77788 + This routine should NOT be called from guest-partition
77789 + (i.e. guestId != NCSW_MASTER_ID)
77790 +*//***************************************************************************/
77791 +void FM_EventIsr(t_Handle h_Fm);
77792 +
77793 +/**************************************************************************//**
77794 + @Function FM_GetSpecialOperationCoding
77795 +
77796 + @Description Return a specific coding according to the input mask.
77797 +
77798 + @Param[in] h_Fm A handle to an FM Module.
77799 + @Param[in] spOper special operation mask.
77800 + @Param[out] p_SpOperCoding special operation code.
77801 +
77802 + @Return E_OK on success; Error code otherwise.
77803 +
77804 + @Cautions Allowed only following FM_Init().
77805 +*//***************************************************************************/
77806 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
77807 + fmSpecialOperations_t spOper,
77808 + uint8_t *p_SpOperCoding);
77809 +
77810 +/**************************************************************************//**
77811 + @Function FM_CtrlMonStart
77812 +
77813 + @Description Start monitoring utilization of all available FM controllers.
77814 +
77815 + In order to obtain FM controllers utilization the following sequence
77816 + should be used:
77817 + -# FM_CtrlMonStart()
77818 + -# FM_CtrlMonStop()
77819 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77820 +
77821 + @Param[in] h_Fm A handle to an FM Module.
77822 +
77823 + @Return E_OK on success; Error code otherwise.
77824 +
77825 + @Cautions Allowed only following FM_Init().
77826 + This routine should NOT be called from guest-partition
77827 + (i.e. guestId != NCSW_MASTER_ID).
77828 +*//***************************************************************************/
77829 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
77830 +
77831 +/**************************************************************************//**
77832 + @Function FM_CtrlMonStop
77833 +
77834 + @Description Stop monitoring utilization of all available FM controllers.
77835 +
77836 + In order to obtain FM controllers utilization the following sequence
77837 + should be used:
77838 + -# FM_CtrlMonStart()
77839 + -# FM_CtrlMonStop()
77840 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77841 +
77842 + @Param[in] h_Fm A handle to an FM Module.
77843 +
77844 + @Return E_OK on success; Error code otherwise.
77845 +
77846 + @Cautions Allowed only following FM_Init().
77847 + This routine should NOT be called from guest-partition
77848 + (i.e. guestId != NCSW_MASTER_ID).
77849 +*//***************************************************************************/
77850 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
77851 +
77852 +/**************************************************************************//**
77853 + @Function FM_CtrlMonGetCounters
77854 +
77855 + @Description Obtain FM controller utilization parameters.
77856 +
77857 + In order to obtain FM controllers utilization the following sequence
77858 + should be used:
77859 + -# FM_CtrlMonStart()
77860 + -# FM_CtrlMonStop()
77861 + -# FM_CtrlMonGetCounters() - issued for each FM controller
77862 +
77863 + @Param[in] h_Fm A handle to an FM Module.
77864 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
77865 + are requested.
77866 + @Param[in] p_Mon Pointer to utilization results structure.
77867 +
77868 + @Return E_OK on success; Error code otherwise.
77869 +
77870 + @Cautions Allowed only following FM_Init().
77871 + This routine should NOT be called from guest-partition
77872 + (i.e. guestId != NCSW_MASTER_ID).
77873 +*//***************************************************************************/
77874 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
77875 +
77876 +
77877 +/**************************************************************************//*
77878 + @Function FM_ForceIntr
77879 +
77880 + @Description Causes an interrupt event on the requested source.
77881 +
77882 + @Param[in] h_Fm A handle to an FM Module.
77883 + @Param[in] exception An exception to be forced.
77884 +
77885 + @Return E_OK on success; Error code if the exception is not enabled,
77886 + or is not able to create interrupt.
77887 +
77888 + @Cautions Allowed only following FM_Init().
77889 + This routine should NOT be called from guest-partition
77890 + (i.e. guestId != NCSW_MASTER_ID)
77891 +*//***************************************************************************/
77892 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
77893 +
77894 +/**************************************************************************//*
77895 + @Function FM_SetPortsBandwidth
77896 +
77897 + @Description Sets relative weights between ports when accessing common resources.
77898 +
77899 + @Param[in] h_Fm A handle to an FM Module.
77900 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
77901 + total must equal 100.
77902 +
77903 + @Return E_OK on success; Error code otherwise.
77904 +
77905 + @Cautions Allowed only following FM_Init().
77906 + This routine should NOT be called from guest-partition
77907 + (i.e. guestId != NCSW_MASTER_ID)
77908 +*//***************************************************************************/
77909 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
77910 +
77911 +/**************************************************************************//*
77912 + @Function FM_GetMuramHandle
77913 +
77914 + @Description Gets the corresponding MURAM handle
77915 +
77916 + @Param[in] h_Fm A handle to an FM Module.
77917 +
77918 + @Return MURAM handle; NULL otherwise.
77919 +
77920 + @Cautions Allowed only following FM_Init().
77921 + This routine should NOT be called from guest-partition
77922 + (i.e. guestId != NCSW_MASTER_ID)
77923 +*//***************************************************************************/
77924 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
77925 +
77926 +/** @} */ /* end of FM_runtime_control_grp group */
77927 +/** @} */ /* end of FM_lib_grp group */
77928 +/** @} */ /* end of FM_grp group */
77929 +
77930 +
77931 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
77932 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
77933 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
77934 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
77935 +typedef t_FmExtPools t_FmPortExtPools;
77936 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
77937 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
77938 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
77939 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
77940 +
77941 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
77942 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
77943 +
77944 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
77945 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
77946 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
77947 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
77948 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
77949 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
77950 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
77951 +
77952 +
77953 +#endif /* __FM_EXT */
77954 --- /dev/null
77955 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
77956 @@ -0,0 +1,859 @@
77957 +/*
77958 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77959 + *
77960 + * Redistribution and use in source and binary forms, with or without
77961 + * modification, are permitted provided that the following conditions are met:
77962 + * * Redistributions of source code must retain the above copyright
77963 + * notice, this list of conditions and the following disclaimer.
77964 + * * Redistributions in binary form must reproduce the above copyright
77965 + * notice, this list of conditions and the following disclaimer in the
77966 + * documentation and/or other materials provided with the distribution.
77967 + * * Neither the name of Freescale Semiconductor nor the
77968 + * names of its contributors may be used to endorse or promote products
77969 + * derived from this software without specific prior written permission.
77970 + *
77971 + *
77972 + * ALTERNATIVELY, this software may be distributed under the terms of the
77973 + * GNU General Public License ("GPL") as published by the Free Software
77974 + * Foundation, either version 2 of that License or (at your option) any
77975 + * later version.
77976 + *
77977 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77978 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77979 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77980 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77981 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77982 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77983 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77984 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77985 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77986 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77987 + */
77988 +
77989 +
77990 +/**************************************************************************//**
77991 + @File fm_mac_ext.h
77992 +
77993 + @Description FM MAC ...
77994 +*//***************************************************************************/
77995 +#ifndef __FM_MAC_EXT_H
77996 +#define __FM_MAC_EXT_H
77997 +
77998 +#include "std_ext.h"
77999 +#include "enet_ext.h"
78000 +
78001 +
78002 +/**************************************************************************//**
78003 +
78004 + @Group FM_grp Frame Manager API
78005 +
78006 + @Description FM API functions, definitions and enums
78007 +
78008 + @{
78009 +*//***************************************************************************/
78010 +
78011 +/**************************************************************************//**
78012 + @Group FM_mac_grp FM MAC
78013 +
78014 + @Description FM MAC API functions, definitions and enums
78015 +
78016 + @{
78017 +*//***************************************************************************/
78018 +
78019 +#define FM_MAC_NO_PFC 0xff
78020 +
78021 +
78022 +/**************************************************************************//**
78023 + @Description FM MAC Exceptions
78024 +*//***************************************************************************/
78025 +typedef enum e_FmMacExceptions {
78026 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
78027 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
78028 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
78029 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
78030 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
78031 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
78032 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
78033 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
78034 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
78035 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
78036 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
78037 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
78038 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
78039 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
78040 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
78041 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
78042 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
78043 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
78044 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
78045 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
78046 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
78047 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
78048 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
78049 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
78050 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
78051 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
78052 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
78053 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
78054 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
78055 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
78056 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
78057 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
78058 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
78059 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
78060 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
78061 + not supported on T4240/B4860 rev1 chips */
78062 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
78063 + /**< mEMAC Magic Packet Indication Interrupt */
78064 +} e_FmMacExceptions;
78065 +
78066 +/**************************************************************************//**
78067 + @Description TM MAC statistics level
78068 +*//***************************************************************************/
78069 +typedef enum e_FmMacStatisticsLevel {
78070 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
78071 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
78072 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
78073 +} e_FmMacStatisticsLevel;
78074 +
78075 +
78076 +#if (DPAA_VERSION >= 11)
78077 +/**************************************************************************//**
78078 + @Description Priority Flow Control Parameters
78079 +*//***************************************************************************/
78080 +typedef struct t_FmMacPfcParams {
78081 + bool pfcEnable; /**< Enable/Disable PFC */
78082 +
78083 + 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*/
78084 +
78085 + 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*/
78086 +
78087 +
78088 +} t_FmMacPfcParams;
78089 +#endif /* (DPAA_VERSION >= 11) */
78090 +
78091 +/**************************************************************************//**
78092 + @Function t_FmMacExceptionCallback
78093 +
78094 + @Description Fm Mac Exception Callback from FM MAC to the user
78095 +
78096 + @Param[in] h_App - Handle to the upper layer handler
78097 +
78098 + @Param[in] exceptions - The exception that occurred
78099 +
78100 + @Return void.
78101 +*//***************************************************************************/
78102 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
78103 +
78104 +
78105 +/**************************************************************************//**
78106 + @Description TM MAC statistics rfc3635
78107 +*//***************************************************************************/
78108 +typedef struct t_FmMacStatistics {
78109 +/* RMON */
78110 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
78111 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
78112 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
78113 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
78114 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
78115 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
78116 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
78117 +/* */
78118 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
78119 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
78120 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
78121 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
78122 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
78123 + This count does not include range length errors */
78124 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
78125 + a valid FCS and otherwise well formed */
78126 +/* Pause */
78127 + uint64_t teStatPause; /**< Pause MAC Control received */
78128 + uint64_t reStatPause; /**< Pause MAC Control sent */
78129 +/* MIB II */
78130 + uint64_t ifInOctets; /**< Total number of byte received. */
78131 + uint64_t ifInPkts; /**< Total number of packets received.*/
78132 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
78133 + NOTE: this counter is not supported on dTSEC MAC */
78134 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
78135 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
78136 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
78137 + uint64_t ifInErrors; /**< Number of frames received with error:
78138 + - FIFO Overflow Error
78139 + - CRC Error
78140 + - Frame Too Long Error
78141 + - Alignment Error
78142 + - The dedicated Error Code (0xfe, not a code error) was received */
78143 + uint64_t ifOutOctets; /**< Total number of byte sent. */
78144 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
78145 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
78146 + NOTE: this counter is not supported on dTSEC MAC */
78147 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
78148 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
78149 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
78150 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
78151 + - FIFO Overflow Error
78152 + - FIFO Underflow Error
78153 + - Other */
78154 +} t_FmMacStatistics;
78155 +
78156 +
78157 +/**************************************************************************//**
78158 + @Group FM_mac_init_grp FM MAC Initialization Unit
78159 +
78160 + @Description FM MAC Initialization Unit
78161 +
78162 + @{
78163 +*//***************************************************************************/
78164 +
78165 +/**************************************************************************//**
78166 + @Description FM MAC config input
78167 +*//***************************************************************************/
78168 +typedef struct t_FmMacParams {
78169 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
78170 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
78171 + uint8_t macId; /**< MAC ID;
78172 + numbering of dTSEC and 1G-mEMAC:
78173 + 0 - FM_MAX_NUM_OF_1G_MACS;
78174 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
78175 + 0 - FM_MAX_NUM_OF_10G_MACS */
78176 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
78177 + Note that the speed should indicate the maximum rate that
78178 + this MAC should support rather than the actual speed;
78179 + i.e. user should use the FM_MAC_AdjustLink() routine to
78180 + provide accurate speed;
78181 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
78182 + automatic mode, where actual speed/duplex mode information
78183 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
78184 + function should be used to switch to manual RGMII speed/duplex mode
78185 + configuration if RGMII PHY doesn't support in-band status signaling;
78186 + In addition, in mEMAC, in case where user is using the higher MACs
78187 + (i.e. the MACs that should support 10G), user should pass here
78188 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
78189 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
78190 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
78191 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
78192 + mdio-irq, or for polling */
78193 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
78194 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
78195 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78196 + be passed by the driver upon calling the above callbacks */
78197 +} t_FmMacParams;
78198 +
78199 +
78200 +/**************************************************************************//**
78201 + @Function FM_MAC_Config
78202 +
78203 + @Description Creates descriptor for the FM MAC module.
78204 +
78205 + The routine returns a handle (descriptor) to the FM MAC object.
78206 + This descriptor must be passed as first parameter to all other
78207 + FM MAC function calls.
78208 +
78209 + No actual initialization or configuration of FM MAC hardware is
78210 + done by this routine.
78211 +
78212 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
78213 +
78214 + @Retval Handle to FM MAC object, or NULL for Failure.
78215 +*//***************************************************************************/
78216 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
78217 +
78218 +/**************************************************************************//**
78219 + @Function FM_MAC_Init
78220 +
78221 + @Description Initializes the FM MAC module
78222 +
78223 + @Param[in] h_FmMac - FM module descriptor
78224 +
78225 + @Return E_OK on success; Error code otherwise.
78226 +*//***************************************************************************/
78227 +t_Error FM_MAC_Init(t_Handle h_FmMac);
78228 +
78229 +/**************************************************************************//**
78230 + @Function FM_Free
78231 +
78232 + @Description Frees all resources that were assigned to FM MAC module.
78233 +
78234 + Calling this routine invalidates the descriptor.
78235 +
78236 + @Param[in] h_FmMac - FM module descriptor
78237 +
78238 + @Return E_OK on success; Error code otherwise.
78239 +*//***************************************************************************/
78240 +t_Error FM_MAC_Free(t_Handle h_FmMac);
78241 +
78242 +
78243 +/**************************************************************************//**
78244 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
78245 +
78246 + @Description Configuration functions used to change default values.
78247 +
78248 + @{
78249 +*//***************************************************************************/
78250 +
78251 +/**************************************************************************//**
78252 + @Function FM_MAC_ConfigResetOnInit
78253 +
78254 + @Description Tell the driver whether to reset the FM MAC before initialization or
78255 + not. It changes the default configuration [DEFAULT_resetOnInit].
78256 +
78257 + @Param[in] h_FmMac A handle to a FM MAC Module.
78258 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78259 +
78260 + @Return E_OK on success; Error code otherwise.
78261 +
78262 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78263 +*//***************************************************************************/
78264 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
78265 +
78266 +/**************************************************************************//**
78267 + @Function FM_MAC_ConfigLoopback
78268 +
78269 + @Description Enable/Disable internal loopback mode
78270 +
78271 + @Param[in] h_FmMac A handle to a FM MAC Module.
78272 + @Param[in] enable TRUE to enable or FALSE to disable.
78273 +
78274 + @Return E_OK on success; Error code otherwise.
78275 +
78276 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78277 +*//***************************************************************************/
78278 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
78279 +
78280 +/**************************************************************************//**
78281 + @Function FM_MAC_ConfigMaxFrameLength
78282 +
78283 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
78284 +
78285 + @Param[in] h_FmMac A handle to a FM MAC Module.
78286 + @Param[in] newVal MAX Frame length
78287 +
78288 + @Return E_OK on success; Error code otherwise.
78289 +
78290 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78291 +*//***************************************************************************/
78292 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
78293 +
78294 +/**************************************************************************//**
78295 + @Function FM_MAC_ConfigWan
78296 +
78297 + @Description ENABLE WAN mode in 10G-MAC
78298 +
78299 + @Param[in] h_FmMac A handle to a FM MAC Module.
78300 + @Param[in] enable TRUE to enable or FALSE to disable.
78301 +
78302 + @Return E_OK on success; Error code otherwise.
78303 +
78304 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78305 +*//***************************************************************************/
78306 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
78307 +
78308 +/**************************************************************************//**
78309 + @Function FM_MAC_ConfigPadAndCrc
78310 +
78311 + @Description Config PAD and CRC mode
78312 +
78313 + @Param[in] h_FmMac A handle to a FM MAC Module.
78314 + @Param[in] enable TRUE to enable or FALSE to disable.
78315 +
78316 + @Return E_OK on success; Error code otherwise.
78317 +
78318 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78319 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
78320 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
78321 + added automatically by HW).
78322 +*//***************************************************************************/
78323 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
78324 +
78325 +/**************************************************************************//**
78326 + @Function FM_MAC_ConfigHalfDuplex
78327 +
78328 + @Description Config Half Duplex Mode
78329 +
78330 + @Param[in] h_FmMac A handle to a FM MAC Module.
78331 + @Param[in] enable TRUE to enable or FALSE to disable.
78332 +
78333 + @Return E_OK on success; Error code otherwise.
78334 +
78335 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78336 +*//***************************************************************************/
78337 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
78338 +
78339 +/**************************************************************************//**
78340 + @Function FM_MAC_ConfigTbiPhyAddr
78341 +
78342 + @Description Configures the address of internal TBI PHY.
78343 +
78344 + @Param[in] h_FmMac A handle to a FM MAC Module.
78345 + @Param[in] newVal TBI PHY address (1-31).
78346 +
78347 + @Return E_OK on success; Error code otherwise.
78348 +
78349 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78350 +*//***************************************************************************/
78351 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
78352 +
78353 +/**************************************************************************//**
78354 + @Function FM_MAC_ConfigLengthCheck
78355 +
78356 + @Description Configure the frame length checking.
78357 +
78358 + @Param[in] h_FmMac A handle to a FM MAC Module.
78359 + @Param[in] enable TRUE to enable or FALSE to disable.
78360 +
78361 + @Return E_OK on success; Error code otherwise.
78362 +
78363 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78364 +*//***************************************************************************/
78365 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
78366 +
78367 +/**************************************************************************//**
78368 + @Function FM_MAC_ConfigException
78369 +
78370 + @Description Change Exception selection from default
78371 +
78372 + @Param[in] h_FmMac A handle to a FM MAC Module.
78373 + @Param[in] ex Type of the desired exceptions
78374 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
78375 +
78376 + @Return E_OK on success; Error code otherwise.
78377 +
78378 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78379 +*//***************************************************************************/
78380 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78381 +
78382 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
78383 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
78384 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
78385 +/** @} */ /* end of FM_mac_advanced_init_grp group */
78386 +/** @} */ /* end of FM_mac_init_grp group */
78387 +
78388 +
78389 +/**************************************************************************//**
78390 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
78391 +
78392 + @Description FM MAC Runtime control unit API functions, definitions and enums.
78393 +
78394 + @{
78395 +*//***************************************************************************/
78396 +
78397 +/**************************************************************************//**
78398 + @Function FM_MAC_Enable
78399 +
78400 + @Description Enable the MAC
78401 +
78402 + @Param[in] h_FmMac A handle to a FM MAC Module.
78403 + @Param[in] mode Mode of operation (RX, TX, Both)
78404 +
78405 + @Return E_OK on success; Error code otherwise.
78406 +
78407 + @Cautions Allowed only following FM_MAC_Init().
78408 +*//***************************************************************************/
78409 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
78410 +
78411 +/**************************************************************************//**
78412 + @Function FM_MAC_Disable
78413 +
78414 + @Description DISABLE the MAC
78415 +
78416 + @Param[in] h_FmMac A handle to a FM MAC Module.
78417 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
78418 +
78419 + @Return E_OK on success; Error code otherwise.
78420 +
78421 + @Cautions Allowed only following FM_MAC_Init().
78422 +*//***************************************************************************/
78423 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
78424 +
78425 +/**************************************************************************//**
78426 + @Function FM_MAC_Resume
78427 +
78428 + @Description Re-init the MAC after suspend
78429 +
78430 + @Param[in] h_FmMac A handle to a FM MAC Module.
78431 +
78432 + @Return E_OK on success; Error code otherwise.
78433 +
78434 + @Cautions Allowed only following FM_MAC_Init().
78435 +*//***************************************************************************/
78436 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
78437 +
78438 +/**************************************************************************//**
78439 + @Function FM_MAC_Enable1588TimeStamp
78440 +
78441 + @Description Enables the TSU operation.
78442 +
78443 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78444 +
78445 + @Return E_OK on success; Error code otherwise.
78446 +
78447 + @Cautions Allowed only following FM_MAC_Init().
78448 +*//***************************************************************************/
78449 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
78450 +
78451 +/**************************************************************************//**
78452 + @Function FM_MAC_Disable1588TimeStamp
78453 +
78454 + @Description Disables the TSU operation.
78455 +
78456 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78457 +
78458 + @Return E_OK on success; Error code otherwise.
78459 +
78460 + @Cautions Allowed only following FM_MAC_Init().
78461 +*//***************************************************************************/
78462 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
78463 +
78464 +/**************************************************************************//**
78465 + @Function FM_MAC_SetTxAutoPauseFrames
78466 +
78467 + @Description Enable/Disable transmission of Pause-Frames.
78468 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
78469 +
78470 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78471 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78472 + Each quanta represents a 512 bit-times; Note that '0'
78473 + as an input here will be used as disabling the
78474 + transmission of the pause-frames.
78475 +
78476 + @Return E_OK on success; Error code otherwise.
78477 +
78478 + @Cautions Allowed only following FM_MAC_Init().
78479 +*//***************************************************************************/
78480 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
78481 + uint16_t pauseTime);
78482 +
78483 + /**************************************************************************//**
78484 + @Function FM_MAC_SetTxPauseFrames
78485 +
78486 + @Description Enable/Disable transmission of Pause-Frames.
78487 + The routine changes the default configuration:
78488 + pause-time - [DEFAULT_TX_PAUSE_TIME]
78489 + threshold-time - [0]
78490 +
78491 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78492 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
78493 + to indicate legacy pause support (i.e. no PFC).
78494 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78495 + Each quanta represents a 512 bit-times;
78496 + Note that '0' as an input here will be used as disabling the
78497 + transmission of the pause-frames.
78498 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
78499 + if the situation causing a pause frame to be sent didn't finish when the timer
78500 + reached the threshold quanta, the MAC will retransmit the pause frame.
78501 + Each quanta represents a 512 bit-times.
78502 +
78503 + @Return E_OK on success; Error code otherwise.
78504 +
78505 + @Cautions Allowed only following FM_MAC_Init().
78506 + In order for PFC to work properly the user must configure
78507 + TNUM-aging in the tx-port it is recommended that pre-fetch and
78508 + rate limit in the tx port should be disabled;
78509 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
78510 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
78511 + in the 'priority' field.
78512 +*//***************************************************************************/
78513 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
78514 + uint8_t priority,
78515 + uint16_t pauseTime,
78516 + uint16_t threshTime);
78517 +
78518 +/**************************************************************************//**
78519 + @Function FM_MAC_SetRxIgnorePauseFrames
78520 +
78521 + @Description Enable/Disable ignoring of Pause-Frames.
78522 +
78523 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78524 + @Param[in] en - boolean indicates whether to ignore the incoming pause
78525 + frames or not.
78526 +
78527 + @Return E_OK on success; Error code otherwise.
78528 +
78529 + @Cautions Allowed only following FM_MAC_Init().
78530 +*//***************************************************************************/
78531 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
78532 +
78533 +/**************************************************************************//**
78534 + @Function FM_MAC_SetWakeOnLan
78535 +
78536 + @Description Enable/Disable Wake On Lan support
78537 +
78538 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78539 + @Param[in] en - boolean indicates whether to enable Wake On Lan
78540 + support or not.
78541 +
78542 + @Return E_OK on success; Error code otherwise.
78543 +
78544 + @Cautions Allowed only following FM_MAC_Init().
78545 +*//***************************************************************************/
78546 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
78547 +
78548 +/**************************************************************************//**
78549 + @Function FM_MAC_ResetCounters
78550 +
78551 + @Description reset all statistics counters
78552 +
78553 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78554 +
78555 + @Return E_OK on success; Error code otherwise.
78556 +
78557 + @Cautions Allowed only following FM_MAC_Init().
78558 +*//***************************************************************************/
78559 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
78560 +
78561 +/**************************************************************************//**
78562 + @Function FM_MAC_SetException
78563 +
78564 + @Description Enable/Disable a specific Exception
78565 +
78566 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78567 + @Param[in] ex - Type of the desired exceptions
78568 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
78569 +
78570 +
78571 + @Return E_OK on success; Error code otherwise.
78572 +
78573 + @Cautions Allowed only following FM_MAC_Init().
78574 +*//***************************************************************************/
78575 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78576 +
78577 +/**************************************************************************//**
78578 + @Function FM_MAC_SetStatistics
78579 +
78580 + @Description Define Statistics level.
78581 + Where applicable, the routine also enables the MIB counters
78582 + overflow interrupt in order to keep counters accurate
78583 + and account for overflows.
78584 + This routine is relevant only for dTSEC.
78585 +
78586 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78587 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
78588 + reduce performance. Partial statistics provides only special
78589 + event counters (errors etc.). If selected, regular counters (such as
78590 + byte/packet) will be invalid and will return -1.
78591 +
78592 + @Return E_OK on success; Error code otherwise.
78593 +
78594 + @Cautions Allowed only following FM_MAC_Init().
78595 +*//***************************************************************************/
78596 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
78597 +
78598 +/**************************************************************************//**
78599 + @Function FM_MAC_GetStatistics
78600 +
78601 + @Description get all statistics counters
78602 +
78603 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78604 + @Param[in] p_Statistics - Structure with statistics
78605 +
78606 + @Return E_OK on success; Error code otherwise.
78607 +
78608 + @Cautions Allowed only following FM_Init().
78609 +*//***************************************************************************/
78610 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
78611 +
78612 +/**************************************************************************//**
78613 + @Function FM_MAC_ModifyMacAddr
78614 +
78615 + @Description Replace the main MAC Address
78616 +
78617 + @Param[in] h_FmMac - A handle to a FM Module.
78618 + @Param[in] p_EnetAddr - Ethernet Mac address
78619 +
78620 + @Return E_OK on success; Error code otherwise.
78621 +
78622 + @Cautions Allowed only after FM_MAC_Init().
78623 +*//***************************************************************************/
78624 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78625 +
78626 +/**************************************************************************//**
78627 + @Function FM_MAC_AddHashMacAddr
78628 +
78629 + @Description Add an Address to the hash table. This is for filter purpose only.
78630 +
78631 + @Param[in] h_FmMac - A handle to a FM Module.
78632 + @Param[in] p_EnetAddr - Ethernet Mac address
78633 +
78634 + @Return E_OK on success; Error code otherwise.
78635 +
78636 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
78637 + @Cautions Some address need to be filterd out in upper FM blocks.
78638 +*//***************************************************************************/
78639 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78640 +
78641 +/**************************************************************************//**
78642 + @Function FM_MAC_RemoveHashMacAddr
78643 +
78644 + @Description Delete an Address to the hash table. This is for filter purpose only.
78645 +
78646 + @Param[in] h_FmMac - A handle to a FM Module.
78647 + @Param[in] p_EnetAddr - Ethernet Mac address
78648 +
78649 + @Return E_OK on success; Error code otherwise.
78650 +
78651 + @Cautions Allowed only following FM_MAC_Init().
78652 +*//***************************************************************************/
78653 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78654 +
78655 +/**************************************************************************//**
78656 + @Function FM_MAC_AddExactMatchMacAddr
78657 +
78658 + @Description Add a unicast or multicast mac address for exact-match filtering
78659 + (8 on dTSEC, 2 for 10G-MAC)
78660 +
78661 + @Param[in] h_FmMac - A handle to a FM Module.
78662 + @Param[in] p_EnetAddr - MAC Address to ADD
78663 +
78664 + @Return E_OK on success; Error code otherwise.
78665 +
78666 + @Cautions Allowed only after FM_MAC_Init().
78667 +*//***************************************************************************/
78668 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78669 +
78670 +/**************************************************************************//**
78671 + @Function FM_MAC_RemovelExactMatchMacAddr
78672 +
78673 + @Description Remove a uni cast or multi cast mac address.
78674 +
78675 + @Param[in] h_FmMac - A handle to a FM Module.
78676 + @Param[in] p_EnetAddr - MAC Address to remove
78677 +
78678 + @Return E_OK on success; Error code otherwise..
78679 +
78680 + @Cautions Allowed only after FM_MAC_Init().
78681 +*//***************************************************************************/
78682 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
78683 +
78684 +/**************************************************************************//**
78685 + @Function FM_MAC_SetPromiscuous
78686 +
78687 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
78688 +
78689 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78690 + @Param[in] enable - TRUE to enable or FALSE to disable.
78691 +
78692 + @Return E_OK on success; Error code otherwise.
78693 +
78694 + @Cautions Allowed only after FM_MAC_Init().
78695 +*//***************************************************************************/
78696 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
78697 +
78698 +/**************************************************************************//**
78699 + @Function FM_MAC_AdjustLink
78700 +
78701 + @Description Adjusts the Ethernet link with new speed/duplex setup.
78702 + This routine is relevant for dTSEC and mEMAC.
78703 + In case of mEMAC, this routine is also used for manual
78704 + re-configuration of RGMII speed and duplex mode for
78705 + RGMII PHYs not supporting in-band status information
78706 + to MAC.
78707 +
78708 + @Param[in] h_FmMac - A handle to a FM Module.
78709 + @Param[in] speed - Ethernet speed.
78710 + @Param[in] fullDuplex - TRUE for full-duplex mode;
78711 + FALSE for half-duplex mode.
78712 +
78713 + @Return E_OK on success; Error code otherwise.
78714 +*//***************************************************************************/
78715 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
78716 +
78717 +/**************************************************************************//**
78718 + @Function FM_MAC_RestartAutoneg
78719 +
78720 + @Description Restarts the auto-negotiation process.
78721 + When auto-negotiation process is invoked under traffic the
78722 + auto-negotiation process between the internal SGMII PHY and the
78723 + external PHY does not always complete successfully. Calling this
78724 + function will restart the auto-negotiation process that will end
78725 + successfully. It is recommended to call this function after issuing
78726 + auto-negotiation restart command to the Eth Phy.
78727 + This routine is relevant only for dTSEC.
78728 +
78729 + @Param[in] h_FmMac - A handle to a FM Module.
78730 +
78731 + @Return E_OK on success; Error code otherwise.
78732 +*//***************************************************************************/
78733 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
78734 +
78735 +/**************************************************************************//**
78736 + @Function FM_MAC_GetId
78737 +
78738 + @Description Return the MAC ID
78739 +
78740 + @Param[in] h_FmMac - A handle to a FM Module.
78741 + @Param[out] p_MacId - MAC ID of device
78742 +
78743 + @Return E_OK on success; Error code otherwise.
78744 +
78745 + @Cautions Allowed only after FM_MAC_Init().
78746 +*//***************************************************************************/
78747 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
78748 +
78749 +/**************************************************************************//**
78750 + @Function FM_MAC_GetVesrion
78751 +
78752 + @Description Return Mac HW chip version
78753 +
78754 + @Param[in] h_FmMac - A handle to a FM Module.
78755 + @Param[out] p_MacVresion - Mac version as defined by the chip
78756 +
78757 + @Return E_OK on success; Error code otherwise.
78758 +
78759 + @Cautions Allowed only after FM_MAC_Init().
78760 +*//***************************************************************************/
78761 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
78762 +
78763 +/**************************************************************************//**
78764 + @Function FM_MAC_MII_WritePhyReg
78765 +
78766 + @Description Write data into Phy Register
78767 +
78768 + @Param[in] h_FmMac - A handle to a FM Module.
78769 + @Param[in] phyAddr - Phy Address on the MII bus
78770 + @Param[in] reg - Register Number.
78771 + @Param[in] data - Data to write.
78772 +
78773 + @Return E_OK on success; Error code otherwise.
78774 +
78775 + @Cautions Allowed only after FM_MAC_Init().
78776 +*//***************************************************************************/
78777 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
78778 +
78779 +/**************************************************************************//**
78780 + @Function FM_MAC_MII_ReadPhyReg
78781 +
78782 + @Description Read data from Phy Register
78783 +
78784 + @Param[in] h_FmMac - A handle to a FM Module.
78785 + @Param[in] phyAddr - Phy Address on the MII bus
78786 + @Param[in] reg - Register Number.
78787 + @Param[out] p_Data - Data from PHY.
78788 +
78789 + @Return E_OK on success; Error code otherwise.
78790 +
78791 + @Cautions Allowed only after FM_MAC_Init().
78792 +*//***************************************************************************/
78793 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
78794 +
78795 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
78796 +/**************************************************************************//**
78797 + @Function FM_MAC_DumpRegs
78798 +
78799 + @Description Dump internal registers
78800 +
78801 + @Param[in] h_FmMac - A handle to a FM Module.
78802 +
78803 + @Return E_OK on success; Error code otherwise.
78804 +
78805 + @Cautions Allowed only after FM_MAC_Init().
78806 +*//***************************************************************************/
78807 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
78808 +#endif /* (defined(DEBUG_ERRORS) && ... */
78809 +
78810 +/** @} */ /* end of FM_mac_runtime_control_grp group */
78811 +/** @} */ /* end of FM_mac_grp group */
78812 +/** @} */ /* end of FM_grp group */
78813 +
78814 +
78815 +#endif /* __FM_MAC_EXT_H */
78816 --- /dev/null
78817 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
78818 @@ -0,0 +1,1271 @@
78819 +/*
78820 + * Copyright 2008-2015 Freescale Semiconductor Inc.
78821 + *
78822 + * Redistribution and use in source and binary forms, with or without
78823 + * modification, are permitted provided that the following conditions are met:
78824 + * * Redistributions of source code must retain the above copyright
78825 + * notice, this list of conditions and the following disclaimer.
78826 + * * Redistributions in binary form must reproduce the above copyright
78827 + * notice, this list of conditions and the following disclaimer in the
78828 + * documentation and/or other materials provided with the distribution.
78829 + * * Neither the name of Freescale Semiconductor nor the
78830 + * names of its contributors may be used to endorse or promote products
78831 + * derived from this software without specific prior written permission.
78832 + *
78833 + *
78834 + * ALTERNATIVELY, this software may be distributed under the terms of the
78835 + * GNU General Public License ("GPL") as published by the Free Software
78836 + * Foundation, either version 2 of that License or (at your option) any
78837 + * later version.
78838 + *
78839 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78840 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78841 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78842 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78843 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78844 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78845 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78846 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78847 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78848 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78849 + */
78850 +
78851 +/**************************************************************************//**
78852 + @File fm_macsec_ext.h
78853 +
78854 + @Description FM MACSEC ...
78855 +*//***************************************************************************/
78856 +#ifndef __FM_MACSEC_EXT_H
78857 +#define __FM_MACSEC_EXT_H
78858 +
78859 +#include "std_ext.h"
78860 +
78861 +
78862 +/**************************************************************************//**
78863 + @Group FM_grp Frame Manager API
78864 +
78865 + @Description FM API functions, definitions and enums
78866 +
78867 + @{
78868 +*//***************************************************************************/
78869 +
78870 +/**************************************************************************//**
78871 + @Group FM_MACSEC_grp FM MACSEC
78872 +
78873 + @Description FM MACSEC API functions, definitions and enums
78874 +
78875 + @{
78876 +*//***************************************************************************/
78877 +
78878 +/**************************************************************************//**
78879 + @Description MACSEC Exceptions
78880 +*//***************************************************************************/
78881 +typedef enum e_FmMacsecExceptions {
78882 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
78883 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
78884 +} e_FmMacsecExceptions;
78885 +
78886 +
78887 +/**************************************************************************//**
78888 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
78889 +
78890 + @Description FM MACSEC Initialization Unit
78891 +
78892 + @{
78893 +*//***************************************************************************/
78894 +
78895 +/**************************************************************************//**
78896 + @Function t_FmMacsecExceptionsCallback
78897 +
78898 + @Description Exceptions user callback routine, will be called upon an
78899 + exception passing the exception identification.
78900 +
78901 + @Param[in] h_App A handle to an application layer object; This handle
78902 + will be passed by the driver upon calling this callback.
78903 + @Param[in] exception The exception.
78904 +*//***************************************************************************/
78905 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
78906 + e_FmMacsecExceptions exception);
78907 +
78908 +
78909 +/**************************************************************************//**
78910 + @Description FM MACSEC config input
78911 +*//***************************************************************************/
78912 +typedef struct t_FmMacsecParams {
78913 + t_Handle h_Fm; /**< A handle to the FM object related to */
78914 + bool guestMode; /**< Partition-id */
78915 + union {
78916 + struct {
78917 + uint8_t fmMacId; /**< FM MAC id */
78918 + } guestParams;
78919 +
78920 + struct {
78921 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
78922 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
78923 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
78924 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78925 + be passed by the driver upon calling the above callbacks */
78926 + } nonGuestParams;
78927 + };
78928 +} t_FmMacsecParams;
78929 +
78930 +/**************************************************************************//**
78931 + @Function FM_MACSEC_Config
78932 +
78933 + @Description Creates descriptor for the FM MACSEC module;
78934 +
78935 + The routine returns a handle (descriptor) to the FM MACSEC object;
78936 + This descriptor must be passed as first parameter to all other
78937 + FM MACSEC function calls;
78938 +
78939 + No actual initialization or configuration of FM MACSEC hardware is
78940 + done by this routine.
78941 +
78942 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
78943 +
78944 + @Retval Handle to FM MACSEC object, or NULL for Failure.
78945 +*//***************************************************************************/
78946 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
78947 +
78948 +/**************************************************************************//**
78949 + @Function FM_MACSEC_Init
78950 +
78951 + @Description Initializes the FM MACSEC module.
78952 +
78953 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
78954 +
78955 + @Return E_OK on success; Error code otherwise.
78956 +*//***************************************************************************/
78957 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
78958 +
78959 +/**************************************************************************//**
78960 + @Function FM_MACSEC_Free
78961 +
78962 + @Description Frees all resources that were assigned to FM MACSEC module;
78963 +
78964 + Calling this routine invalidates the descriptor.
78965 +
78966 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
78967 +
78968 + @Return E_OK on success; Error code otherwise.
78969 +*//***************************************************************************/
78970 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
78971 +
78972 +
78973 +/**************************************************************************//**
78974 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
78975 +
78976 + @Description Configuration functions used to change default values.
78977 +
78978 + @{
78979 +*//***************************************************************************/
78980 +
78981 +/**************************************************************************//**
78982 + @Description enum for unknown sci frame treatment
78983 +*//***************************************************************************/
78984 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
78985 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
78986 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
78987 + Controlled port - Check or Disable mode */
78988 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
78989 + 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,
78990 + else discard on uncontrolled port and deliver on controlled port
78991 + Controlled port - Check or Disable mode */
78992 +} e_FmMacsecUnknownSciFrameTreatment;
78993 +
78994 +/**************************************************************************//**
78995 + @Description enum for untag frame treatment
78996 +*//***************************************************************************/
78997 +typedef enum e_FmMacsecUntagFrameTreatment {
78998 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
78999 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
79000 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
79001 +} e_FmMacsecUntagFrameTreatment;
79002 +
79003 +/**************************************************************************//**
79004 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
79005 +
79006 + @Description Change the treatment for received frames with unknown sci from its default
79007 + configuration [DEFAULT_unknownSciFrameTreatment].
79008 +
79009 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79010 + @Param[in] treatMode The selected mode.
79011 +
79012 + @Return E_OK on success; Error code otherwise.
79013 +
79014 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79015 +*//***************************************************************************/
79016 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
79017 +
79018 +/**************************************************************************//**
79019 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
79020 +
79021 + @Description Change the treatment for received frames with invalid tags or
79022 + a zero value PN or an invalid ICV from its default configuration
79023 + [DEFAULT_invalidTagsFrameTreatment].
79024 +
79025 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79026 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79027 + In both cases discard on the controlled port;
79028 + this provide Strict, Check or Disable mode.
79029 +
79030 + @Return E_OK on success; Error code otherwise.
79031 +
79032 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79033 +*//***************************************************************************/
79034 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79035 +
79036 +/**************************************************************************//**
79037 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
79038 +
79039 + @Description Change the treatment for received frames with the Encryption bit
79040 + set and the Changed Text bit clear from its default configuration
79041 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
79042 +
79043 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79044 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
79045 + In both cases discard on the controlled port;
79046 + this provide Strict, Check or Disable mode.
79047 +
79048 + @Return E_OK on success; Error code otherwise.
79049 +
79050 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79051 +*//***************************************************************************/
79052 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
79053 +
79054 +/**************************************************************************//**
79055 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
79056 +
79057 + @Description Change the treatment for received frames with the Encryption bit
79058 + clear and the Changed Text bit set from its default configuration
79059 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
79060 +
79061 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79062 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79063 + In both cases discard on the controlled port;
79064 + this provide Strict, Check or Disable mode.
79065 +
79066 + @Return E_OK on success; Error code otherwise.
79067 +
79068 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79069 +*//***************************************************************************/
79070 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79071 +
79072 +/**************************************************************************//**
79073 + @Function FM_MACSEC_ConfigUntagFrameTreatment
79074 +
79075 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
79076 + from its default configuration [DEFAULT_untagFrameTreatment].
79077 +
79078 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79079 + @Param[in] treatMode The selected mode.
79080 +
79081 + @Return E_OK on success; Error code otherwise.
79082 +
79083 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79084 +*//***************************************************************************/
79085 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
79086 +
79087 +/**************************************************************************//**
79088 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
79089 +
79090 + @Description Change the treatment for received frames with only SCB bit set
79091 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
79092 +
79093 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79094 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79095 + In both cases discard on the controlled port;
79096 + this provide Strict, Check or Disable mode.
79097 +
79098 + @Return E_OK on success; Error code otherwise.
79099 +
79100 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79101 +*//***************************************************************************/
79102 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79103 +
79104 +/**************************************************************************//**
79105 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
79106 +
79107 + @Description It's provide the ability to configure a PN exhaustion threshold;
79108 + When the NextPn crosses this value an interrupt event
79109 + is asserted to warn that the active SA should re-key.
79110 +
79111 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79112 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
79113 + is asserted to re-key.
79114 +
79115 + @Return E_OK on success; Error code otherwise.
79116 +
79117 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79118 +*//***************************************************************************/
79119 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
79120 +
79121 +/**************************************************************************//**
79122 + @Function FM_MACSEC_ConfigKeysUnreadable
79123 +
79124 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
79125 + Can not be cleared unless hard reset.
79126 +
79127 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79128 +
79129 + @Return E_OK on success; Error code otherwise.
79130 +
79131 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79132 +*//***************************************************************************/
79133 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
79134 +
79135 +/**************************************************************************//**
79136 + @Function FM_MACSEC_ConfigSectagWithoutSCI
79137 +
79138 + @Description Promise that all generated Sectag will be without SCI included.
79139 +
79140 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79141 +
79142 + @Return E_OK on success; Error code otherwise.
79143 +
79144 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79145 +*//***************************************************************************/
79146 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
79147 +
79148 +/**************************************************************************//**
79149 + @Function FM_MACSEC_ConfigException
79150 +
79151 + @Description Calling this routine changes the internal driver data base
79152 + from its default selection of exceptions enablement;
79153 + By default all exceptions are enabled.
79154 +
79155 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79156 + @Param[in] exception The exception to be selected.
79157 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79158 +
79159 + @Return E_OK on success; Error code otherwise.
79160 +
79161 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79162 +*//***************************************************************************/
79163 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79164 +
79165 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
79166 +/** @} */ /* end of FM_MACSEC_init_grp group */
79167 +
79168 +
79169 +/**************************************************************************//**
79170 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
79171 +
79172 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
79173 +
79174 + @{
79175 +*//***************************************************************************/
79176 +
79177 +/**************************************************************************//**
79178 + @Function FM_MACSEC_GetRevision
79179 +
79180 + @Description Return MACSEC HW chip revision
79181 +
79182 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79183 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
79184 +
79185 + @Return E_OK on success; Error code otherwise.
79186 +
79187 + @Cautions Allowed only after FM_MACSEC_Init().
79188 +*//***************************************************************************/
79189 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
79190 +
79191 +/**************************************************************************//**
79192 + @Function FM_MACSEC_Enable
79193 +
79194 + @Description This routine should be called after MACSEC is initialized for enabling all
79195 + MACSEC engines according to their existing configuration.
79196 +
79197 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79198 +
79199 + @Return E_OK on success; Error code otherwise.
79200 +
79201 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
79202 +*//***************************************************************************/
79203 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
79204 +
79205 +/**************************************************************************//**
79206 + @Function FM_MACSEC_Disable
79207 +
79208 + @Description This routine may be called when MACSEC is enabled in order to
79209 + disable all MACSEC engines; The MACSEC is working in bypass mode.
79210 +
79211 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79212 +
79213 + @Return E_OK on success; Error code otherwise.
79214 +
79215 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
79216 +*//***************************************************************************/
79217 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
79218 +
79219 +/**************************************************************************//**
79220 + @Function FM_MACSEC_SetException
79221 +
79222 + @Description Calling this routine enables/disables the specified exception.
79223 +
79224 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79225 + @Param[in] exception The exception to be selected.
79226 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79227 +
79228 + @Return E_OK on success; Error code otherwise.
79229 +
79230 + @Cautions Allowed only following FM_MACSEC_Init().
79231 +*//***************************************************************************/
79232 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79233 +
79234 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79235 +/**************************************************************************//**
79236 + @Function FM_MACSEC_DumpRegs
79237 +
79238 + @Description Dump internal registers.
79239 +
79240 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
79241 +
79242 + @Return E_OK on success; Error code otherwise.
79243 +
79244 + @Cautions Allowed only after FM_MACSEC_Init().
79245 +*//***************************************************************************/
79246 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
79247 +#endif /* (defined(DEBUG_ERRORS) && ... */
79248 +
79249 +#ifdef VERIFICATION_SUPPORT
79250 +/********************* VERIFICATION ONLY ********************************/
79251 +/**************************************************************************//**
79252 + @Function FM_MACSEC_BackdoorSet
79253 +
79254 + @Description Set register of the MACSEC memory map
79255 +
79256 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79257 + @Param[out] offset Register offset.
79258 + @Param[out] value Value to write.
79259 +
79260 +
79261 + @Return None
79262 +
79263 + @Cautions Allowed only following FM_MACSEC_Init().
79264 +*//***************************************************************************/
79265 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
79266 +
79267 +/**************************************************************************//**
79268 + @Function FM_MACSEC_BackdoorGet
79269 +
79270 + @Description Read from register of the MACSEC memory map.
79271 +
79272 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79273 + @Param[out] offset Register offset.
79274 +
79275 + @Return Value read
79276 +
79277 + @Cautions Allowed only following FM_MACSEC_Init().
79278 +*//***************************************************************************/
79279 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
79280 +#endif /* VERIFICATION_SUPPORT */
79281 +
79282 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
79283 +
79284 +
79285 +/**************************************************************************//**
79286 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
79287 +
79288 + @Description FM-MACSEC SecY API functions, definitions and enums
79289 +
79290 + @{
79291 +*//***************************************************************************/
79292 +
79293 +typedef uint8_t macsecSAKey_t[32];
79294 +typedef uint64_t macsecSCI_t;
79295 +typedef uint8_t macsecAN_t;
79296 +
79297 +/**************************************************************************//**
79298 +@Description MACSEC SECY Cipher Suite
79299 +*//***************************************************************************/
79300 +typedef enum e_FmMacsecSecYCipherSuite {
79301 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
79302 +#if (DPAA_VERSION >= 11)
79303 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
79304 +#endif /* (DPAA_VERSION >= 11) */
79305 +} e_FmMacsecSecYCipherSuite;
79306 +
79307 +/**************************************************************************//**
79308 + @Description MACSEC SECY Exceptions
79309 +*//***************************************************************************/
79310 +typedef enum e_FmMacsecSecYExceptions {
79311 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
79312 +} e_FmMacsecSecYExceptions;
79313 +
79314 +/**************************************************************************//**
79315 + @Description MACSEC SECY Events
79316 +*//***************************************************************************/
79317 +typedef enum e_FmMacsecSecYEvents {
79318 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
79319 +} e_FmMacsecSecYEvents;
79320 +
79321 +/**************************************************************************//**
79322 + @Collection MACSEC SECY Frame Discarded Descriptor error
79323 +*//***************************************************************************/
79324 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
79325 +
79326 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
79327 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
79328 +/* @} */
79329 +
79330 +/**************************************************************************//**
79331 + @Function t_FmMacsecSecYExceptionsCallback
79332 +
79333 + @Description Exceptions user callback routine, will be called upon an
79334 + exception passing the exception identification.
79335 +
79336 + @Param[in] h_App A handle to an application layer object; This handle
79337 + will be passed by the driver upon calling this callback.
79338 + @Param[in] exception The exception.
79339 +*//***************************************************************************/
79340 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
79341 + e_FmMacsecSecYExceptions exception);
79342 +
79343 +/**************************************************************************//**
79344 + @Function t_FmMacsecSecYEventsCallback
79345 +
79346 + @Description Events user callback routine, will be called upon an
79347 + event passing the event identification.
79348 +
79349 + @Param[in] h_App A handle to an application layer object; This handle
79350 + will be passed by the driver upon calling this callback.
79351 + @Param[in] event The event.
79352 +*//***************************************************************************/
79353 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
79354 + e_FmMacsecSecYEvents event);
79355 +
79356 +/**************************************************************************//**
79357 + @Description RFC2863 MIB
79358 +*//***************************************************************************/
79359 +typedef struct t_MIBStatistics {
79360 + uint64_t ifInOctets; /**< Total number of byte received */
79361 + uint64_t ifInPkts; /**< Total number of packets received */
79362 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
79363 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79364 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
79365 + - InPktsNoTag,
79366 + - InPktsLate,
79367 + - InPktsOverrun */
79368 + uint64_t ifInErrors; /**< Number of frames received with error:
79369 + - InPktsBadTag,
79370 + - InPktsNoSCI,
79371 + - InPktsNotUsingSA
79372 + - InPktsNotValid */
79373 + uint64_t ifOutOctets; /**< Total number of byte sent */
79374 + uint64_t ifOutPkts; /**< Total number of packets sent */
79375 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79376 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79377 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
79378 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79379 + - FIFO Overflow Error
79380 + - FIFO Underflow Error
79381 + - Other */
79382 +} t_MIBStatistics;
79383 +
79384 +/**************************************************************************//**
79385 + @Description MACSEC SecY Rx SA Statistics
79386 +*//***************************************************************************/
79387 +typedef struct t_FmMacsecSecYRxSaStatistics {
79388 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79389 + frame validation frame validation with the validateFrame not set to disable */
79390 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79391 + validation with the validateFrame set to check */
79392 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79393 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79394 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79395 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79396 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79397 + with validateFrame not in the strict mode and the C bit is cleared */
79398 +} t_FmMacsecSecYRxSaStatistics;
79399 +
79400 +/**************************************************************************//**
79401 + @Description MACSEC SecY Tx SA Statistics
79402 +*//***************************************************************************/
79403 +typedef struct t_FmMacsecSecYTxSaStatistics {
79404 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79405 + be transmitted, which were integrity protected */
79406 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79407 + be transmitted, which were confidentiality protected */
79408 +} t_FmMacsecSecYTxSaStatistics;
79409 +
79410 +/**************************************************************************//**
79411 + @Description MACSEC SecY Rx SC Statistics
79412 +*//***************************************************************************/
79413 +typedef struct t_FmMacsecSecYRxScStatistics {
79414 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79415 + that are not validated with the validateFrame set to disable */
79416 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79417 + that have their PN smaller than the lowest_PN with the validateFrame set to
79418 + disable or replayProtect disabled */
79419 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
79420 + that have their PN smaller than the lowest_PN with the validateFrame set to
79421 + Check or Strict and replayProtect enabled */
79422 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79423 + frame validation frame validation with the validateFrame not set to disable */
79424 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79425 + validation with the validateFrame set to check */
79426 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79427 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79428 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79429 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79430 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79431 + with validateFrame not in the strict mode and the C bit is cleared */
79432 +} t_FmMacsecSecYRxScStatistics;
79433 +
79434 +/**************************************************************************//**
79435 + @Description MACSEC SecY Tx SC Statistics
79436 +*//***************************************************************************/
79437 +typedef struct t_FmMacsecSecYTxScStatistics {
79438 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79439 + be transmitted, which were integrity protected */
79440 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79441 + be transmitted, which were confidentiality protected */
79442 +} t_FmMacsecSecYTxScStatistics;
79443 +
79444 +/**************************************************************************//**
79445 + @Description MACSEC SecY Statistics
79446 +*//***************************************************************************/
79447 +typedef struct t_FmMacsecSecYStatistics {
79448 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
79449 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
79450 +/* Frame verification statistics */
79451 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
79452 + (SecTAG) with validateFrames which is not in the strict mode */
79453 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
79454 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
79455 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
79456 + SecTAG or a zero value PN or an invalid ICV */
79457 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
79458 + condition : validateFrames is not in the strict mode and the
79459 + C bit in the SecTAG is not set */
79460 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
79461 + information with the condition : validateFrames is in the strict mode
79462 + or the C bit in the SecTAG is set */
79463 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
79464 + received packets exceeded the cryptographic performance capabilities */
79465 +/* Frame validation statistics */
79466 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
79467 + resolved SCI that were integrity protected but not encrypted */
79468 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
79469 + resolved SCI that were integrity protected and encrypted */
79470 +/* Frame generation statistics */
79471 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
79472 + be transmitted, with protectFrame false */
79473 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
79474 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
79475 +/* Frame protection statistics */
79476 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
79477 + integrity protected but not encrypted */
79478 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
79479 + both integrity protected and encrypted */
79480 +} t_FmMacsecSecYStatistics;
79481 +
79482 +
79483 +/**************************************************************************//**
79484 + @Description MACSEC SecY SC Params
79485 +*//***************************************************************************/
79486 +typedef struct t_FmMacsecSecYSCParams {
79487 + macsecSCI_t sci; /**< The secure channel identification of the SC */
79488 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
79489 +} t_FmMacsecSecYSCParams;
79490 +
79491 +/**************************************************************************//**
79492 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
79493 +
79494 + @Description FM-MACSEC SecY Initialization Unit
79495 +
79496 + @{
79497 +*//***************************************************************************/
79498 +
79499 +/**************************************************************************//**
79500 + @Description enum for validate frames
79501 +*//***************************************************************************/
79502 +typedef enum e_FmMacsecValidFrameBehavior {
79503 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
79504 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
79505 + without filtering out invalid frames */
79506 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
79507 + out those invalid frames */
79508 +} e_FmMacsecValidFrameBehavior;
79509 +
79510 +/**************************************************************************//**
79511 + @Description enum for sci insertion
79512 +*//***************************************************************************/
79513 +typedef enum e_FmMacsecSciInsertionMode {
79514 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
79515 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
79516 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
79517 +} e_FmMacsecSciInsertionMode;
79518 +
79519 +/**************************************************************************//**
79520 + @Description FM MACSEC SecY config input
79521 +*//***************************************************************************/
79522 +typedef struct t_FmMacsecSecYParams {
79523 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
79524 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
79525 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
79526 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
79527 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
79528 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79529 + be passed by the driver upon calling the above callbacks */
79530 +} t_FmMacsecSecYParams;
79531 +
79532 +/**************************************************************************//**
79533 + @Function FM_MACSEC_SECY_Config
79534 +
79535 + @Description Creates descriptor for the FM MACSEC SECY module;
79536 +
79537 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
79538 + This descriptor must be passed as first parameter to all other
79539 + FM MACSEC SECY function calls;
79540 + No actual initialization or configuration of FM MACSEC SecY hardware is
79541 + done by this routine.
79542 +
79543 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
79544 +
79545 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
79546 +*//***************************************************************************/
79547 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
79548 +
79549 +/**************************************************************************//**
79550 + @Function FM_MACSEC_SECY_Init
79551 +
79552 + @Description Initializes the FM MACSEC SECY module.
79553 +
79554 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79555 +
79556 + @Return E_OK on success; Error code otherwise.
79557 +*//***************************************************************************/
79558 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
79559 +
79560 +/**************************************************************************//**
79561 + @Function FM_MACSEC_SECY_Free
79562 +
79563 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
79564 +
79565 + Calling this routine invalidates the descriptor.
79566 +
79567 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79568 +
79569 + @Return E_OK on success; Error code otherwise.
79570 +*//***************************************************************************/
79571 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
79572 +
79573 +/**************************************************************************//**
79574 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
79575 +
79576 + @Description Configuration functions used to change default values.
79577 +
79578 + @{
79579 +*//***************************************************************************/
79580 +
79581 +/**************************************************************************//**
79582 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
79583 +
79584 + @Description Calling this routine changes the SCI-insertion-mode in the
79585 + internal driver data base from its default configuration
79586 + [DEFAULT_sciInsertionMode]
79587 +
79588 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79589 + @Param[in] sciInsertionMode Sci insertion mode
79590 +
79591 + @Return E_OK on success; Error code otherwise.
79592 +
79593 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79594 +
79595 +*//***************************************************************************/
79596 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
79597 +
79598 +/**************************************************************************//**
79599 + @Function FM_MACSEC_SECY_ConfigProtectFrames
79600 +
79601 + @Description Calling this routine changes the protect-frame mode in the
79602 + internal driver data base from its default configuration
79603 + [DEFAULT_protectFrames]
79604 +
79605 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79606 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
79607 +
79608 + @Return E_OK on success; Error code otherwise.
79609 +
79610 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79611 +
79612 +*//***************************************************************************/
79613 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
79614 +
79615 +/**************************************************************************//**
79616 + @Function FM_MACSEC_SECY_ConfigReplayWindow
79617 +
79618 + @Description Calling this routine changes the replay-window settings in the
79619 + internal driver data base from its default configuration
79620 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
79621 +
79622 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79623 + @Param[in] replayProtect; Replay protection function mode
79624 + @Param[in] replayWindow; The size of the replay window
79625 +
79626 + @Return E_OK on success; Error code otherwise.
79627 +
79628 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79629 +
79630 +*//***************************************************************************/
79631 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
79632 +
79633 +/**************************************************************************//**
79634 + @Function FM_MACSEC_SECY_ConfigValidationMode
79635 +
79636 + @Description Calling this routine changes the frame-validation-behavior mode
79637 + in the internal driver data base from its default configuration
79638 + [DEFAULT_validateFrames]
79639 +
79640 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79641 + @Param[in] validateFrames Validation function mode
79642 +
79643 + @Return E_OK on success; Error code otherwise.
79644 +
79645 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79646 +
79647 +*//***************************************************************************/
79648 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
79649 +
79650 +/**************************************************************************//**
79651 + @Function FM_MACSEC_SECY_ConfigConfidentiality
79652 +
79653 + @Description Calling this routine changes the confidentiality settings in the
79654 + internal driver data base from its default configuration
79655 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
79656 +
79657 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79658 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
79659 + FALSE - no confidentiality protection, only integrity protection
79660 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
79661 + common values are 0, 30, and 50
79662 +
79663 + @Return E_OK on success; Error code otherwise.
79664 +
79665 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79666 +
79667 +*//***************************************************************************/
79668 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
79669 +
79670 +/**************************************************************************//**
79671 + @Function FM_MACSEC_SECY_ConfigPointToPoint
79672 +
79673 + @Description configure this SecY to work in point-to-point mode, means that
79674 + it will have only one rx sc;
79675 +
79676 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79677 +
79678 + @Return E_OK on success; Error code otherwise.
79679 +
79680 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79681 + Can be called only once in a system; only the first secY that will call this
79682 + routine will be able to operate in Point-To-Point mode.
79683 +*//***************************************************************************/
79684 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
79685 +
79686 +/**************************************************************************//**
79687 + @Function FM_MACSEC_SECY_ConfigException
79688 +
79689 + @Description Calling this routine changes the internal driver data base
79690 + from its default selection of exceptions enablement;
79691 + By default all exceptions are enabled.
79692 +
79693 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79694 + @Param[in] exception The exception to be selected.
79695 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79696 +
79697 + @Return E_OK on success; Error code otherwise.
79698 +
79699 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
79700 +*//***************************************************************************/
79701 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
79702 +
79703 +/**************************************************************************//**
79704 + @Function FM_MACSEC_SECY_ConfigEvent
79705 +
79706 + @Description Calling this routine changes the internal driver data base
79707 + from its default selection of events enablement;
79708 + By default all events are enabled.
79709 +
79710 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79711 + @Param[in] event The event to be selected.
79712 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79713 +
79714 + @Return E_OK on success; Error code otherwise.
79715 +
79716 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
79717 +*//***************************************************************************/
79718 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
79719 +
79720 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
79721 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
79722 +
79723 +
79724 +/**************************************************************************//**
79725 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
79726 +
79727 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
79728 +
79729 + @{
79730 +*//***************************************************************************/
79731 +
79732 +/**************************************************************************//**
79733 + @Function FM_MACSEC_SECY_CreateRxSc
79734 +
79735 + @Description Create a receive secure channel.
79736 +
79737 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79738 + @Param[in] scParams secure channel params.
79739 +
79740 + @Return E_OK on success; Error code otherwise.
79741 +
79742 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79743 +*//***************************************************************************/
79744 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
79745 +
79746 +/**************************************************************************//**
79747 + @Function FM_MACSEC_SECY_DeleteRxSc
79748 +
79749 + @Description Deleting an initialized secure channel.
79750 +
79751 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79752 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79753 +
79754 + @Return E_OK on success; Error code otherwise.
79755 +
79756 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
79757 +*//***************************************************************************/
79758 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
79759 +
79760 +/**************************************************************************//**
79761 + @Function FM_MACSEC_SECY_CreateRxSa
79762 +
79763 + @Description Create a receive secure association for the secure channel;
79764 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
79765 +
79766 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79767 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79768 + @Param[in] an association number represent the SA.
79769 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
79770 + @Param[in] key the desired key for this SA.
79771 +
79772 + @Return E_OK on success; Error code otherwise.
79773 +
79774 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
79775 +*//***************************************************************************/
79776 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
79777 +
79778 +/**************************************************************************//**
79779 + @Function FM_MACSEC_SECY_DeleteRxSa
79780 +
79781 + @Description Deleting an initialized secure association.
79782 +
79783 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79784 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79785 + @Param[in] an association number represent the SA.
79786 +
79787 + @Return E_OK on success; Error code otherwise.
79788 +
79789 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79790 +*//***************************************************************************/
79791 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79792 +
79793 +/**************************************************************************//**
79794 + @Function FM_MACSEC_SECY_RxSaEnableReceive
79795 +
79796 + @Description Enabling the SA to receive frames.
79797 +
79798 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79799 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79800 + @Param[in] an association number represent the SA.
79801 +
79802 + @Return E_OK on success; Error code otherwise.
79803 +
79804 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79805 +*//***************************************************************************/
79806 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79807 +
79808 +/**************************************************************************//**
79809 + @Function FM_MACSEC_SECY_RxSaDisableReceive
79810 +
79811 + @Description Disabling the SA from receive frames.
79812 +
79813 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79814 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79815 + @Param[in] an association number represent the SA.
79816 +
79817 + @Return E_OK on success; Error code otherwise.
79818 +
79819 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79820 +*//***************************************************************************/
79821 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
79822 +
79823 +/**************************************************************************//**
79824 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
79825 +
79826 + @Description Update the next packet number expected on RX;
79827 + The value of nextPN shall be set to the greater of its existing value and the
79828 + supplied of updtNextPN (802.1AE-2006 10.7.15).
79829 +
79830 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79831 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79832 + @Param[in] an association number represent the SA.
79833 + @Param[in] updtNextPN the next PN value for a received frame.
79834 +
79835 + @Return E_OK on success; Error code otherwise.
79836 +
79837 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79838 +*//***************************************************************************/
79839 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
79840 +
79841 +/**************************************************************************//**
79842 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
79843 +
79844 + @Description Update the lowest packet number expected on RX;
79845 + The value of lowestPN shall be set to the greater of its existing value and the
79846 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
79847 +
79848 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79849 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79850 + @Param[in] an association number represent the SA.
79851 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
79852 +
79853 + @Return E_OK on success; Error code otherwise.
79854 +
79855 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79856 +*//***************************************************************************/
79857 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
79858 +
79859 +/**************************************************************************//**
79860 + @Function FM_MACSEC_SECY_RxSaModifyKey
79861 +
79862 + @Description Modify the current key of the SA with a new one.
79863 +
79864 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79865 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
79866 + @Param[in] an association number represent the SA.
79867 + @Param[in] key new key to replace the current key.
79868 +
79869 + @Return E_OK on success; Error code otherwise.
79870 +
79871 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
79872 +*//***************************************************************************/
79873 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
79874 +
79875 +/**************************************************************************//**
79876 + @Function FM_MACSEC_SECY_CreateTxSa
79877 +
79878 + @Description Create a transmit secure association for the secure channel;
79879 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
79880 + Only one SA can be active at a time.
79881 +
79882 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79883 + @Param[in] an association number represent the SA.
79884 + @Param[in] key the desired key for this SA.
79885 +
79886 + @Return E_OK on success; Error code otherwise.
79887 +
79888 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79889 +*//***************************************************************************/
79890 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
79891 +
79892 +/**************************************************************************//**
79893 + @Function FM_MACSEC_SECY_DeleteTxSa
79894 +
79895 + @Description Deleting an initialized secure association.
79896 +
79897 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79898 + @Param[in] an association number represent the SA.
79899 +
79900 + @Return E_OK on success; Error code otherwise.
79901 +
79902 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79903 +*//***************************************************************************/
79904 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
79905 +
79906 +/**************************************************************************//**
79907 + @Function FM_MACSEC_SECY_TxSaModifyKey
79908 +
79909 + @Description Modify the key of the inactive SA with a new one.
79910 +
79911 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79912 + @Param[in] nextActiveAn association number represent the next SA to be activated.
79913 + @Param[in] key new key to replace the current key.
79914 +
79915 + @Return E_OK on success; Error code otherwise.
79916 +
79917 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79918 +*//***************************************************************************/
79919 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
79920 +
79921 +/**************************************************************************//**
79922 + @Function FM_MACSEC_SECY_TxSaSetActive
79923 +
79924 + @Description Set this SA to the active SA to be used on TX for SC;
79925 + only one SA can be active at a time.
79926 +
79927 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79928 + @Param[in] an association number represent the SA.
79929 +
79930 + @Return E_OK on success; Error code otherwise.
79931 +
79932 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79933 +*//***************************************************************************/
79934 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
79935 +
79936 +/**************************************************************************//**
79937 + @Function FM_MACSEC_SECY_TxSaGetActive
79938 +
79939 + @Description Get the active SA that being used for TX.
79940 +
79941 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79942 + @Param[out] p_An the active an.
79943 +
79944 + @Return E_OK on success; Error code otherwise.
79945 +
79946 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79947 +*//***************************************************************************/
79948 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
79949 +
79950 +/**************************************************************************//**
79951 + @Function FM_MACSEC_SECY_GetStatistics
79952 +
79953 + @Description get all statistics counters.
79954 +
79955 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79956 + @Param[in] p_Statistics Structure with statistics.
79957 +
79958 + @Return E_OK on success; Error code otherwise.
79959 +
79960 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79961 +*//***************************************************************************/
79962 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
79963 +
79964 +/**************************************************************************//**
79965 + @Function FM_MACSEC_SECY_RxScGetStatistics
79966 +
79967 + @Description get all statistics counters.
79968 +
79969 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79970 + @Param[in] h_Sc Rx Sc handle.
79971 + @Param[in] p_Statistics Structure with statistics.
79972 +
79973 + @Return E_OK on success; Error code otherwise.
79974 +
79975 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79976 +*//***************************************************************************/
79977 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
79978 +
79979 +/**************************************************************************//**
79980 + @Function FM_MACSEC_SECY_RxSaGetStatistics
79981 +
79982 + @Description get all statistics counters
79983 +
79984 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79985 + @Param[in] h_Sc Rx Sc handle.
79986 + @Param[in] an association number represent the SA.
79987 + @Param[in] p_Statistics Structure with statistics.
79988 +
79989 + @Return E_OK on success; Error code otherwise.
79990 +
79991 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
79992 +*//***************************************************************************/
79993 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
79994 +
79995 +/**************************************************************************//**
79996 + @Function FM_MACSEC_SECY_TxScGetStatistics
79997 +
79998 + @Description get all statistics counters.
79999 +
80000 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80001 + @Param[in] p_Statistics Structure with statistics.
80002 +
80003 + @Return E_OK on success; Error code otherwise.
80004 +
80005 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80006 +*//***************************************************************************/
80007 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
80008 +
80009 +/**************************************************************************//**
80010 + @Function FM_MACSEC_SECY_TxSaGetStatistics
80011 +
80012 + @Description get all statistics counters.
80013 +
80014 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80015 + @Param[in] an association number represent the SA.
80016 + @Param[in] p_Statistics Structure with statistics.
80017 +
80018 + @Return E_OK on success; Error code otherwise.
80019 +
80020 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80021 +*//***************************************************************************/
80022 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
80023 +
80024 +/**************************************************************************//**
80025 + @Function FM_MACSEC_SECY_SetException
80026 +
80027 + @Description Calling this routine enables/disables the specified exception.
80028 +
80029 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80030 + @Param[in] exception The exception to be selected.
80031 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80032 +
80033 + @Return E_OK on success; Error code otherwise.
80034 +
80035 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80036 +*//***************************************************************************/
80037 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
80038 +
80039 +/**************************************************************************//**
80040 + @Function FM_MACSEC_SECY_SetEvent
80041 +
80042 + @Description Calling this routine enables/disables the specified event.
80043 +
80044 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80045 + @Param[in] event The event to be selected.
80046 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80047 +
80048 + @Return E_OK on success; Error code otherwise.
80049 +
80050 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80051 +*//***************************************************************************/
80052 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80053 +
80054 +/**************************************************************************//**
80055 + @Function FM_MACSEC_SECY_GetRxScPhysId
80056 +
80057 + @Description return the physical id of the Secure Channel.
80058 +
80059 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80060 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80061 + @Param[out] p_ScPhysId the SC physical id.
80062 +
80063 + @Return E_OK on success; Error code otherwise.
80064 +
80065 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80066 +*//***************************************************************************/
80067 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
80068 +
80069 +/**************************************************************************//**
80070 + @Function FM_MACSEC_SECY_GetTxScPhysId
80071 +
80072 + @Description return the physical id of the Secure Channel.
80073 +
80074 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80075 + @Param[out] p_ScPhysId the SC physical id.
80076 +
80077 + @Return E_OK on success; Error code otherwise.
80078 +
80079 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80080 +*//***************************************************************************/
80081 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
80082 +
80083 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
80084 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
80085 +/** @} */ /* end of FM_MACSEC_grp group */
80086 +/** @} */ /* end of FM_grp group */
80087 +
80088 +
80089 +#endif /* __FM_MACSEC_EXT_H */
80090 --- /dev/null
80091 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80092 @@ -0,0 +1,170 @@
80093 +/*
80094 + * Copyright 2008-2012 Freescale Semiconductor Inc.
80095 + *
80096 + * Redistribution and use in source and binary forms, with or without
80097 + * modification, are permitted provided that the following conditions are met:
80098 + * * Redistributions of source code must retain the above copyright
80099 + * notice, this list of conditions and the following disclaimer.
80100 + * * Redistributions in binary form must reproduce the above copyright
80101 + * notice, this list of conditions and the following disclaimer in the
80102 + * documentation and/or other materials provided with the distribution.
80103 + * * Neither the name of Freescale Semiconductor nor the
80104 + * names of its contributors may be used to endorse or promote products
80105 + * derived from this software without specific prior written permission.
80106 + *
80107 + *
80108 + * ALTERNATIVELY, this software may be distributed under the terms of the
80109 + * GNU General Public License ("GPL") as published by the Free Software
80110 + * Foundation, either version 2 of that License or (at your option) any
80111 + * later version.
80112 + *
80113 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80114 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80115 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80116 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80117 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80118 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80119 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80120 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80121 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80122 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80123 + */
80124 +
80125 +
80126 +/**************************************************************************//**
80127 + @File fm_muram_ext.h
80128 +
80129 + @Description FM MURAM Application Programming Interface.
80130 +*//***************************************************************************/
80131 +#ifndef __FM_MURAM_EXT
80132 +#define __FM_MURAM_EXT
80133 +
80134 +#include "error_ext.h"
80135 +#include "std_ext.h"
80136 +
80137 +
80138 +/**************************************************************************//**
80139 +
80140 + @Group FM_grp Frame Manager API
80141 +
80142 + @Description FM API functions, definitions and enums
80143 +
80144 + @{
80145 +*//***************************************************************************/
80146 +
80147 +/**************************************************************************//**
80148 + @Group FM_muram_grp FM MURAM
80149 +
80150 + @Description FM MURAM API functions, definitions and enums
80151 +
80152 + @{
80153 +*//***************************************************************************/
80154 +
80155 +/**************************************************************************//**
80156 + @Group FM_muram_init_grp FM MURAM Initialization Unit
80157 +
80158 + @Description FM MURAM initialization API functions, definitions and enums
80159 +
80160 + @{
80161 +*//***************************************************************************/
80162 +
80163 +/**************************************************************************//**
80164 + @Function FM_MURAM_ConfigAndInit
80165 +
80166 + @Description Creates partition in the MURAM.
80167 +
80168 + The routine returns a handle (descriptor) to the MURAM partition.
80169 + This descriptor must be passed as first parameter to all other
80170 + FM-MURAM function calls.
80171 +
80172 + No actual initialization or configuration of FM_MURAM hardware is
80173 + done by this routine.
80174 +
80175 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
80176 + @Param[in] size - Size of the FM-MURAM partition.
80177 +
80178 + @Return Handle to FM-MURAM object, or NULL for Failure.
80179 +*//***************************************************************************/
80180 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
80181 +
80182 +/**************************************************************************//**
80183 + @Function FM_MURAM_Free
80184 +
80185 + @Description Frees all resources that were assigned to FM-MURAM module.
80186 +
80187 + Calling this routine invalidates the descriptor.
80188 +
80189 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80190 +
80191 + @Return E_OK on success; Error code otherwise.
80192 +*//***************************************************************************/
80193 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
80194 +
80195 +/** @} */ /* end of FM_muram_init_grp group */
80196 +
80197 +
80198 +/**************************************************************************//**
80199 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
80200 +
80201 + @Description FM MURAM control API functions, definitions and enums
80202 +
80203 + @{
80204 +*//***************************************************************************/
80205 +
80206 +/**************************************************************************//**
80207 + @Function FM_MURAM_AllocMem
80208 +
80209 + @Description Allocate some memory from FM-MURAM partition.
80210 +
80211 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80212 + @Param[in] size - size of the memory to be allocated.
80213 + @Param[in] align - Alignment of the memory.
80214 +
80215 + @Return address of the allocated memory; NULL otherwise.
80216 +*//***************************************************************************/
80217 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
80218 +
80219 +/**************************************************************************//**
80220 + @Function FM_MURAM_AllocMemForce
80221 +
80222 + @Description Allocate some specific memory from FM-MURAM partition (according
80223 + to base).
80224 +
80225 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80226 + @Param[in] base - the desired base-address to be allocated.
80227 + @Param[in] size - size of the memory to be allocated.
80228 +
80229 + @Return address of the allocated memory; NULL otherwise.
80230 +*//***************************************************************************/
80231 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
80232 +
80233 +/**************************************************************************//**
80234 + @Function FM_MURAM_FreeMem
80235 +
80236 + @Description Free an allocated memory from FM-MURAM partition.
80237 +
80238 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80239 + @Param[in] ptr - A pointer to an allocated memory.
80240 +
80241 + @Return E_OK on success; Error code otherwise.
80242 +*//***************************************************************************/
80243 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
80244 +
80245 +/**************************************************************************//**
80246 + @Function FM_MURAM_GetFreeMemSize
80247 +
80248 + @Description Returns the size (in bytes) of free MURAM memory.
80249 +
80250 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80251 +
80252 + @Return Free MURAM memory size in bytes.
80253 +*//***************************************************************************/
80254 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
80255 +
80256 +/** @} */ /* end of FM_muram_ctrl_grp group */
80257 +/** @} */ /* end of FM_muram_grp group */
80258 +/** @} */ /* end of FM_grp group */
80259 +
80260 +
80261 +
80262 +#endif /* __FM_MURAM_EXT */
80263 --- /dev/null
80264 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80265 @@ -0,0 +1,3974 @@
80266 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
80267 + * All rights reserved.
80268 + *
80269 + * Redistribution and use in source and binary forms, with or without
80270 + * modification, are permitted provided that the following conditions are met:
80271 + * * Redistributions of source code must retain the above copyright
80272 + * notice, this list of conditions and the following disclaimer.
80273 + * * Redistributions in binary form must reproduce the above copyright
80274 + * notice, this list of conditions and the following disclaimer in the
80275 + * documentation and/or other materials provided with the distribution.
80276 + * * Neither the name of Freescale Semiconductor nor the
80277 + * names of its contributors may be used to endorse or promote products
80278 + * derived from this software without specific prior written permission.
80279 + *
80280 + *
80281 + * ALTERNATIVELY, this software may be distributed under the terms of the
80282 + * GNU General Public License ("GPL") as published by the Free Software
80283 + * Foundation, either version 2 of that License or (at your option) any
80284 + * later version.
80285 + *
80286 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80287 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80288 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80289 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80290 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80291 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80292 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80293 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80294 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80295 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80296 + */
80297 +
80298 +
80299 +/**************************************************************************//**
80300 + @File fm_pcd_ext.h
80301 +
80302 + @Description FM PCD API definitions
80303 +*//***************************************************************************/
80304 +#ifndef __FM_PCD_EXT
80305 +#define __FM_PCD_EXT
80306 +
80307 +#include "std_ext.h"
80308 +#include "net_ext.h"
80309 +#include "list_ext.h"
80310 +#include "fm_ext.h"
80311 +#include "fsl_fman_kg.h"
80312 +
80313 +
80314 +/**************************************************************************//**
80315 + @Group FM_grp Frame Manager API
80316 +
80317 + @Description Frame Manager Application Programming Interface
80318 +
80319 + @{
80320 +*//***************************************************************************/
80321 +
80322 +/**************************************************************************//**
80323 + @Group FM_PCD_grp FM PCD
80324 +
80325 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
80326 +
80327 + The FM PCD module is responsible for the initialization of all
80328 + global classifying FM modules. This includes the parser general and
80329 + common registers, the key generator global and common registers,
80330 + and the policer global and common registers.
80331 + In addition, the FM PCD SW module will initialize all required
80332 + key generator schemes, coarse classification flows, and policer
80333 + profiles. When FM module is configured to work with one of these
80334 + entities, it will register to it using the FM PORT API. The PCD
80335 + module will manage the PCD resources - i.e. resource management of
80336 + KeyGen schemes, etc.
80337 +
80338 + @{
80339 +*//***************************************************************************/
80340 +
80341 +/**************************************************************************//**
80342 + @Collection General PCD defines
80343 +*//***************************************************************************/
80344 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
80345 +
80346 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
80347 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
80348 + /**< Number of distinction units is limited by
80349 + register size (32 bits) minus reserved bits
80350 + for private headers. */
80351 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
80352 + in a distinction unit */
80353 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
80354 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
80355 + For HW implementation reasons, in most
80356 + cases less than this will be allowed; The
80357 + driver will return an initialization error
80358 + if resource is unavailable. */
80359 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
80360 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
80361 +
80362 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
80363 +#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)
80364 + /**< Maximum size of SW parser code */
80365 +
80366 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
80367 + insert manipulation */
80368 +
80369 +#if (DPAA_VERSION >= 11)
80370 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
80371 +#endif /* (DPAA_VERSION >= 11) */
80372 +/* @} */
80373 +
80374 +
80375 +/**************************************************************************//**
80376 + @Group FM_PCD_init_grp FM PCD Initialization Unit
80377 +
80378 + @Description Frame Manager PCD Initialization Unit API
80379 +
80380 + @{
80381 +*//***************************************************************************/
80382 +
80383 +/**************************************************************************//**
80384 + @Description PCD counters
80385 +*//***************************************************************************/
80386 +typedef enum e_FmPcdCounters {
80387 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
80388 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
80389 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
80390 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
80391 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
80392 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
80393 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
80394 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
80395 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
80396 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
80397 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
80398 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
80399 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
80400 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
80401 + 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. */
80402 + 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. */
80403 + 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. */
80404 + 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. */
80405 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
80406 + 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. */
80407 + 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). */
80408 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
80409 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
80410 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
80411 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
80412 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
80413 +} e_FmPcdCounters;
80414 +
80415 +/**************************************************************************//**
80416 + @Description PCD interrupts
80417 +*//***************************************************************************/
80418 +typedef enum e_FmPcdExceptions {
80419 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
80420 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
80421 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
80422 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
80423 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
80424 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
80425 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
80426 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
80427 +} e_FmPcdExceptions;
80428 +
80429 +
80430 +/**************************************************************************//**
80431 + @Description Exceptions user callback routine, will be called upon an
80432 + exception passing the exception identification.
80433 +
80434 + @Param[in] h_App - User's application descriptor.
80435 + @Param[in] exception - The exception.
80436 + *//***************************************************************************/
80437 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
80438 +
80439 +/**************************************************************************//**
80440 + @Description Exceptions user callback routine, will be called upon an exception
80441 + passing the exception identification.
80442 +
80443 + @Param[in] h_App - User's application descriptor.
80444 + @Param[in] exception - The exception.
80445 + @Param[in] index - id of the relevant source (may be scheme or profile id).
80446 + *//***************************************************************************/
80447 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
80448 + e_FmPcdExceptions exception,
80449 + uint16_t index);
80450 +
80451 +/**************************************************************************//**
80452 + @Description A callback for enqueuing frame onto a QM queue.
80453 +
80454 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
80455 + @Param[in] p_Fd - Frame descriptor for the frame.
80456 +
80457 + @Return E_OK on success; Error code otherwise.
80458 + *//***************************************************************************/
80459 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
80460 +
80461 +/**************************************************************************//**
80462 + @Description Host-Command parameters structure.
80463 +
80464 + When using Host command for PCD functionalities, a dedicated port
80465 + must be used. If this routine is called for a PCD in a single partition
80466 + environment, or it is the Master partition in a Multi-partition
80467 + environment, The port will be initialized by the PCD driver
80468 + initialization routine.
80469 + *//***************************************************************************/
80470 +typedef struct t_FmPcdHcParams {
80471 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
80472 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
80473 + NOTE: When configuring Host Command port for
80474 + FMANv3 devices (DPAA_VERSION 11 and higher),
80475 + portId=0 MUST be used. */
80476 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
80477 + (irrelevant for P4080 revision 1.0) */
80478 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
80479 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
80480 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
80481 + will be used by the FM for dequeue. */
80482 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
80483 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
80484 +} t_FmPcdHcParams;
80485 +
80486 +/**************************************************************************//**
80487 + @Description The main structure for PCD initialization
80488 + *//***************************************************************************/
80489 +typedef struct t_FmPcdParams {
80490 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
80491 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
80492 + of the FM ports. */
80493 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
80494 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
80495 + t_Handle h_Fm; /**< A handle to the FM module. */
80496 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
80497 + this parameter is relevant if 'kgSupport'=TRUE. */
80498 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
80499 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
80500 + Relevant when FM not runs in "guest-mode". */
80501 +
80502 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
80503 + Relevant when FM not runs in "guest-mode". */
80504 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
80505 + Policer profile exceptions;
80506 + Relevant when FM not runs in "guest-mode". */
80507 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80508 + be passed by the driver upon calling the above callbacks;
80509 + Relevant when FM not runs in "guest-mode". */
80510 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
80511 + this parameter is relevant if 'plcrSupport'=TRUE.
80512 + NOTE: this parameter relevant only when working with multiple partitions. */
80513 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
80514 + this parameter is relevant if 'plcrSupport'=TRUE.
80515 + NOTE: this parameter relevant only when working with multiple partitions. */
80516 +} t_FmPcdParams;
80517 +
80518 +
80519 +/**************************************************************************//**
80520 + @Function FM_PCD_Config
80521 +
80522 + @Description Basic configuration of the PCD module.
80523 + Creates descriptor for the FM PCD module.
80524 +
80525 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
80526 +
80527 + @Return A handle to the initialized module.
80528 +*//***************************************************************************/
80529 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
80530 +
80531 +/**************************************************************************//**
80532 + @Function FM_PCD_Init
80533 +
80534 + @Description Initialization of the PCD module.
80535 +
80536 + @Param[in] h_FmPcd - FM PCD module descriptor.
80537 +
80538 + @Return E_OK on success; Error code otherwise.
80539 +*//***************************************************************************/
80540 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
80541 +
80542 +/**************************************************************************//**
80543 + @Function FM_PCD_Free
80544 +
80545 + @Description Frees all resources that were assigned to FM module.
80546 +
80547 + Calling this routine invalidates the descriptor.
80548 +
80549 + @Param[in] h_FmPcd - FM PCD module descriptor.
80550 +
80551 + @Return E_OK on success; Error code otherwise.
80552 +*//***************************************************************************/
80553 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
80554 +
80555 +/**************************************************************************//**
80556 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
80557 +
80558 + @Description Frame Manager PCD Advanced Configuration API.
80559 +
80560 + @{
80561 +*//***************************************************************************/
80562 +
80563 +/**************************************************************************//**
80564 + @Function FM_PCD_ConfigException
80565 +
80566 + @Description Calling this routine changes the internal driver data base
80567 + from its default selection of exceptions enabling.
80568 + [DEFAULT_numOfSharedPlcrProfiles].
80569 +
80570 + @Param[in] h_FmPcd FM PCD module descriptor.
80571 + @Param[in] exception The exception to be selected.
80572 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80573 +
80574 + @Return E_OK on success; Error code otherwise.
80575 +
80576 + @Cautions This routine should NOT be called from guest-partition
80577 + (i.e. guestId != NCSW_MASTER_ID)
80578 +*//***************************************************************************/
80579 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
80580 +
80581 +/**************************************************************************//**
80582 + @Function FM_PCD_ConfigHcFramesDataMemory
80583 +
80584 + @Description Configures memory-partition-id for FMan-Controller Host-Command
80585 + frames. Calling this routine changes the internal driver data
80586 + base from its default configuration [0].
80587 +
80588 + @Param[in] h_FmPcd FM PCD module descriptor.
80589 + @Param[in] memId Memory partition ID.
80590 +
80591 + @Return E_OK on success; Error code otherwise.
80592 +
80593 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
80594 + when FM_PCD_Config() routine was called.
80595 +*//***************************************************************************/
80596 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
80597 +
80598 +/**************************************************************************//**
80599 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
80600 +
80601 + @Description Calling this routine changes the internal driver data base
80602 + from its default selection of exceptions enablement.
80603 + [DEFAULT_numOfSharedPlcrProfiles].
80604 +
80605 + @Param[in] h_FmPcd FM PCD module descriptor.
80606 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
80607 + be shared between ports on this partition
80608 +
80609 + @Return E_OK on success; Error code otherwise.
80610 +*//***************************************************************************/
80611 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
80612 +
80613 +/**************************************************************************//**
80614 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
80615 +
80616 + @Description Calling this routine changes the internal driver data base
80617 + from its default selection of exceptions enablement.
80618 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
80619 +
80620 + @Param[in] h_FmPcd FM PCD module descriptor.
80621 + @Param[in] enable TRUE to enable, FALSE to disable
80622 +
80623 + @Return E_OK on success; Error code otherwise.
80624 +
80625 + @Cautions This routine should NOT be called from guest-partition
80626 + (i.e. guestId != NCSW_MASTER_ID)
80627 +*//***************************************************************************/
80628 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
80629 +
80630 +/**************************************************************************//**
80631 + @Function FM_PCD_ConfigPrsMaxCycleLimit
80632 +
80633 + @Description Calling this routine changes the internal data structure for
80634 + the maximum parsing time from its default value
80635 + [DEFAULT_MAX_PRS_CYC_LIM].
80636 +
80637 + @Param[in] h_FmPcd FM PCD module descriptor.
80638 + @Param[in] value 0 to disable the mechanism, or new
80639 + maximum parsing time.
80640 +
80641 + @Return E_OK on success; Error code otherwise.
80642 +
80643 + @Cautions This routine should NOT be called from guest-partition
80644 + (i.e. guestId != NCSW_MASTER_ID)
80645 +*//***************************************************************************/
80646 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
80647 +
80648 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
80649 +/** @} */ /* end of FM_PCD_init_grp group */
80650 +
80651 +
80652 +/**************************************************************************//**
80653 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
80654 +
80655 + @Description Frame Manager PCD Runtime Unit API
80656 +
80657 + The runtime control allows creation of PCD infrastructure modules
80658 + such as Network Environment Characteristics, Classification Plan
80659 + Groups and Coarse Classification Trees.
80660 + It also allows on-the-fly initialization, modification and removal
80661 + of PCD modules such as KeyGen schemes, coarse classification nodes
80662 + and Policer profiles.
80663 +
80664 + In order to explain the programming model of the PCD driver interface
80665 + a few terms should be explained, and will be used below.
80666 + - Distinction Header - One of the 16 protocols supported by the FM parser,
80667 + or one of the SHIM headers (1 or 2). May be a header with a special
80668 + option (see below).
80669 + - Interchangeable Headers Group - This is a group of Headers recognized
80670 + by either one of them. For example, if in a specific context the user
80671 + chooses to treat IPv4 and IPV6 in the same way, they may create an
80672 + interchangeable Headers Unit consisting of these 2 headers.
80673 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
80674 + Group.
80675 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
80676 + IPv6, includes multicast, broadcast and other protocol specific options.
80677 + In terms of hardware it relates to the options available in the classification
80678 + plan.
80679 + - Network Environment Characteristics - a set of Distinction Units that define
80680 + the total recognizable header selection for a certain environment. This is
80681 + NOT the list of all headers that will ever appear in a flow, but rather
80682 + everything that needs distinction in a flow, where distinction is made by KeyGen
80683 + schemes and coarse classification action descriptors.
80684 +
80685 + The PCD runtime modules initialization is done in stages. The first stage after
80686 + initializing the PCD module itself is to establish a Network Flows Environment
80687 + Definition. The application may choose to establish one or more such environments.
80688 + Later, when needed, the application will have to state, for some of its modules,
80689 + to which single environment it belongs.
80690 +
80691 + @{
80692 +*//***************************************************************************/
80693 +
80694 +/**************************************************************************//**
80695 + @Description A structure for SW parser labels
80696 + *//***************************************************************************/
80697 +typedef struct t_FmPcdPrsLabelParams {
80698 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
80699 + resolution), relative to Parser RAM. */
80700 + e_NetHeaderType hdr; /**< The existence of this header will invoke
80701 + the SW parser code; Use HEADER_TYPE_NONE
80702 + to indicate that sw parser is to run
80703 + independent of the existence of any protocol
80704 + (run before HW parser). */
80705 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
80706 + attachments for the same header, use this
80707 + index to distinguish between them. */
80708 +} t_FmPcdPrsLabelParams;
80709 +
80710 +/**************************************************************************//**
80711 + @Description A structure for SW parser
80712 + *//***************************************************************************/
80713 +typedef struct t_FmPcdPrsSwParams {
80714 + bool override; /**< FALSE to invoke a check that nothing else
80715 + was loaded to this address, including
80716 + internal patches.
80717 + TRUE to override any existing code.*/
80718 + uint32_t size; /**< SW parser code size */
80719 + uint16_t base; /**< SW parser base (in instruction counts!
80720 + must be larger than 0x20)*/
80721 + uint8_t *p_Code; /**< SW parser code */
80722 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
80723 + /**< SW parser data (parameters) */
80724 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
80725 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
80726 + /**< SW parser labels table, containing
80727 + numOfLabels entries */
80728 +} t_FmPcdPrsSwParams;
80729 +
80730 +
80731 +/**************************************************************************//**
80732 + @Function FM_PCD_Enable
80733 +
80734 + @Description This routine should be called after PCD is initialized for enabling all
80735 + PCD engines according to their existing configuration.
80736 +
80737 + @Param[in] h_FmPcd FM PCD module descriptor.
80738 +
80739 + @Return E_OK on success; Error code otherwise.
80740 +
80741 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80742 +*//***************************************************************************/
80743 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
80744 +
80745 +/**************************************************************************//**
80746 + @Function FM_PCD_Disable
80747 +
80748 + @Description This routine may be called when PCD is enabled in order to
80749 + disable all PCD engines. It may be called
80750 + only when none of the ports in the system are using the PCD.
80751 +
80752 + @Param[in] h_FmPcd FM PCD module descriptor.
80753 +
80754 + @Return E_OK on success; Error code otherwise.
80755 +
80756 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
80757 +*//***************************************************************************/
80758 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
80759 +
80760 +/**************************************************************************//**
80761 + @Function FM_PCD_GetCounter
80762 +
80763 + @Description Reads one of the FM PCD counters.
80764 +
80765 + @Param[in] h_FmPcd FM PCD module descriptor.
80766 + @Param[in] counter The requested counter.
80767 +
80768 + @Return Counter's current value.
80769 +
80770 + @Cautions Allowed only following FM_PCD_Init().
80771 + Note that it is user's responsibility to call this routine only
80772 + for enabled counters, and there will be no indication if a
80773 + disabled counter is accessed.
80774 +*//***************************************************************************/
80775 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
80776 +
80777 +/**************************************************************************//**
80778 +@Function FM_PCD_PrsLoadSw
80779 +
80780 +@Description This routine may be called in order to load software parsing code.
80781 +
80782 +
80783 +@Param[in] h_FmPcd FM PCD module descriptor.
80784 +@Param[in] p_SwPrs A pointer to a structure of software
80785 + parser parameters, including the software
80786 + parser image.
80787 +
80788 +@Return E_OK on success; Error code otherwise.
80789 +
80790 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80791 + This routine should NOT be called from guest-partition
80792 + (i.e. guestId != NCSW_MASTER_ID)
80793 +*//***************************************************************************/
80794 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
80795 +
80796 +/**************************************************************************//**
80797 +@Function FM_PCD_SetAdvancedOffloadSupport
80798 +
80799 +@Description This routine must be called in order to support the following features:
80800 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
80801 +
80802 +@Param[in] h_FmPcd FM PCD module descriptor.
80803 +
80804 +@Return E_OK on success; Error code otherwise.
80805 +
80806 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80807 + This routine should NOT be called from guest-partition
80808 + (i.e. guestId != NCSW_MASTER_ID)
80809 +*//***************************************************************************/
80810 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
80811 +
80812 +/**************************************************************************//**
80813 + @Function FM_PCD_KgSetDfltValue
80814 +
80815 + @Description Calling this routine sets a global default value to be used
80816 + by the KeyGen when parser does not recognize a required
80817 + field/header.
80818 + By default default values are 0.
80819 +
80820 + @Param[in] h_FmPcd FM PCD module descriptor.
80821 + @Param[in] valueId 0,1 - one of 2 global default values.
80822 + @Param[in] value The requested default value.
80823 +
80824 + @Return E_OK on success; Error code otherwise.
80825 +
80826 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80827 + This routine should NOT be called from guest-partition
80828 + (i.e. guestId != NCSW_MASTER_ID)
80829 +*//***************************************************************************/
80830 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
80831 +
80832 +/**************************************************************************//**
80833 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
80834 +
80835 + @Description Calling this routine allows the KeyGen to access data past
80836 + the parser finishing point.
80837 +
80838 + @Param[in] h_FmPcd FM PCD module descriptor.
80839 + @Param[in] payloadOffset the number of bytes beyond the parser location.
80840 +
80841 + @Return E_OK on success; Error code otherwise.
80842 +
80843 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
80844 + This routine should NOT be called from guest-partition
80845 + (i.e. guestId != NCSW_MASTER_ID)
80846 +*//***************************************************************************/
80847 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
80848 +
80849 +/**************************************************************************//**
80850 + @Function FM_PCD_SetException
80851 +
80852 + @Description Calling this routine enables/disables PCD interrupts.
80853 +
80854 + @Param[in] h_FmPcd FM PCD module descriptor.
80855 + @Param[in] exception The exception to be selected.
80856 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80857 +
80858 + @Return E_OK on success; Error code otherwise.
80859 +
80860 + @Cautions Allowed only following FM_PCD_Init().
80861 + This routine should NOT be called from guest-partition
80862 + (i.e. guestId != NCSW_MASTER_ID)
80863 +*//***************************************************************************/
80864 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
80865 +
80866 +/**************************************************************************//**
80867 + @Function FM_PCD_ModifyCounter
80868 +
80869 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
80870 +
80871 + @Param[in] h_FmPcd FM PCD module descriptor.
80872 + @Param[in] counter The requested counter.
80873 + @Param[in] value The requested value to be written into the counter.
80874 +
80875 + @Return E_OK on success; Error code otherwise.
80876 +
80877 + @Cautions Allowed only following FM_PCD_Init().
80878 + This routine should NOT be called from guest-partition
80879 + (i.e. guestId != NCSW_MASTER_ID)
80880 +*//***************************************************************************/
80881 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
80882 +
80883 +/**************************************************************************//**
80884 + @Function FM_PCD_SetPlcrStatistics
80885 +
80886 + @Description This routine may be used to enable/disable policer statistics
80887 + counter. By default the statistics is enabled.
80888 +
80889 + @Param[in] h_FmPcd FM PCD module descriptor
80890 + @Param[in] enable TRUE to enable, FALSE to disable.
80891 +
80892 + @Return E_OK on success; Error code otherwise.
80893 +
80894 + @Cautions Allowed only following FM_PCD_Init().
80895 + This routine should NOT be called from guest-partition
80896 + (i.e. guestId != NCSW_MASTER_ID)
80897 +*//***************************************************************************/
80898 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
80899 +
80900 +/**************************************************************************//**
80901 + @Function FM_PCD_SetPrsStatistics
80902 +
80903 + @Description Defines whether to gather parser statistics including all ports.
80904 +
80905 + @Param[in] h_FmPcd FM PCD module descriptor.
80906 + @Param[in] enable TRUE to enable, FALSE to disable.
80907 +
80908 + @Return None
80909 +
80910 + @Cautions Allowed only following FM_PCD_Init().
80911 + This routine should NOT be called from guest-partition
80912 + (i.e. guestId != NCSW_MASTER_ID)
80913 +*//***************************************************************************/
80914 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
80915 +
80916 +/**************************************************************************//**
80917 + @Function FM_PCD_HcTxConf
80918 +
80919 + @Description This routine should be called to confirm frames that were
80920 + received on the HC confirmation queue.
80921 +
80922 + @Param[in] h_FmPcd A handle to an FM PCD Module.
80923 + @Param[in] p_Fd Frame descriptor of the received frame.
80924 +
80925 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
80926 + option was selected in the initialization.
80927 +*//***************************************************************************/
80928 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
80929 +
80930 +/**************************************************************************//*
80931 + @Function FM_PCD_ForceIntr
80932 +
80933 + @Description Causes an interrupt event on the requested source.
80934 +
80935 + @Param[in] h_FmPcd FM PCD module descriptor.
80936 + @Param[in] exception An exception to be forced.
80937 +
80938 + @Return E_OK on success; Error code if the exception is not enabled,
80939 + or is not able to create interrupt.
80940 +
80941 + @Cautions Allowed only following FM_PCD_Init().
80942 + This routine should NOT be called from guest-partition
80943 + (i.e. guestId != NCSW_MASTER_ID)
80944 +*//***************************************************************************/
80945 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
80946 +
80947 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
80948 +/**************************************************************************//**
80949 + @Function FM_PCD_DumpRegs
80950 +
80951 + @Description Dumps all PCD registers
80952 +
80953 + @Param[in] h_FmPcd A handle to an FM PCD Module.
80954 +
80955 + @Return E_OK on success; Error code otherwise.
80956 +
80957 + @Cautions Allowed only following FM_PCD_Init().
80958 + NOTE: this routine may be called only for FM in master mode
80959 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
80960 + are mapped.
80961 +*//***************************************************************************/
80962 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
80963 +
80964 +/**************************************************************************//**
80965 + @Function FM_PCD_KgDumpRegs
80966 +
80967 + @Description Dumps all PCD KG registers
80968 +
80969 + @Param[in] h_FmPcd A handle to an FM PCD Module.
80970 +
80971 + @Return E_OK on success; Error code otherwise.
80972 +
80973 + @Cautions Allowed only following FM_PCD_Init().
80974 + NOTE: this routine may be called only for FM in master mode
80975 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
80976 + are mapped.
80977 +*//***************************************************************************/
80978 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
80979 +
80980 +/**************************************************************************//**
80981 + @Function FM_PCD_PlcrDumpRegs
80982 +
80983 + @Description Dumps all PCD Policer registers
80984 +
80985 + @Param[in] h_FmPcd A handle to an FM PCD Module.
80986 +
80987 + @Return E_OK on success; Error code otherwise.
80988 +
80989 + @Cautions Allowed only following FM_PCD_Init().
80990 + NOTE: this routine may be called only for FM in master mode
80991 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
80992 + are mapped.
80993 +*//***************************************************************************/
80994 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
80995 +
80996 +/**************************************************************************//**
80997 + @Function FM_PCD_PlcrProfileDumpRegs
80998 +
80999 + @Description Dumps all PCD Policer profile registers
81000 +
81001 + @Param[in] h_Profile A handle to a Policer profile.
81002 +
81003 + @Return E_OK on success; Error code otherwise.
81004 +
81005 + @Cautions Allowed only following FM_PCD_Init().
81006 + NOTE: this routine may be called only for FM in master mode
81007 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81008 + are mapped.
81009 +*//***************************************************************************/
81010 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
81011 +
81012 +/**************************************************************************//**
81013 + @Function FM_PCD_PrsDumpRegs
81014 +
81015 + @Description Dumps all PCD Parser registers
81016 +
81017 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81018 +
81019 + @Return E_OK on success; Error code otherwise.
81020 +
81021 + @Cautions Allowed only following FM_PCD_Init().
81022 + NOTE: this routine may be called only for FM in master mode
81023 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81024 + are mapped.
81025 +*//***************************************************************************/
81026 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
81027 +
81028 +/**************************************************************************//**
81029 + @Function FM_PCD_HcDumpRegs
81030 +
81031 + @Description Dumps HC Port registers
81032 +
81033 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81034 +
81035 + @Return E_OK on success; Error code otherwise.
81036 +
81037 + @Cautions Allowed only following FM_PCD_Init().
81038 + NOTE: this routine may be called only for FM in master mode
81039 + (i.e. 'guestId'=NCSW_MASTER_ID).
81040 +*//***************************************************************************/
81041 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
81042 +#endif /* (defined(DEBUG_ERRORS) && ... */
81043 +
81044 +
81045 +
81046 +/**************************************************************************//**
81047 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
81048 +
81049 + @Description Frame Manager PCD Runtime Building API
81050 +
81051 + This group contains routines for setting, deleting and modifying
81052 + PCD resources, for defining the total PCD tree.
81053 + @{
81054 +*//***************************************************************************/
81055 +
81056 +/**************************************************************************//**
81057 + @Collection Definitions of coarse classification
81058 + parameters as required by KeyGen (when coarse classification
81059 + is the next engine after this scheme).
81060 +*//***************************************************************************/
81061 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
81062 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
81063 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
81064 +#define FM_PCD_MAX_NUM_OF_KEYS 256
81065 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
81066 +#define FM_PCD_MAX_SIZE_OF_KEY 56
81067 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
81068 +#define FM_PCD_LAST_KEY_INDEX 0xffff
81069 +
81070 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
81071 +/* @} */
81072 +
81073 +/**************************************************************************//**
81074 + @Collection A set of definitions to allow protocol
81075 + special option description.
81076 +*//***************************************************************************/
81077 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
81078 +
81079 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
81080 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
81081 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
81082 +
81083 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
81084 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
81085 +
81086 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
81087 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
81088 +
81089 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
81090 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
81091 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
81092 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
81093 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
81094 +
81095 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
81096 + IPV4 Reassembly manipulation requires network
81097 + environment with IPV4 header and IPV4_FRAG_1 option */
81098 +
81099 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
81100 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
81101 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
81102 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
81103 +
81104 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
81105 + IPV6 Reassembly manipulation requires network
81106 + environment with IPV6 header and IPV6_FRAG_1 option;
81107 + in case where fragment found, the fragment-extension offset
81108 + may be found at 'shim2' (in parser-result). */
81109 +#if (DPAA_VERSION >= 11)
81110 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
81111 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
81112 + CAPWAP Reassembly manipulation requires network
81113 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
81114 + in case where fragment found, the fragment-extension offset
81115 + may be found at 'shim2' (in parser-result). */
81116 +#endif /* (DPAA_VERSION >= 11) */
81117 +
81118 +
81119 +/* @} */
81120 +
81121 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
81122 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
81123 +
81124 +/**************************************************************************//**
81125 + @Collection A set of definitions to support Header Manipulation selection.
81126 +*//***************************************************************************/
81127 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
81128 +
81129 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
81130 +
81131 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
81132 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81133 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
81134 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81135 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
81136 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
81137 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81138 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
81139 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81140 +
81141 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
81142 +
81143 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
81144 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81145 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
81146 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
81147 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81148 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
81149 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81150 +
81151 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
81152 +
81153 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
81154 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81155 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
81156 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81157 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
81158 +
81159 +/* @} */
81160 +
81161 +/**************************************************************************//**
81162 + @Description A type used for returning the order of the key extraction.
81163 + each value in this array represents the index of the extraction
81164 + command as defined by the user in the initialization extraction array.
81165 + The valid size of this array is the user define number of extractions
81166 + required (also marked by the second '0' in this array).
81167 +*//***************************************************************************/
81168 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
81169 +
81170 +/**************************************************************************//**
81171 + @Description All PCD engines
81172 +*//***************************************************************************/
81173 +typedef enum e_FmPcdEngine {
81174 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
81175 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
81176 + e_FM_PCD_KG, /**< KeyGen */
81177 + e_FM_PCD_CC, /**< Coarse classifier */
81178 + e_FM_PCD_PLCR, /**< Policer */
81179 + e_FM_PCD_PRS, /**< Parser */
81180 +#if (DPAA_VERSION >= 11)
81181 + e_FM_PCD_FR, /**< Frame-Replicator */
81182 +#endif /* (DPAA_VERSION >= 11) */
81183 + e_FM_PCD_HASH /**< Hash table */
81184 +} e_FmPcdEngine;
81185 +
81186 +/**************************************************************************//**
81187 + @Description Enumeration type for selecting extraction by header types
81188 +*//***************************************************************************/
81189 +typedef enum e_FmPcdExtractByHdrType {
81190 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
81191 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
81192 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
81193 +} e_FmPcdExtractByHdrType;
81194 +
81195 +/**************************************************************************//**
81196 + @Description Enumeration type for selecting extraction source
81197 + (when it is not the header)
81198 +*//***************************************************************************/
81199 +typedef enum e_FmPcdExtractFrom {
81200 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
81201 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
81202 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
81203 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
81204 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
81205 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
81206 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
81207 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
81208 +} e_FmPcdExtractFrom;
81209 +
81210 +/**************************************************************************//**
81211 + @Description Enumeration type for selecting extraction type
81212 +*//***************************************************************************/
81213 +typedef enum e_FmPcdExtractType {
81214 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
81215 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
81216 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
81217 +} e_FmPcdExtractType;
81218 +
81219 +/**************************************************************************//**
81220 + @Description Enumeration type for selecting default extraction value
81221 +*//***************************************************************************/
81222 +typedef enum e_FmPcdKgExtractDfltSelect {
81223 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
81224 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
81225 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
81226 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
81227 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
81228 +} e_FmPcdKgExtractDfltSelect;
81229 +
81230 +/**************************************************************************//**
81231 + @Description Enumeration type defining all default groups - each group shares
81232 + a default value, one of four user-initialized values.
81233 +*//***************************************************************************/
81234 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
81235 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
81236 + e_FM_PCD_KG_TCI, /**< TCI field */
81237 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
81238 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
81239 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
81240 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
81241 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
81242 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
81243 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
81244 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
81245 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
81246 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
81247 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
81248 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
81249 + any data extraction that is not the full
81250 + field described above */
81251 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
81252 + any data extraction without validation */
81253 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
81254 + extraction from parser result or
81255 + direct use of default value */
81256 +} e_FmPcdKgKnownFieldsDfltTypes;
81257 +
81258 +/**************************************************************************//**
81259 + @Description Enumeration type for defining header index for scenarios with
81260 + multiple (tunneled) headers
81261 +*//***************************************************************************/
81262 +typedef enum e_FmPcdHdrIndex {
81263 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
81264 + to specify regular IP (not tunneled). */
81265 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
81266 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
81267 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
81268 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
81269 +} e_FmPcdHdrIndex;
81270 +
81271 +/**************************************************************************//**
81272 + @Description Enumeration type for selecting the policer profile functional type
81273 +*//***************************************************************************/
81274 +typedef enum e_FmPcdProfileTypeSelection {
81275 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
81276 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
81277 +} e_FmPcdProfileTypeSelection;
81278 +
81279 +/**************************************************************************//**
81280 + @Description Enumeration type for selecting the policer profile algorithm
81281 +*//***************************************************************************/
81282 +typedef enum e_FmPcdPlcrAlgorithmSelection {
81283 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
81284 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
81285 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
81286 +} e_FmPcdPlcrAlgorithmSelection;
81287 +
81288 +/**************************************************************************//**
81289 + @Description Enumeration type for selecting a policer profile color mode
81290 +*//***************************************************************************/
81291 +typedef enum e_FmPcdPlcrColorMode {
81292 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
81293 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
81294 +} e_FmPcdPlcrColorMode;
81295 +
81296 +/**************************************************************************//**
81297 + @Description Enumeration type for selecting a policer profile color
81298 +*//***************************************************************************/
81299 +typedef enum e_FmPcdPlcrColor {
81300 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
81301 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
81302 + e_FM_PCD_PLCR_RED, /**< Red color code */
81303 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
81304 +} e_FmPcdPlcrColor;
81305 +
81306 +/**************************************************************************//**
81307 + @Description Enumeration type for selecting the policer profile packet frame length selector
81308 +*//***************************************************************************/
81309 +typedef enum e_FmPcdPlcrFrameLengthSelect {
81310 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
81311 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
81312 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
81313 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
81314 +} e_FmPcdPlcrFrameLengthSelect;
81315 +
81316 +/**************************************************************************//**
81317 + @Description Enumeration type for selecting roll-back frame
81318 +*//***************************************************************************/
81319 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
81320 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
81321 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
81322 +} e_FmPcdPlcrRollBackFrameSelect;
81323 +
81324 +/**************************************************************************//**
81325 + @Description Enumeration type for selecting the policer profile packet or byte mode
81326 +*//***************************************************************************/
81327 +typedef enum e_FmPcdPlcrRateMode {
81328 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
81329 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
81330 +} e_FmPcdPlcrRateMode;
81331 +
81332 +/**************************************************************************//**
81333 + @Description Enumeration type for defining action of frame
81334 +*//***************************************************************************/
81335 +typedef enum e_FmPcdDoneAction {
81336 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
81337 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
81338 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
81339 + flag will be set for this frame. */
81340 +} e_FmPcdDoneAction;
81341 +
81342 +/**************************************************************************//**
81343 + @Description Enumeration type for selecting the policer counter
81344 +*//***************************************************************************/
81345 +typedef enum e_FmPcdPlcrProfileCounters {
81346 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
81347 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
81348 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
81349 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
81350 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
81351 +} e_FmPcdPlcrProfileCounters;
81352 +
81353 +/**************************************************************************//**
81354 + @Description Enumeration type for selecting the PCD action after extraction
81355 +*//***************************************************************************/
81356 +typedef enum e_FmPcdAction {
81357 + e_FM_PCD_ACTION_NONE, /**< NONE */
81358 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
81359 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
81360 +} e_FmPcdAction;
81361 +
81362 +/**************************************************************************//**
81363 + @Description Enumeration type for selecting type of insert manipulation
81364 +*//***************************************************************************/
81365 +typedef enum e_FmPcdManipHdrInsrtType {
81366 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
81367 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
81368 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81369 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
81370 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81371 +} e_FmPcdManipHdrInsrtType;
81372 +
81373 +/**************************************************************************//**
81374 + @Description Enumeration type for selecting type of remove manipulation
81375 +*//***************************************************************************/
81376 +typedef enum e_FmPcdManipHdrRmvType {
81377 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
81378 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
81379 +} e_FmPcdManipHdrRmvType;
81380 +
81381 +/**************************************************************************//**
81382 + @Description Enumeration type for selecting specific L2 fields removal
81383 +*//***************************************************************************/
81384 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
81385 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
81386 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
81387 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
81388 + the header which follows the MPLS header */
81389 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
81390 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
81391 +} e_FmPcdManipHdrRmvSpecificL2;
81392 +
81393 +/**************************************************************************//**
81394 + @Description Enumeration type for selecting specific fields updates
81395 +*//***************************************************************************/
81396 +typedef enum e_FmPcdManipHdrFieldUpdateType {
81397 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
81398 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
81399 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
81400 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
81401 +} e_FmPcdManipHdrFieldUpdateType;
81402 +
81403 +/**************************************************************************//**
81404 + @Description Enumeration type for selecting VLAN updates
81405 +*//***************************************************************************/
81406 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
81407 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
81408 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
81409 +} e_FmPcdManipHdrFieldUpdateVlan;
81410 +
81411 +/**************************************************************************//**
81412 + @Description Enumeration type for selecting specific L2 header insertion
81413 +*//***************************************************************************/
81414 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
81415 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
81416 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
81417 +} e_FmPcdManipHdrInsrtSpecificL2;
81418 +
81419 +#if (DPAA_VERSION >= 11)
81420 +/**************************************************************************//**
81421 + @Description Enumeration type for selecting QoS mapping mode
81422 +
81423 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
81424 + User should instruct the port to read the hash-result
81425 +*//***************************************************************************/
81426 +typedef enum e_FmPcdManipHdrQosMappingMode {
81427 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
81428 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
81429 +} e_FmPcdManipHdrQosMappingMode;
81430 +
81431 +/**************************************************************************//**
81432 + @Description Enumeration type for selecting QoS source
81433 +
81434 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
81435 + User should left room for the hash-result on input/output buffer
81436 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
81437 +*//***************************************************************************/
81438 +typedef enum e_FmPcdManipHdrQosSrc {
81439 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
81440 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
81441 +} e_FmPcdManipHdrQosSrc;
81442 +#endif /* (DPAA_VERSION >= 11) */
81443 +
81444 +/**************************************************************************//**
81445 + @Description Enumeration type for selecting type of header insertion
81446 +*//***************************************************************************/
81447 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
81448 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
81449 +#if (DPAA_VERSION >= 11)
81450 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
81451 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
81452 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
81453 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
81454 +#endif /* (DPAA_VERSION >= 11) */
81455 +} e_FmPcdManipHdrInsrtByHdrType;
81456 +
81457 +/**************************************************************************//**
81458 + @Description Enumeration type for selecting specific customCommand
81459 +*//***************************************************************************/
81460 +typedef enum e_FmPcdManipHdrCustomType {
81461 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
81462 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
81463 +} e_FmPcdManipHdrCustomType;
81464 +
81465 +/**************************************************************************//**
81466 + @Description Enumeration type for selecting specific customCommand
81467 +*//***************************************************************************/
81468 +typedef enum e_FmPcdManipHdrCustomIpReplace {
81469 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
81470 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
81471 +} e_FmPcdManipHdrCustomIpReplace;
81472 +
81473 +/**************************************************************************//**
81474 + @Description Enumeration type for selecting type of header removal
81475 +*//***************************************************************************/
81476 +typedef enum e_FmPcdManipHdrRmvByHdrType {
81477 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
81478 +#if (DPAA_VERSION >= 11)
81479 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
81480 +#endif /* (DPAA_VERSION >= 11) */
81481 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81482 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
81483 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81484 +} e_FmPcdManipHdrRmvByHdrType;
81485 +
81486 +/**************************************************************************//**
81487 + @Description Enumeration type for selecting type of timeout mode
81488 +*//***************************************************************************/
81489 +typedef enum e_FmPcdManipReassemTimeOutMode {
81490 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
81491 + from the first fragment to the last */
81492 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
81493 +} e_FmPcdManipReassemTimeOutMode;
81494 +
81495 +/**************************************************************************//**
81496 + @Description Enumeration type for selecting type of WaysNumber mode
81497 +*//***************************************************************************/
81498 +typedef enum e_FmPcdManipReassemWaysNumber {
81499 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
81500 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
81501 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
81502 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
81503 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
81504 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
81505 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
81506 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
81507 +} e_FmPcdManipReassemWaysNumber;
81508 +
81509 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81510 +/**************************************************************************//**
81511 + @Description Enumeration type for selecting type of statistics mode
81512 +*//***************************************************************************/
81513 +typedef enum e_FmPcdStatsType {
81514 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
81515 +} e_FmPcdStatsType;
81516 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81517 +
81518 +/**************************************************************************//**
81519 + @Description Enumeration type for selecting manipulation type
81520 +*//***************************************************************************/
81521 +typedef enum e_FmPcdManipType {
81522 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
81523 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
81524 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
81525 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
81526 +} e_FmPcdManipType;
81527 +
81528 +/**************************************************************************//**
81529 + @Description Enumeration type for selecting type of statistics mode
81530 +*//***************************************************************************/
81531 +typedef enum e_FmPcdCcStatsMode {
81532 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
81533 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
81534 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
81535 +#if (DPAA_VERSION >= 11)
81536 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
81537 + This mode is supported only on B4860 device */
81538 +#endif /* (DPAA_VERSION >= 11) */
81539 +} e_FmPcdCcStatsMode;
81540 +
81541 +/**************************************************************************//**
81542 + @Description Enumeration type for determining the action in case an IP packet
81543 + is larger than MTU but its DF (Don't Fragment) bit is set.
81544 +*//***************************************************************************/
81545 +typedef enum e_FmPcdManipDontFragAction {
81546 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
81547 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
81548 + /**< Obsolete, cannot enqueue to error queue;
81549 + In practice, selects to discard packets;
81550 + Will be removed in the future */
81551 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
81552 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
81553 +} e_FmPcdManipDontFragAction;
81554 +
81555 +/**************************************************************************//**
81556 + @Description Enumeration type for selecting type of special offload manipulation
81557 +*//***************************************************************************/
81558 +typedef enum e_FmPcdManipSpecialOffloadType {
81559 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
81560 +#if (DPAA_VERSION >= 11)
81561 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
81562 +#endif /* (DPAA_VERSION >= 11) */
81563 +} e_FmPcdManipSpecialOffloadType;
81564 +
81565 +
81566 +/**************************************************************************//**
81567 + @Description A Union of protocol dependent special options
81568 +*//***************************************************************************/
81569 +typedef union u_FmPcdHdrProtocolOpt {
81570 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
81571 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
81572 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
81573 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
81574 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
81575 +#if (DPAA_VERSION >= 11)
81576 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
81577 +#endif /* (DPAA_VERSION >= 11) */
81578 +} u_FmPcdHdrProtocolOpt;
81579 +
81580 +/**************************************************************************//**
81581 + @Description A union holding protocol fields
81582 +
81583 +
81584 + Fields supported as "full fields":
81585 + HEADER_TYPE_ETH:
81586 + NET_HEADER_FIELD_ETH_DA
81587 + NET_HEADER_FIELD_ETH_SA
81588 + NET_HEADER_FIELD_ETH_TYPE
81589 +
81590 + HEADER_TYPE_LLC_SNAP:
81591 + NET_HEADER_FIELD_LLC_SNAP_TYPE
81592 +
81593 + HEADER_TYPE_VLAN:
81594 + NET_HEADER_FIELD_VLAN_TCI
81595 + (index may apply:
81596 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81597 + e_FM_PCD_HDR_INDEX_LAST)
81598 +
81599 + HEADER_TYPE_MPLS:
81600 + NET_HEADER_FIELD_MPLS_LABEL_STACK
81601 + (index may apply:
81602 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81603 + e_FM_PCD_HDR_INDEX_2,
81604 + e_FM_PCD_HDR_INDEX_LAST)
81605 +
81606 + HEADER_TYPE_IPv4:
81607 + NET_HEADER_FIELD_IPv4_SRC_IP
81608 + NET_HEADER_FIELD_IPv4_DST_IP
81609 + NET_HEADER_FIELD_IPv4_PROTO
81610 + NET_HEADER_FIELD_IPv4_TOS
81611 + (index may apply:
81612 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81613 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81614 +
81615 + HEADER_TYPE_IPv6:
81616 + NET_HEADER_FIELD_IPv6_SRC_IP
81617 + NET_HEADER_FIELD_IPv6_DST_IP
81618 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81619 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
81620 + (index may apply:
81621 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81622 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81623 +
81624 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
81625 + the last next header indication, meaning the next L4, which may be
81626 + present at the Ipv6 last extension. On earlier revisions this field
81627 + applies to the Next-Header field of the main IPv6 header)
81628 +
81629 + HEADER_TYPE_IP:
81630 + NET_HEADER_FIELD_IP_PROTO
81631 + (index may apply:
81632 + e_FM_PCD_HDR_INDEX_LAST)
81633 + NET_HEADER_FIELD_IP_DSCP
81634 + (index may apply:
81635 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
81636 + HEADER_TYPE_GRE:
81637 + NET_HEADER_FIELD_GRE_TYPE
81638 +
81639 + HEADER_TYPE_MINENCAP
81640 + NET_HEADER_FIELD_MINENCAP_SRC_IP
81641 + NET_HEADER_FIELD_MINENCAP_DST_IP
81642 + NET_HEADER_FIELD_MINENCAP_TYPE
81643 +
81644 + HEADER_TYPE_TCP:
81645 + NET_HEADER_FIELD_TCP_PORT_SRC
81646 + NET_HEADER_FIELD_TCP_PORT_DST
81647 + NET_HEADER_FIELD_TCP_FLAGS
81648 +
81649 + HEADER_TYPE_UDP:
81650 + NET_HEADER_FIELD_UDP_PORT_SRC
81651 + NET_HEADER_FIELD_UDP_PORT_DST
81652 +
81653 + HEADER_TYPE_UDP_LITE:
81654 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
81655 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
81656 +
81657 + HEADER_TYPE_IPSEC_AH:
81658 + NET_HEADER_FIELD_IPSEC_AH_SPI
81659 + NET_HEADER_FIELD_IPSEC_AH_NH
81660 +
81661 + HEADER_TYPE_IPSEC_ESP:
81662 + NET_HEADER_FIELD_IPSEC_ESP_SPI
81663 +
81664 + HEADER_TYPE_SCTP:
81665 + NET_HEADER_FIELD_SCTP_PORT_SRC
81666 + NET_HEADER_FIELD_SCTP_PORT_DST
81667 +
81668 + HEADER_TYPE_DCCP:
81669 + NET_HEADER_FIELD_DCCP_PORT_SRC
81670 + NET_HEADER_FIELD_DCCP_PORT_DST
81671 +
81672 + HEADER_TYPE_PPPoE:
81673 + NET_HEADER_FIELD_PPPoE_PID
81674 + NET_HEADER_FIELD_PPPoE_SID
81675 +
81676 + *****************************************************************
81677 + Fields supported as "from fields":
81678 + HEADER_TYPE_ETH (with or without validation):
81679 + NET_HEADER_FIELD_ETH_TYPE
81680 +
81681 + HEADER_TYPE_VLAN (with or without validation):
81682 + NET_HEADER_FIELD_VLAN_TCI
81683 + (index may apply:
81684 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81685 + e_FM_PCD_HDR_INDEX_LAST)
81686 +
81687 + HEADER_TYPE_IPv4 (without validation):
81688 + NET_HEADER_FIELD_IPv4_PROTO
81689 + (index may apply:
81690 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81691 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81692 +
81693 + HEADER_TYPE_IPv6 (without validation):
81694 + NET_HEADER_FIELD_IPv6_NEXT_HDR
81695 + (index may apply:
81696 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81697 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81698 +
81699 +*//***************************************************************************/
81700 +typedef union t_FmPcdFields {
81701 + headerFieldEth_t eth; /**< Ethernet */
81702 + headerFieldVlan_t vlan; /**< VLAN */
81703 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
81704 + headerFieldPppoe_t pppoe; /**< PPPoE */
81705 + headerFieldMpls_t mpls; /**< MPLS */
81706 + headerFieldIp_t ip; /**< IP */
81707 + headerFieldIpv4_t ipv4; /**< IPv4 */
81708 + headerFieldIpv6_t ipv6; /**< IPv6 */
81709 + headerFieldUdp_t udp; /**< UDP */
81710 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
81711 + headerFieldTcp_t tcp; /**< TCP */
81712 + headerFieldSctp_t sctp; /**< SCTP */
81713 + headerFieldDccp_t dccp; /**< DCCP */
81714 + headerFieldGre_t gre; /**< GRE */
81715 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
81716 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
81717 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
81718 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
81719 +} t_FmPcdFields;
81720 +
81721 +/**************************************************************************//**
81722 + @Description Parameters for defining header extraction for key generation
81723 +*//***************************************************************************/
81724 +typedef struct t_FmPcdFromHdr {
81725 + uint8_t size; /**< Size in byte */
81726 + uint8_t offset; /**< Byte offset */
81727 +} t_FmPcdFromHdr;
81728 +
81729 +/**************************************************************************//**
81730 + @Description Parameters for defining field extraction for key generation
81731 +*//***************************************************************************/
81732 +typedef struct t_FmPcdFromField {
81733 + t_FmPcdFields field; /**< Field selection */
81734 + uint8_t size; /**< Size in byte */
81735 + uint8_t offset; /**< Byte offset */
81736 +} t_FmPcdFromField;
81737 +
81738 +/**************************************************************************//**
81739 + @Description Parameters for defining a single network environment unit
81740 +
81741 + A distinction unit should be defined if it will later be used
81742 + by one or more PCD engines to distinguish between flows.
81743 +*//***************************************************************************/
81744 +typedef struct t_FmPcdDistinctionUnit {
81745 + struct {
81746 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
81747 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
81748 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
81749 +} t_FmPcdDistinctionUnit;
81750 +
81751 +/**************************************************************************//**
81752 + @Description Parameters for defining all different distinction units supported
81753 + by a specific PCD Network Environment Characteristics module.
81754 +
81755 + Each unit represent a protocol or a group of protocols that may
81756 + be used later by the different PCD engines to distinguish
81757 + between flows.
81758 +*//***************************************************************************/
81759 +typedef struct t_FmPcdNetEnvParams {
81760 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
81761 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
81762 + different units to be identified */
81763 +} t_FmPcdNetEnvParams;
81764 +
81765 +/**************************************************************************//**
81766 + @Description Parameters for defining a single extraction action when
81767 + creating a key
81768 +*//***************************************************************************/
81769 +typedef struct t_FmPcdExtractEntry {
81770 + e_FmPcdExtractType type; /**< Extraction type select */
81771 + union {
81772 + struct {
81773 + e_NetHeaderType hdr; /**< Header selection */
81774 + bool ignoreProtocolValidation;
81775 + /**< Ignore protocol validation */
81776 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
81777 + IP. Otherwise should be cleared. */
81778 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
81779 + union {
81780 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
81781 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
81782 + t_FmPcdFields fullField; /**< Extract full filed parameters */
81783 + } extractByHdrType;
81784 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
81785 + struct {
81786 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
81787 + e_FmPcdAction action; /**< Relevant for CC Only */
81788 + uint16_t icIndxMask; /**< Relevant only for CC when
81789 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
81790 + Note that the number of bits that are set within
81791 + this mask must be log2 of the CC-node 'numOfKeys'.
81792 + Note that the mask cannot be set on the lower bits. */
81793 + uint8_t offset; /**< Byte offset */
81794 + uint8_t size; /**< Size in byte */
81795 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
81796 + };
81797 +} t_FmPcdExtractEntry;
81798 +
81799 +/**************************************************************************//**
81800 + @Description Parameters for defining masks for each extracted field in the key.
81801 +*//***************************************************************************/
81802 +typedef struct t_FmPcdKgExtractMask {
81803 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
81804 + uint8_t offset; /**< Byte offset */
81805 + uint8_t mask; /**< A byte mask (selected bits will be used) */
81806 +} t_FmPcdKgExtractMask;
81807 +
81808 +/**************************************************************************//**
81809 + @Description Parameters for defining default selection per groups of fields
81810 +*//***************************************************************************/
81811 +typedef struct t_FmPcdKgExtractDflt {
81812 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
81813 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
81814 +} t_FmPcdKgExtractDflt;
81815 +
81816 +/**************************************************************************//**
81817 + @Description Parameters for defining key extraction and hashing
81818 +*//***************************************************************************/
81819 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
81820 + uint32_t privateDflt0; /**< Scheme default register 0 */
81821 + uint32_t privateDflt1; /**< Scheme default register 1 */
81822 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
81823 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
81824 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
81825 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
81826 + /**< For each extraction used in this scheme, specify the required
81827 + default register to be used when header is not found.
81828 + types not specified in this array will get undefined value. */
81829 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
81830 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
81831 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
81832 + result. 0 means using the 24 LSB's, otherwise use the
81833 + 24 LSB's after shifting right.*/
81834 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
81835 + of queues for the key and hash functionality */
81836 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
81837 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
81838 + destination fields on all layers; If TRUE, driver will check that for
81839 + all layers, if SRC extraction is selected, DST extraction must also be
81840 + selected, and vice versa. */
81841 +} t_FmPcdKgKeyExtractAndHashParams;
81842 +
81843 +/**************************************************************************//**
81844 + @Description Parameters for defining a single FQID mask (extracted OR).
81845 +*//***************************************************************************/
81846 +typedef struct t_FmPcdKgExtractedOrParams {
81847 + e_FmPcdExtractType type; /**< Extraction type select */
81848 + union {
81849 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
81850 + e_NetHeaderType hdr;
81851 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
81852 + IP. Otherwise should be cleared.*/
81853 + bool ignoreProtocolValidation;
81854 + /**< continue extraction even if protocol is not recognized */
81855 + } extractByHdr; /**< Header to extract by */
81856 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
81857 + };
81858 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
81859 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
81860 + field not found */
81861 + uint8_t mask; /**< Extraction mask (specified bits are used) */
81862 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
81863 + the extracted byte; Assume byte is placed as the 8 MSB's in
81864 + a 32 bit word where the lower bits
81865 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
81866 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
81867 + extracted byte will effect the 8 LSB's of the FQID,
81868 + if bitOffsetInFqid=31 than the byte's MSB will effect
81869 + the FQID's LSB; 0 means - no effect on FQID;
81870 + Note that one, and only one of
81871 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
81872 + extracted byte must effect either FQID or Policer profile).*/
81873 + uint8_t bitOffsetInPlcrProfile;
81874 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
81875 + effect using the extracted byte; Assume byte is placed
81876 + as the 8 MSB's in a 16 bit word where the lower bits
81877 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
81878 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
81879 + than the extracted byte will effect the whole policer profile id,
81880 + if bitOffsetInFqid=15 than the byte's MSB will effect
81881 + the Policer Profile id's LSB;
81882 + 0 means - no effect on policer profile; Note that one, and only one of
81883 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
81884 + extracted byte must effect either FQID or Policer profile).*/
81885 +} t_FmPcdKgExtractedOrParams;
81886 +
81887 +/**************************************************************************//**
81888 + @Description Parameters for configuring a scheme counter
81889 +*//***************************************************************************/
81890 +typedef struct t_FmPcdKgSchemeCounter {
81891 + bool update; /**< FALSE to keep the current counter state
81892 + and continue from that point, TRUE to update/reset
81893 + the counter when the scheme is written. */
81894 + uint32_t value; /**< If update=TRUE, this value will be written into the
81895 + counter. clear this field to reset the counter. */
81896 +} t_FmPcdKgSchemeCounter;
81897 +
81898 +/**************************************************************************//**
81899 + @Description Parameters for configuring a policer profile for a KeyGen scheme
81900 + (when policer is the next engine after this scheme).
81901 +*//***************************************************************************/
81902 +typedef struct t_FmPcdKgPlcrProfile {
81903 + bool sharedProfile; /**< TRUE if this profile is shared between ports
81904 + (managed by master partition); Must not be TRUE
81905 + if profile is after Coarse Classification*/
81906 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
81907 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
81908 + together with fqidOffsetShift and numOfProfiles
81909 + parameters, to define a range of profiles from
81910 + which the KeyGen result will determine the
81911 + destination policer profile. */
81912 + union {
81913 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
81914 + should indicate the policer profile offset within the
81915 + port's policer profiles or shared window. */
81916 + struct {
81917 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
81918 + final FQID - without the FQID base). */
81919 + uint8_t fqidOffsetRelativeProfileIdBase;
81920 + /**< The base of the FMan Port's relative Storage-Profile ID;
81921 + this value will be "OR'ed" with the KeyGen create FQID
81922 + offset (i.e. not the final FQID - without the FQID base);
81923 + the final result should indicate the Storage-Profile offset
81924 + within the FMan Port's relative Storage-Profiles window/
81925 + (or the SHARED window depends on 'sharedProfile'). */
81926 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
81927 + } indirectProfile; /**< Indirect profile parameters */
81928 + } profileSelect; /**< Direct/indirect profile selection and parameters */
81929 +} t_FmPcdKgPlcrProfile;
81930 +
81931 +#if (DPAA_VERSION >= 11)
81932 +/**************************************************************************//**
81933 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
81934 +*//***************************************************************************/
81935 +typedef struct t_FmPcdKgStorageProfile {
81936 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
81937 + profile id;
81938 + If FALSE, fqidOffsetRelativeProfileIdBase is used
81939 + together with fqidOffsetShift and numOfProfiles
81940 + parameters to define a range of profiles from which
81941 + the KeyGen result will determine the destination
81942 + storage profile. */
81943 + union {
81944 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
81945 + should indicate the storage profile offset within the
81946 + port's storage profiles window. */
81947 + struct {
81948 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
81949 + final FQID - without the FQID base). */
81950 + uint8_t fqidOffsetRelativeProfileIdBase;
81951 + /**< The base of the FMan Port's relative Storage-Profile ID;
81952 + this value will be "OR'ed" with the KeyGen create FQID
81953 + offset (i.e. not the final FQID - without the FQID base);
81954 + the final result should indicate the Storage-Profile offset
81955 + within the FMan Port's relative Storage-Profiles window. */
81956 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
81957 + } indirectProfile; /**< Indirect profile parameters. */
81958 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
81959 +} t_FmPcdKgStorageProfile;
81960 +#endif /* (DPAA_VERSION >= 11) */
81961 +
81962 +/**************************************************************************//**
81963 + @Description Parameters for defining CC as the next engine after KeyGen
81964 +*//***************************************************************************/
81965 +typedef struct t_FmPcdKgCc {
81966 + t_Handle h_CcTree; /**< A handle to a CC Tree */
81967 + uint8_t grpId; /**< CC group id within the CC tree */
81968 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
81969 + policing is required. */
81970 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
81971 + selected profile is the one set at port initialization. */
81972 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
81973 + bypassPlcrProfileGeneration = FALSE */
81974 +} t_FmPcdKgCc;
81975 +
81976 +/**************************************************************************//**
81977 + @Description Parameters for defining initializing a KeyGen scheme
81978 +*//***************************************************************************/
81979 +typedef struct t_FmPcdKgSchemeParams {
81980 + bool modify; /**< TRUE to change an existing scheme */
81981 + union
81982 + {
81983 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
81984 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
81985 + } id;
81986 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
81987 + for match vector; KeyGen will ignore it when matching */
81988 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
81989 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
81990 + by FM_PCD_NetEnvCharacteristicsSet() */
81991 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
81992 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
81993 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
81994 + } netEnvParams;
81995 + bool useHash; /**< use the KeyGen Hash functionality */
81996 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
81997 + /**< used only if useHash = TRUE */
81998 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
81999 + In such a case FQID after KeyGen will be the default FQID
82000 + defined for the relevant port, or the FQID defined by CC
82001 + in cases where CC was the previous engine. */
82002 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
82003 + If hash is used and an even distribution is expected
82004 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
82005 + hashDistributionNumOfFqids. */
82006 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
82007 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
82008 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
82009 + registers are shared between qidMasks
82010 + functionality and some of the extraction
82011 + actions; Normally only some will be used
82012 + for qidMask. Driver will return error if
82013 + resource is full at initialization time. */
82014 +
82015 +#if (DPAA_VERSION >= 11)
82016 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
82017 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
82018 +#endif /* (DPAA_VERSION >= 11) */
82019 +
82020 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
82021 + union { /**< depends on nextEngine */
82022 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
82023 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
82024 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
82025 + } kgNextEngineParams;
82026 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
82027 + the scheme counter */
82028 +} t_FmPcdKgSchemeParams;
82029 +
82030 +/**************************************************************************//**
82031 + @Collection Definitions for CC statistics
82032 +*//***************************************************************************/
82033 +#if (DPAA_VERSION >= 11)
82034 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
82035 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
82036 +#endif /* (DPAA_VERSION >= 11) */
82037 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
82038 +/* @} */
82039 +
82040 +/**************************************************************************//**
82041 + @Description Parameters for defining CC as the next engine after a CC node.
82042 +*//***************************************************************************/
82043 +typedef struct t_FmPcdCcNextCcParams {
82044 + t_Handle h_CcNode; /**< A handle of the next CC node */
82045 +} t_FmPcdCcNextCcParams;
82046 +
82047 +#if (DPAA_VERSION >= 11)
82048 +/**************************************************************************//**
82049 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
82050 +*//***************************************************************************/
82051 +typedef struct t_FmPcdCcNextFrParams {
82052 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
82053 +} t_FmPcdCcNextFrParams;
82054 +#endif /* (DPAA_VERSION >= 11) */
82055 +
82056 +/**************************************************************************//**
82057 + @Description Parameters for defining Policer as the next engine after a CC node.
82058 +*//***************************************************************************/
82059 +typedef struct t_FmPcdCcNextPlcrParams {
82060 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
82061 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
82062 + TRUE if this profile is shared between ports */
82063 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
82064 + (otherwise profile id is taken from KeyGen);
82065 + This parameter should indicate the policer
82066 + profile offset within the port's
82067 + policer profiles or from SHARED window.*/
82068 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
82069 + FQID for enqueuing the frame;
82070 + In earlier chips if policer next engine is KEYGEN,
82071 + this parameter can be 0, because the KEYGEN
82072 + always decides the enqueue FQID.*/
82073 +#if (DPAA_VERSION >= 11)
82074 + uint8_t newRelativeStorageProfileId;
82075 + /**< Indicates the relative storage profile offset within
82076 + the port's storage profiles window;
82077 + Relevant only if the port was configured with VSP. */
82078 +#endif /* (DPAA_VERSION >= 11) */
82079 +} t_FmPcdCcNextPlcrParams;
82080 +
82081 +/**************************************************************************//**
82082 + @Description Parameters for defining enqueue as the next action after a CC node.
82083 +*//***************************************************************************/
82084 +typedef struct t_FmPcdCcNextEnqueueParams {
82085 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82086 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82087 + relevant if action = e_FM_PCD_ENQ_FRAME */
82088 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82089 + (otherwise FQID is taken from KeyGen),
82090 + relevant if action = e_FM_PCD_ENQ_FRAME */
82091 +#if (DPAA_VERSION >= 11)
82092 + uint8_t newRelativeStorageProfileId;
82093 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82094 + storage profile offset within the port's storage profiles
82095 + window; Relevant only if the port was configured with VSP. */
82096 +#endif /* (DPAA_VERSION >= 11) */
82097 +} t_FmPcdCcNextEnqueueParams;
82098 +
82099 +/**************************************************************************//**
82100 + @Description Parameters for defining KeyGen as the next engine after a CC node.
82101 +*//***************************************************************************/
82102 +typedef struct t_FmPcdCcNextKgParams {
82103 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82104 + Note - this parameters irrelevant for earlier chips */
82105 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82106 + (otherwise FQID is taken from KeyGen),
82107 + Note - this parameters irrelevant for earlier chips */
82108 +#if (DPAA_VERSION >= 11)
82109 + uint8_t newRelativeStorageProfileId;
82110 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82111 + storage profile offset within the port's storage profiles
82112 + window; Relevant only if the port was configured with VSP. */
82113 +#endif /* (DPAA_VERSION >= 11) */
82114 +
82115 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
82116 +} t_FmPcdCcNextKgParams;
82117 +
82118 +/**************************************************************************//**
82119 + @Description Parameters for defining the next engine after a CC node.
82120 +*//***************************************************************************/
82121 +typedef struct t_FmPcdCcNextEngineParams {
82122 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
82123 + according to nextEngine definition */
82124 + union {
82125 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
82126 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
82127 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
82128 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
82129 +#if (DPAA_VERSION >= 11)
82130 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
82131 +#endif /* (DPAA_VERSION >= 11) */
82132 + } params; /**< union used for all the next-engine parameters options */
82133 +
82134 + t_Handle h_Manip; /**< Handle to Manipulation object.
82135 + Relevant if next engine is of type result
82136 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
82137 +
82138 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
82139 + for each frame passing through this
82140 + Coarse Classification entry. */
82141 +} t_FmPcdCcNextEngineParams;
82142 +
82143 +/**************************************************************************//**
82144 + @Description Parameters for defining a single CC key
82145 +*//***************************************************************************/
82146 +typedef struct t_FmPcdCcKeyParams {
82147 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82148 + pointer to the key of the size defined in keySize */
82149 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82150 + pointer to the Mask per key of the size defined
82151 + in keySize. p_Key and p_Mask (if defined) has to be
82152 + of the same size defined in the keySize;
82153 + NOTE that if this value is equal for all entries whithin
82154 + this table, the driver will automatically use global-mask
82155 + (i.e. one common mask for all entries) instead of private
82156 + one; that is done in order to spare some memory and for
82157 + better performance. */
82158 + t_FmPcdCcNextEngineParams ccNextEngineParams;
82159 + /**< parameters for the next for the defined Key in
82160 + the p_Key */
82161 +} t_FmPcdCcKeyParams;
82162 +
82163 +/**************************************************************************//**
82164 + @Description Parameters for defining CC keys parameters
82165 + The driver supports two methods for CC node allocation: dynamic and static.
82166 + Static mode was created in order to prevent runtime alloc/free
82167 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
82168 + the driver automatically allocates the memory according to
82169 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
82170 + size that may be used for this CC-Node taking into consideration
82171 + 'maskSupport' and 'statisticsMode' parameters.
82172 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
82173 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
82174 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
82175 + all required structures are allocated according to 'numOfKeys'
82176 + parameter. During runtime modification, these structures are
82177 + re-allocated according to the updated number of keys.
82178 +
82179 + Please note that 'action' and 'icIndxMask' mentioned in the
82180 + specific parameter explanations are passed in the extraction
82181 + parameters of the node (fields of extractCcParams.extractNonHdr).
82182 +*//***************************************************************************/
82183 +typedef struct t_KeysParams {
82184 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
82185 + A value of zero may be used for dynamic memory allocation. */
82186 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
82187 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
82188 + Should be TRUE to reserve table memory for key masks, even if
82189 + initial keys do not contain masks, or if the node was initialized
82190 + as 'empty' (without keys); this will allow user to add keys with
82191 + masks at runtime.
82192 + NOTE that if user want to use only global-masks (i.e. one common mask
82193 + for all the entries within this table, this parameter should set to 'FALSE'. */
82194 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
82195 + To enable statistics gathering, statistics should be enabled per
82196 + every key, using 'statisticsEn' in next engine parameters structure
82197 + of that key;
82198 + If 'maxNumOfKeys' is set, all required structures will be
82199 + preallocated for all keys. */
82200 +#if (DPAA_VERSION >= 11)
82201 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82202 + /**< Relevant only for 'RMON' statistics mode
82203 + (this feature is supported only on B4860 device);
82204 + Holds a list of programmable thresholds - for each received frame,
82205 + its length in bytes is examined against these range thresholds and
82206 + the appropriate counter is incremented by 1 - for example, to belong
82207 + to range i, the following should hold:
82208 + range i-1 threshold < frame length <= range i threshold
82209 + Each range threshold must be larger then its preceding range
82210 + threshold, and last range threshold must be 0xFFFF. */
82211 +#endif /* (DPAA_VERSION >= 11) */
82212 + uint16_t numOfKeys; /**< Number of initial keys;
82213 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
82214 + this field should be power-of-2 of the number of bits that are
82215 + set in 'icIndxMask'. */
82216 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
82217 + to be the standard size of the selected key; For other extraction
82218 + types, 'keySize' has to be as size of extraction; When 'action' =
82219 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
82220 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
82221 + /**< An array with 'numOfKeys' entries, each entry specifies the
82222 + corresponding key parameters;
82223 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
82224 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
82225 + for the 'miss' entry. */
82226 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
82227 + /**< Parameters for defining the next engine when a key is not matched;
82228 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
82229 +} t_KeysParams;
82230 +
82231 +
82232 +/**************************************************************************//**
82233 + @Description Parameters for defining a CC node
82234 +*//***************************************************************************/
82235 +typedef struct t_FmPcdCcNodeParams {
82236 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
82237 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
82238 +} t_FmPcdCcNodeParams;
82239 +
82240 +/**************************************************************************//**
82241 + @Description Parameters for defining a hash table
82242 +*//***************************************************************************/
82243 +typedef struct t_FmPcdHashTableParams {
82244 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
82245 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
82246 + requested statistics mode will be allocated according to maxNumOfKeys. */
82247 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
82248 + that leads to this hash-table. */
82249 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
82250 + The number-of-sets for this hash will be calculated
82251 + as (2^(number of bits set in 'hashResMask'));
82252 + The 4 lower bits must be cleared. */
82253 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
82254 + 2-bytes to be used as hash index. */
82255 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
82256 +
82257 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
82258 +
82259 +} t_FmPcdHashTableParams;
82260 +
82261 +/**************************************************************************//**
82262 + @Description Parameters for defining a CC tree group.
82263 +
82264 + This structure defines a CC group in terms of NetEnv units
82265 + and the action to be taken in each case. The unitIds list must
82266 + be given in order from low to high indices.
82267 +
82268 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
82269 + structures where each defines the next action to be taken for
82270 + each units combination. for example:
82271 + numOfDistinctionUnits = 2
82272 + unitIds = {1,3}
82273 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
82274 + unit 1 - not found; unit 3 - not found;
82275 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
82276 + unit 1 - not found; unit 3 - found;
82277 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
82278 + unit 1 - found; unit 3 - not found;
82279 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
82280 + unit 1 - found; unit 3 - found;
82281 +*//***************************************************************************/
82282 +typedef struct t_FmPcdCcGrpParams {
82283 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
82284 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
82285 + /**< Indices of the units as defined in
82286 + FM_PCD_NetEnvCharacteristicsSet() */
82287 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
82288 + /**< Maximum entries per group is 16 */
82289 +} t_FmPcdCcGrpParams;
82290 +
82291 +/**************************************************************************//**
82292 + @Description Parameters for defining CC tree groups
82293 +*//***************************************************************************/
82294 +typedef struct t_FmPcdCcTreeParams {
82295 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82296 + by FM_PCD_NetEnvCharacteristicsSet() */
82297 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
82298 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
82299 + /**< Parameters for each group. */
82300 +} t_FmPcdCcTreeParams;
82301 +
82302 +
82303 +/**************************************************************************//**
82304 + @Description CC key statistics structure
82305 +*//***************************************************************************/
82306 +typedef struct t_FmPcdCcKeyStatistics {
82307 + uint32_t byteCount; /**< This counter reflects byte count of frames that
82308 + were matched by this key. */
82309 + uint32_t frameCount; /**< This counter reflects count of frames that
82310 + were matched by this key. */
82311 +#if (DPAA_VERSION >= 11)
82312 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82313 + /**< These counters reflect how many frames matched
82314 + this key in 'RMON' statistics mode:
82315 + Each counter holds the number of frames of a
82316 + specific frames length range, according to the
82317 + ranges provided at initialization. */
82318 +#endif /* (DPAA_VERSION >= 11) */
82319 +} t_FmPcdCcKeyStatistics;
82320 +
82321 +/**************************************************************************//**
82322 + @Description Parameters for defining policer byte rate
82323 +*//***************************************************************************/
82324 +typedef struct t_FmPcdPlcrByteRateModeParams {
82325 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
82326 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
82327 + e_FM_PCD_PLCR_FULL_FRM_LEN */
82328 +} t_FmPcdPlcrByteRateModeParams;
82329 +
82330 +/**************************************************************************//**
82331 + @Description Parameters for defining the policer profile (based on
82332 + RFC-2698 or RFC-4115 attributes).
82333 +*//***************************************************************************/
82334 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
82335 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
82336 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
82337 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
82338 + uint32_t committedBurstSize; /**< Bytes/Packets */
82339 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
82340 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
82341 +} t_FmPcdPlcrNonPassthroughAlgParams;
82342 +
82343 +/**************************************************************************//**
82344 + @Description Parameters for defining the next engine after policer
82345 +*//***************************************************************************/
82346 +typedef union u_FmPcdPlcrNextEngineParams {
82347 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82348 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
82349 + is Policer, must be a SHARED profile */
82350 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
82351 +} u_FmPcdPlcrNextEngineParams;
82352 +
82353 +/**************************************************************************//**
82354 + @Description Parameters for defining the policer profile entry
82355 +*//***************************************************************************/
82356 +typedef struct t_FmPcdPlcrProfileParams {
82357 + bool modify; /**< TRUE to change an existing profile */
82358 + union {
82359 + struct {
82360 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
82361 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
82362 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
82363 + } newParams; /**< use it when modify = FALSE */
82364 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
82365 + } id;
82366 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
82367 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
82368 +
82369 + union {
82370 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
82371 + any incoming packet with the default value. */
82372 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
82373 + pre-color value of 2'b11. */
82374 + } color;
82375 +
82376 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
82377 +
82378 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
82379 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
82380 +
82381 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
82382 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
82383 +
82384 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
82385 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
82386 +
82387 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
82388 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
82389 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
82390 +} t_FmPcdPlcrProfileParams;
82391 +
82392 +/**************************************************************************//**
82393 + @Description Parameters for selecting a location for requested manipulation
82394 +*//***************************************************************************/
82395 +typedef struct t_FmManipHdrInfo {
82396 + e_NetHeaderType hdr; /**< Header selection */
82397 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
82398 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
82399 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
82400 +} t_FmManipHdrInfo;
82401 +
82402 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82403 +/**************************************************************************//**
82404 + @Description Parameters for defining an insertion manipulation
82405 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
82406 +*//***************************************************************************/
82407 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
82408 + uint8_t size; /**< Size of insert template to the start of the frame. */
82409 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
82410 + /**< Array of the insertion template. */
82411 +
82412 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
82413 + struct {
82414 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
82415 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
82416 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
82417 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
82418 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
82419 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
82420 + 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.*/
82421 + struct {
82422 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
82423 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
82424 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
82425 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
82426 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
82427 +
82428 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
82429 + struct {
82430 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
82431 + VPri only 3 bits, it has to be adjusted to the right*/
82432 + } modifyOuterVlanParams;
82433 +} t_FmPcdManipHdrInsrtByTemplateParams;
82434 +
82435 +/**************************************************************************//**
82436 + @Description Parameters for defining CAPWAP fragmentation
82437 +*//***************************************************************************/
82438 +typedef struct t_CapwapFragmentationParams {
82439 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
82440 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
82441 + and all other fragments exclude the CAPWAP options field,
82442 + FALSE - all fragments include CAPWAP header options field. */
82443 +} t_CapwapFragmentationParams;
82444 +
82445 +/**************************************************************************//**
82446 + @Description Parameters for defining CAPWAP reassembly
82447 +*//***************************************************************************/
82448 +typedef struct t_CapwapReassemblyParams {
82449 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
82450 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82451 + maxNumFramesInProcess has to be in the range of 4 - 512,
82452 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82453 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
82454 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
82455 + and all processed fragments will be enqueued with error indication;
82456 + If FALSE, only duplicated fragments will be enqueued with error indication. */
82457 +
82458 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
82459 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
82460 + uint32_t timeoutRoutineRequestTime;
82461 + /**< Represents the time interval in microseconds between consecutive
82462 + timeout routine requests It has to be power of 2. */
82463 + uint32_t timeoutThresholdForReassmProcess;
82464 + /**< Time interval (microseconds) for marking frames in process as too old;
82465 + Frames in process are those for which at least one fragment was received
82466 + but not all fragments. */
82467 +
82468 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
82469 +} t_CapwapReassemblyParams;
82470 +
82471 +/**************************************************************************//**
82472 + @Description Parameters for defining fragmentation/reassembly manipulation
82473 +*//***************************************************************************/
82474 +typedef struct t_FmPcdManipFragOrReasmParams {
82475 + bool frag; /**< TRUE if using the structure for fragmentation,
82476 + otherwise this structure is used for reassembly */
82477 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82478 + Same LIODN number is used for these buffers as for
82479 + the received frames buffers, so buffers of this pool
82480 + need to be allocated in the same memory area as the
82481 + received buffers. If the received buffers arrive
82482 + from different sources, the Scatter/Gather BP id
82483 + should be mutual to all these sources. */
82484 + e_NetHeaderType hdr; /**< Header selection */
82485 + union {
82486 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
82487 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
82488 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
82489 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
82490 + } u;
82491 +} t_FmPcdManipFragOrReasmParams;
82492 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82493 +
82494 +
82495 +/**************************************************************************//**
82496 + @Description Parameters for defining header removal by header type
82497 +*//***************************************************************************/
82498 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
82499 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
82500 + union {
82501 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82502 + struct {
82503 + bool include; /**< If FALSE, remove until the specified header (not including the header);
82504 + If TRUE, remove also the specified header. */
82505 + t_FmManipHdrInfo hdrInfo;
82506 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82507 +#endif /* (DPAA_VERSION >= 11) || ... */
82508 +#if (DPAA_VERSION >= 11)
82509 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82510 +#endif /* (DPAA_VERSION >= 11) */
82511 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
82512 + Defines which L2 headers to remove. */
82513 + } u;
82514 +} t_FmPcdManipHdrRmvByHdrParams;
82515 +
82516 +/**************************************************************************//**
82517 + @Description Parameters for configuring IP fragmentation manipulation
82518 +
82519 + Restrictions:
82520 + - IP Fragmentation output fragments must not be forwarded to application directly.
82521 + - Maximum number of fragments per frame is 16.
82522 + - Fragmentation of IP fragments is not supported.
82523 + - IPv4 packets containing header Option fields are fragmented by copying all option
82524 + fields to each fragment, regardless of the copy bit value.
82525 + - Transmit confirmation is not supported.
82526 + - Fragmentation after SEC can't handle S/G frames.
82527 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82528 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82529 + - Only BMan buffers shall be used for frames to be fragmented.
82530 + - IPF does not support VSP. Therefore, on the same port where we have IPF
82531 + we cannot support VSP.
82532 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82533 + does not support VSP. Therefore, on the same port where we have IPF we
82534 + cannot support VSP.
82535 +*//***************************************************************************/
82536 +typedef struct t_FmPcdManipFragIpParams {
82537 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82538 + IP fragmentation will be executed.*/
82539 +#if (DPAA_VERSION == 10)
82540 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
82541 +#endif /* (DPAA_VERSION == 10) */
82542 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82543 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82544 + received frame's buffer. */
82545 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82546 + This parameters is relevant when 'sgBpidEn=TRUE';
82547 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82548 + of this pool need to be allocated in the same memory area as the received buffers.
82549 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82550 + mutual to all these sources. */
82551 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
82552 + than MTU and its DF bit is set, then this field will
82553 + determine the action to be taken.*/
82554 +} t_FmPcdManipFragIpParams;
82555 +
82556 +/**************************************************************************//**
82557 + @Description Parameters for configuring IP reassembly manipulation.
82558 +
82559 + This is a common structure for both IPv4 and IPv6 reassembly
82560 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
82561 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
82562 +
82563 + Restrictions:
82564 + - Application must define at least one scheme to catch the reassembled frames.
82565 + - Maximum number of fragments per frame is 16.
82566 + - Reassembly of IPv4 fragments containing Option fields is supported.
82567 +
82568 +*//***************************************************************************/
82569 +typedef struct t_FmPcdManipReassemIpParams {
82570 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
82571 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
82572 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
82573 + NOTE: The following comment is relevant only for FMAN v2 devices:
82574 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
82575 + the user schemes id to ensure that the reassembly schemes will be first match;
82576 + Rest schemes, if defined, should have higher relative scheme ID. */
82577 +#if (DPAA_VERSION >= 11)
82578 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
82579 + profile than the opening fragment (Non-Consistent-SP state)
82580 + then one of two possible scenarios occurs:
82581 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
82582 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
82583 +#else
82584 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
82585 +#endif /* (DPAA_VERSION >= 11) */
82586 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82587 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82588 + uint16_t minFragSize[2]; /**< Minimum fragment size:
82589 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
82590 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
82591 + /**< Number of frames per hash entry needed for reassembly process:
82592 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
82593 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
82594 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
82595 + Must be power of 2;
82596 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82597 + maxNumFramesInProcess has to be in the range of 4 - 512;
82598 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82599 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82600 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82601 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82602 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82603 + uint32_t timeoutThresholdForReassmProcess;
82604 + /**< Represents the time interval in microseconds which defines
82605 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82606 +} t_FmPcdManipReassemIpParams;
82607 +
82608 +/**************************************************************************//**
82609 + @Description structure for defining IPSEC manipulation
82610 +*//***************************************************************************/
82611 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
82612 + bool decryption; /**< TRUE if being used in decryption direction;
82613 + FALSE if being used in encryption direction. */
82614 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
82615 + (direction depends on the 'decryption' field). */
82616 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
82617 + (direction depends on the 'decryption' field). */
82618 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
82619 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
82620 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
82621 + It is specifies the length of the outer IP header that was configured in the
82622 + corresponding SA. */
82623 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
82624 + The value must be a multiplication of 16 */
82625 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
82626 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
82627 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
82628 +} t_FmPcdManipSpecialOffloadIPSecParams;
82629 +
82630 +#if (DPAA_VERSION >= 11)
82631 +/**************************************************************************//**
82632 + @Description Parameters for configuring CAPWAP fragmentation manipulation
82633 +
82634 + Restrictions:
82635 + - Maximum number of fragments per frame is 16.
82636 + - Transmit confirmation is not supported.
82637 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82638 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82639 + - Only BMan buffers shall be used for frames to be fragmented.
82640 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82641 + does not support VSP. Therefore, on the same port where we have IPF we
82642 + cannot support VSP.
82643 +*//***************************************************************************/
82644 +typedef struct t_FmPcdManipFragCapwapParams {
82645 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82646 + CAPWAP fragmentation will be executed.*/
82647 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82648 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82649 + received frame's buffer. */
82650 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82651 + This parameters is relevant when 'sgBpidEn=TRUE';
82652 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82653 + of this pool need to be allocated in the same memory area as the received buffers.
82654 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82655 + mutual to all these sources. */
82656 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
82657 + When this mode is enabled then only the first fragment include the CAPWAP header options
82658 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
82659 + options field (CAPWAP header is updated accordingly).*/
82660 +} t_FmPcdManipFragCapwapParams;
82661 +
82662 +/**************************************************************************//**
82663 + @Description Parameters for configuring CAPWAP reassembly manipulation.
82664 +
82665 + Restrictions:
82666 + - Application must define one scheme to catch the reassembled frames.
82667 + - Maximum number of fragments per frame is 16.
82668 +
82669 +*//***************************************************************************/
82670 +typedef struct t_FmPcdManipReassemCapwapParams {
82671 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
82672 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
82673 + Rest schemes, if defined, should have higher relative scheme ID. */
82674 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82675 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82676 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
82677 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
82678 + considered as a valid length;
82679 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
82680 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
82681 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
82682 + /**< Number of frames per hash entry needed for reassembly process */
82683 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
82684 + Must be power of 2;
82685 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82686 + maxNumFramesInProcess has to be in the range of 4 - 512;
82687 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82688 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82689 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82690 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82691 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82692 + uint32_t timeoutThresholdForReassmProcess;
82693 + /**< Represents the time interval in microseconds which defines
82694 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82695 +} t_FmPcdManipReassemCapwapParams;
82696 +
82697 +/**************************************************************************//**
82698 + @Description structure for defining CAPWAP manipulation
82699 +*//***************************************************************************/
82700 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
82701 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
82702 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
82703 +} t_FmPcdManipSpecialOffloadCapwapParams;
82704 +
82705 +#endif /* (DPAA_VERSION >= 11) */
82706 +
82707 +
82708 +/**************************************************************************//**
82709 + @Description Parameters for defining special offload manipulation
82710 +*//***************************************************************************/
82711 +typedef struct t_FmPcdManipSpecialOffloadParams {
82712 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
82713 + union
82714 + {
82715 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
82716 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
82717 +#if (DPAA_VERSION >= 11)
82718 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
82719 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
82720 +#endif /* (DPAA_VERSION >= 11) */
82721 + } u;
82722 +} t_FmPcdManipSpecialOffloadParams;
82723 +
82724 +/**************************************************************************//**
82725 + @Description Parameters for defining insertion manipulation
82726 +*//***************************************************************************/
82727 +typedef struct t_FmPcdManipHdrInsrt {
82728 + uint8_t size; /**< size of inserted section */
82729 + uint8_t *p_Data; /**< data to be inserted */
82730 +} t_FmPcdManipHdrInsrt;
82731 +
82732 +
82733 +/**************************************************************************//**
82734 + @Description Parameters for defining generic removal manipulation
82735 +*//***************************************************************************/
82736 +typedef struct t_FmPcdManipHdrRmvGenericParams {
82737 + uint8_t offset; /**< Offset from beginning of header to the start
82738 + location of the removal */
82739 + uint8_t size; /**< Size of removed section */
82740 +} t_FmPcdManipHdrRmvGenericParams;
82741 +
82742 +/**************************************************************************//**
82743 + @Description Parameters for defining generic insertion manipulation
82744 +*//***************************************************************************/
82745 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
82746 + uint8_t offset; /**< Offset from beginning of header to the start
82747 + location of the insertion */
82748 + uint8_t size; /**< Size of inserted section */
82749 + bool replace; /**< TRUE to override (replace) existing data at
82750 + 'offset', FALSE to insert */
82751 + uint8_t *p_Data; /**< Pointer to data to be inserted */
82752 +} t_FmPcdManipHdrInsrtGenericParams;
82753 +
82754 +/**************************************************************************//**
82755 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
82756 +*//***************************************************************************/
82757 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
82758 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
82759 + /**< A table of VPri values for each DSCP value;
82760 + The index is the DSCP value (0-0x3F) and the
82761 + value is the corresponding VPRI (0-15). */
82762 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
82763 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
82764 + this field is the Q Tag default value if the
82765 + IP header is not found. */
82766 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
82767 +
82768 +/**************************************************************************//**
82769 + @Description Parameters for defining header manipulation VLAN fields updates
82770 +*//***************************************************************************/
82771 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
82772 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
82773 + union {
82774 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
82775 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
82776 + is the new VLAN pri. */
82777 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
82778 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
82779 + } u;
82780 +} t_FmPcdManipHdrFieldUpdateVlan;
82781 +
82782 +/**************************************************************************//**
82783 + @Description Parameters for defining header manipulation IPV4 fields updates
82784 +*//***************************************************************************/
82785 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
82786 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82787 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
82788 + HDR_MANIP_IPV4_TOS */
82789 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
82790 + contains HDR_MANIP_IPV4_ID */
82791 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
82792 + contains HDR_MANIP_IPV4_SRC */
82793 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
82794 + contains HDR_MANIP_IPV4_DST */
82795 +} t_FmPcdManipHdrFieldUpdateIpv4;
82796 +
82797 +/**************************************************************************//**
82798 + @Description Parameters for defining header manipulation IPV6 fields updates
82799 +*//***************************************************************************/
82800 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
82801 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82802 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
82803 + HDR_MANIP_IPV6_TC */
82804 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
82805 + /**< 16 byte new IP SRC; Relevant only if validUpdates
82806 + contains HDR_MANIP_IPV6_SRC */
82807 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
82808 + /**< 16 byte new IP DST; Relevant only if validUpdates
82809 + contains HDR_MANIP_IPV6_DST */
82810 +} t_FmPcdManipHdrFieldUpdateIpv6;
82811 +
82812 +/**************************************************************************//**
82813 + @Description Parameters for defining header manipulation TCP/UDP fields updates
82814 +*//***************************************************************************/
82815 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
82816 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
82817 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
82818 + contains HDR_MANIP_TCP_UDP_SRC */
82819 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
82820 + contains HDR_MANIP_TCP_UDP_DST */
82821 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
82822 +
82823 +/**************************************************************************//**
82824 + @Description Parameters for defining header manipulation fields updates
82825 +*//***************************************************************************/
82826 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
82827 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
82828 + union {
82829 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
82830 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
82831 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
82832 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
82833 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
82834 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
82835 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
82836 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
82837 + } u;
82838 +} t_FmPcdManipHdrFieldUpdateParams;
82839 +
82840 +
82841 +
82842 +/**************************************************************************//**
82843 + @Description Parameters for defining custom header manipulation for generic field replacement
82844 +*//***************************************************************************/
82845 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
82846 + uint8_t srcOffset; /**< Location of new data - Offset from
82847 + Parse Result (>= 16, srcOffset+size <= 32, ) */
82848 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
82849 + start of frame (dstOffset + size <= 256). */
82850 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
82851 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
82852 + replacement (1 - bit will be replaced);
82853 + Clear to use field as is. */
82854 + uint8_t maskOffset; /**< Relevant if mask != 0;
82855 + Mask offset within the replaces "size" */
82856 +} t_FmPcdManipHdrCustomGenFieldReplace;
82857 +
82858 +/**************************************************************************//**
82859 + @Description Parameters for defining custom header manipulation for IP replacement
82860 +*//***************************************************************************/
82861 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
82862 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
82863 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
82864 + bool updateIpv4Id; /**< Relevant when replaceType =
82865 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
82866 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
82867 + updateIpv4Id = TRUE */
82868 + uint8_t hdrSize; /**< The size of the new IP header */
82869 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
82870 + /**< The new IP header */
82871 +} t_FmPcdManipHdrCustomIpHdrReplace;
82872 +
82873 +/**************************************************************************//**
82874 + @Description Parameters for defining custom header manipulation
82875 +*//***************************************************************************/
82876 +typedef struct t_FmPcdManipHdrCustomParams {
82877 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
82878 + union {
82879 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
82880 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
82881 + } u;
82882 +} t_FmPcdManipHdrCustomParams;
82883 +
82884 +/**************************************************************************//**
82885 + @Description Parameters for defining specific L2 insertion manipulation
82886 +*//***************************************************************************/
82887 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
82888 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
82889 + bool update; /**< TRUE to update MPLS header */
82890 + uint8_t size; /**< size of inserted section */
82891 + uint8_t *p_Data; /**< data to be inserted */
82892 +} t_FmPcdManipHdrInsrtSpecificL2Params;
82893 +
82894 +#if (DPAA_VERSION >= 11)
82895 +/**************************************************************************//**
82896 + @Description Parameters for defining IP insertion manipulation
82897 +*//***************************************************************************/
82898 +typedef struct t_FmPcdManipHdrInsrtIpParams {
82899 + bool calcL4Checksum; /**< Calculate L4 checksum. */
82900 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
82901 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
82902 + the inserted header */
82903 + uint16_t id; /**< 16 bit New IP ID */
82904 + bool dontFragOverwrite;
82905 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
82906 + * This byte is configured to be overwritten when RPD is set. */
82907 + uint8_t lastDstOffset;
82908 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
82909 + * in order to calculate UDP checksum pseudo header;
82910 + * Otherwise set it to '0'. */
82911 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
82912 +} t_FmPcdManipHdrInsrtIpParams;
82913 +#endif /* (DPAA_VERSION >= 11) */
82914 +
82915 +/**************************************************************************//**
82916 + @Description Parameters for defining header insertion manipulation by header type
82917 +*//***************************************************************************/
82918 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
82919 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
82920 + union {
82921 +
82922 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
82923 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
82924 + Selects which L2 headers to insert */
82925 +#if (DPAA_VERSION >= 11)
82926 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
82927 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
82928 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
82929 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
82930 +#endif /* (DPAA_VERSION >= 11) */
82931 + } u;
82932 +} t_FmPcdManipHdrInsrtByHdrParams;
82933 +
82934 +/**************************************************************************//**
82935 + @Description Parameters for defining header insertion manipulation
82936 +*//***************************************************************************/
82937 +typedef struct t_FmPcdManipHdrInsrtParams {
82938 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
82939 + union {
82940 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
82941 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
82942 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
82943 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
82944 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82945 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
82946 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
82947 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82948 + } u;
82949 +} t_FmPcdManipHdrInsrtParams;
82950 +
82951 +/**************************************************************************//**
82952 + @Description Parameters for defining header removal manipulation
82953 +*//***************************************************************************/
82954 +typedef struct t_FmPcdManipHdrRmvParams {
82955 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
82956 + union {
82957 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
82958 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
82959 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
82960 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
82961 + } u;
82962 +} t_FmPcdManipHdrRmvParams;
82963 +
82964 +/**************************************************************************//**
82965 + @Description Parameters for defining header manipulation node
82966 +*//***************************************************************************/
82967 +typedef struct t_FmPcdManipHdrParams {
82968 + bool rmv; /**< TRUE, to define removal manipulation */
82969 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
82970 +
82971 + bool insrt; /**< TRUE, to define insertion manipulation */
82972 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
82973 +
82974 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
82975 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
82976 +
82977 + bool custom; /**< TRUE, to define custom manipulation */
82978 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
82979 +
82980 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
82981 + Restrictions:
82982 + 1. MUST be set if the next engine after the CC is not another CC node
82983 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
82984 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
82985 + also never pointed as h_NextManip of other manipulation nodes)
82986 + 2. MUST be set if the next engine after the CC is another CC node, and
82987 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
82988 +} t_FmPcdManipHdrParams;
82989 +
82990 +/**************************************************************************//**
82991 + @Description Parameters for defining fragmentation manipulation
82992 +*//***************************************************************************/
82993 +typedef struct t_FmPcdManipFragParams {
82994 + e_NetHeaderType hdr; /**< Header selection */
82995 + union {
82996 +#if (DPAA_VERSION >= 11)
82997 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
82998 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
82999 +#endif /* (DPAA_VERSION >= 11) */
83000 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
83001 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83002 + } u;
83003 +} t_FmPcdManipFragParams;
83004 +
83005 +/**************************************************************************//**
83006 + @Description Parameters for defining reassembly manipulation
83007 +*//***************************************************************************/
83008 +typedef struct t_FmPcdManipReassemParams {
83009 + e_NetHeaderType hdr; /**< Header selection */
83010 + union {
83011 +#if (DPAA_VERSION >= 11)
83012 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
83013 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83014 +#endif /* (DPAA_VERSION >= 11) */
83015 +
83016 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
83017 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83018 + } u;
83019 +} t_FmPcdManipReassemParams;
83020 +
83021 +/**************************************************************************//**
83022 + @Description Parameters for defining a manipulation node
83023 +*//***************************************************************************/
83024 +typedef struct t_FmPcdManipParams {
83025 + e_FmPcdManipType type; /**< Selects type of manipulation node */
83026 + union{
83027 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
83028 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
83029 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
83030 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
83031 + } u;
83032 +
83033 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
83034 + Handle to another (previously defined) manipulation node;
83035 + Allows concatenation of manipulation actions;
83036 + This parameter is optional and may be NULL. */
83037 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83038 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
83039 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
83040 + relevant if fragOrReasm = TRUE */
83041 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83042 +} t_FmPcdManipParams;
83043 +
83044 +/**************************************************************************//**
83045 + @Description Structure for retrieving IP reassembly statistics
83046 +*//***************************************************************************/
83047 +typedef struct t_FmPcdManipReassemIpStats {
83048 + /* common counters for both IPv4 and IPv6 */
83049 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83050 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83051 + a Reassembly Frame Descriptor */
83052 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83053 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83054 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83055 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83056 +#if (DPAA_VERSION >= 11)
83057 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
83058 + successfully reassembled frames */
83059 +#endif /* (DPAA_VERSION >= 11) */
83060 + struct {
83061 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83062 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83063 + have been processed for all frames */
83064 + uint32_t processedFragments; /**< Counts the number of processed fragments
83065 + (valid and error fragments) for all frames */
83066 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83067 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83068 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83069 + to access an IP-Reassembly Automatic Learning Hash set */
83070 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83071 + exceeds 16 */
83072 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
83073 +} t_FmPcdManipReassemIpStats;
83074 +
83075 +/**************************************************************************//**
83076 + @Description Structure for retrieving IP fragmentation statistics
83077 +*//***************************************************************************/
83078 +typedef struct t_FmPcdManipFragIpStats {
83079 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83080 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83081 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83082 +} t_FmPcdManipFragIpStats;
83083 +
83084 +#if (DPAA_VERSION >= 11)
83085 +/**************************************************************************//**
83086 + @Description Structure for retrieving CAPWAP reassembly statistics
83087 +*//***************************************************************************/
83088 +typedef struct t_FmPcdManipReassemCapwapStats {
83089 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83090 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83091 + a Reassembly Frame Descriptor */
83092 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83093 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83094 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83095 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83096 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83097 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83098 + have been processed for all frames */
83099 + uint32_t processedFragments; /**< Counts the number of processed fragments
83100 + (valid and error fragments) for all frames */
83101 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83102 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83103 + to access an Reassembly Automatic Learning Hash set */
83104 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83105 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83106 + exceeds 16 */
83107 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
83108 + length exceeds MaxReassembledFrameLength value */
83109 +} t_FmPcdManipReassemCapwapStats;
83110 +
83111 +/**************************************************************************//**
83112 + @Description Structure for retrieving CAPWAP fragmentation statistics
83113 +*//***************************************************************************/
83114 +typedef struct t_FmPcdManipFragCapwapStats {
83115 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83116 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83117 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83118 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83119 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
83120 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
83121 +} t_FmPcdManipFragCapwapStats;
83122 +#endif /* (DPAA_VERSION >= 11) */
83123 +
83124 +/**************************************************************************//**
83125 + @Description Structure for retrieving reassembly statistics
83126 +*//***************************************************************************/
83127 +typedef struct t_FmPcdManipReassemStats {
83128 + union {
83129 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
83130 +#if (DPAA_VERSION >= 11)
83131 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
83132 +#endif /* (DPAA_VERSION >= 11) */
83133 + } u;
83134 +} t_FmPcdManipReassemStats;
83135 +
83136 +/**************************************************************************//**
83137 + @Description Structure for retrieving fragmentation statistics
83138 +*//***************************************************************************/
83139 +typedef struct t_FmPcdManipFragStats {
83140 + union {
83141 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
83142 +#if (DPAA_VERSION >= 11)
83143 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
83144 +#endif /* (DPAA_VERSION >= 11) */
83145 + } u;
83146 +} t_FmPcdManipFragStats;
83147 +
83148 +/**************************************************************************//**
83149 + @Description Structure for selecting manipulation statistics
83150 +*//***************************************************************************/
83151 +typedef struct t_FmPcdManipStats {
83152 + union {
83153 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
83154 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
83155 + } u;
83156 +} t_FmPcdManipStats;
83157 +
83158 +#if (DPAA_VERSION >= 11)
83159 +/**************************************************************************//**
83160 + @Description Parameters for defining frame replicator group and its members
83161 +*//***************************************************************************/
83162 +typedef struct t_FmPcdFrmReplicGroupParams {
83163 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
83164 + Must be at least 2. */
83165 + uint8_t numOfEntries; /**< Number of members in the group;
83166 + Must be at least 1. */
83167 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
83168 + /**< Array of members' parameters */
83169 +} t_FmPcdFrmReplicGroupParams;
83170 +#endif /* (DPAA_VERSION >= 11) */
83171 +
83172 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83173 +/**************************************************************************//**
83174 + @Description structure for defining statistics node
83175 +*//***************************************************************************/
83176 +typedef struct t_FmPcdStatsParams {
83177 + e_FmPcdStatsType type; /**< type of statistics node */
83178 +} t_FmPcdStatsParams;
83179 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83180 +
83181 +/**************************************************************************//**
83182 + @Function FM_PCD_NetEnvCharacteristicsSet
83183 +
83184 + @Description Define a set of Network Environment Characteristics.
83185 +
83186 + When setting an environment it is important to understand its
83187 + application. It is not meant to describe the flows that will run
83188 + on the ports using this environment, but what the user means TO DO
83189 + with the PCD mechanisms in order to parse-classify-distribute those
83190 + frames.
83191 + By specifying a distinction unit, the user means it would use that option
83192 + for distinction between frames at either a KeyGen scheme or a coarse
83193 + classification action descriptor. Using interchangeable headers to define a
83194 + unit means that the user is indifferent to which of the interchangeable
83195 + headers is present in the frame, and wants the distinction to be based
83196 + on the presence of either one of them.
83197 +
83198 + Depending on context, there are limitations to the use of environments. A
83199 + port using the PCD functionality is bound to an environment. Some or even
83200 + all ports may share an environment but also an environment per port is
83201 + possible. When initializing a scheme, a classification plan group (see below),
83202 + or a coarse classification tree, one of the initialized environments must be
83203 + stated and related to. When a port is bound to a scheme, a classification
83204 + plan group, or a coarse classification tree, it MUST be bound to the same
83205 + environment.
83206 +
83207 + The different PCD modules, may relate (for flows definition) ONLY on
83208 + distinction units as defined by their environment. When initializing a
83209 + scheme for example, it may not choose to select IPV4 as a match for
83210 + recognizing flows unless it was defined in the relating environment. In
83211 + fact, to guide the user through the configuration of the PCD, each module's
83212 + characterization in terms of flows is not done using protocol names, but using
83213 + environment indexes.
83214 +
83215 + In terms of HW implementation, the list of distinction units sets the LCV vectors
83216 + and later used for match vector, classification plan vectors and coarse classification
83217 + indexing.
83218 +
83219 + @Param[in] h_FmPcd FM PCD module descriptor.
83220 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
83221 + the network environment.
83222 +
83223 + @Return A handle to the initialized object on success; NULL code otherwise.
83224 +
83225 + @Cautions Allowed only following FM_PCD_Init().
83226 +*//***************************************************************************/
83227 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
83228 +
83229 +/**************************************************************************//**
83230 + @Function FM_PCD_NetEnvCharacteristicsDelete
83231 +
83232 + @Description Deletes a set of Network Environment Characteristics.
83233 +
83234 + @Param[in] h_NetEnv A handle to the Network environment.
83235 +
83236 + @Return E_OK on success; Error code otherwise.
83237 +*//***************************************************************************/
83238 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
83239 +
83240 +/**************************************************************************//**
83241 + @Function FM_PCD_KgSchemeSet
83242 +
83243 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
83244 + This routine should be called for adding or modifying a scheme.
83245 + When a scheme needs modifying, the API requires that it will be
83246 + rewritten. In such a case 'modify' should be TRUE. If the
83247 + routine is called for a valid scheme and 'modify' is FALSE,
83248 + it will return error.
83249 +
83250 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
83251 + Otherwise NULL (ignored by driver).
83252 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
83253 +
83254 + @Return A handle to the initialized scheme on success; NULL code otherwise.
83255 + When used as "modify" (rather than for setting a new scheme),
83256 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
83257 + BUSY state.
83258 +
83259 + @Cautions Allowed only following FM_PCD_Init().
83260 +*//***************************************************************************/
83261 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
83262 + t_FmPcdKgSchemeParams *p_SchemeParams);
83263 +
83264 +/**************************************************************************//**
83265 + @Function FM_PCD_KgSchemeDelete
83266 +
83267 + @Description Deleting an initialized scheme.
83268 +
83269 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
83270 +
83271 + @Return E_OK on success; Error code otherwise.
83272 +
83273 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83274 +*//***************************************************************************/
83275 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
83276 +
83277 +/**************************************************************************//**
83278 + @Function FM_PCD_KgSchemeGetCounter
83279 +
83280 + @Description Reads scheme packet counter.
83281 +
83282 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83283 +
83284 + @Return Counter's current value.
83285 +
83286 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83287 +*//***************************************************************************/
83288 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
83289 +
83290 +/**************************************************************************//**
83291 + @Function FM_PCD_KgSchemeSetCounter
83292 +
83293 + @Description Writes scheme packet counter.
83294 +
83295 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83296 + @Param[in] value New scheme counter value - typically '0' for
83297 + resetting the counter.
83298 +
83299 + @Return E_OK on success; Error code otherwise.
83300 +
83301 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83302 +*//***************************************************************************/
83303 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
83304 +
83305 +/**************************************************************************//**
83306 + @Function FM_PCD_PlcrProfileSet
83307 +
83308 + @Description Sets a profile entry in the policer profile table.
83309 + The routine overrides any existing value.
83310 +
83311 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83312 + @Param[in] p_Profile A structure of parameters for defining a
83313 + policer profile entry.
83314 +
83315 + @Return A handle to the initialized object on success; NULL code otherwise.
83316 + When used as "modify" (rather than for setting a new profile),
83317 + p_Profile->id.h_Profile will return NULL if action fails due to profile
83318 + BUSY state.
83319 + @Cautions Allowed only following FM_PCD_Init().
83320 +*//***************************************************************************/
83321 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
83322 + t_FmPcdPlcrProfileParams *p_Profile);
83323 +
83324 +/**************************************************************************//**
83325 + @Function FM_PCD_PlcrProfileDelete
83326 +
83327 + @Description Delete a profile entry in the policer profile table.
83328 + The routine set entry to invalid.
83329 +
83330 + @Param[in] h_Profile A handle to the profile.
83331 +
83332 + @Return E_OK on success; Error code otherwise.
83333 +
83334 + @Cautions Allowed only following FM_PCD_Init().
83335 +*//***************************************************************************/
83336 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
83337 +
83338 +/**************************************************************************//**
83339 + @Function FM_PCD_PlcrProfileGetCounter
83340 +
83341 + @Description Sets an entry in the classification plan.
83342 + The routine overrides any existing value.
83343 +
83344 + @Param[in] h_Profile A handle to the profile.
83345 + @Param[in] counter Counter selector.
83346 +
83347 + @Return specific counter value.
83348 +
83349 + @Cautions Allowed only following FM_PCD_Init().
83350 +*//***************************************************************************/
83351 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
83352 + e_FmPcdPlcrProfileCounters counter);
83353 +
83354 +/**************************************************************************//**
83355 + @Function FM_PCD_PlcrProfileSetCounter
83356 +
83357 + @Description Sets an entry in the classification plan.
83358 + The routine overrides any existing value.
83359 +
83360 + @Param[in] h_Profile A handle to the profile.
83361 + @Param[in] counter Counter selector.
83362 + @Param[in] value value to set counter with.
83363 +
83364 + @Return E_OK on success; Error code otherwise.
83365 +
83366 + @Cautions Allowed only following FM_PCD_Init().
83367 +*//***************************************************************************/
83368 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
83369 + e_FmPcdPlcrProfileCounters counter,
83370 + uint32_t value);
83371 +
83372 +/**************************************************************************//**
83373 + @Function FM_PCD_CcRootBuild
83374 +
83375 + @Description This routine must be called to define a complete coarse
83376 + classification tree. This is the way to define coarse
83377 + classification to a certain flow - the KeyGen schemes
83378 + may point only to trees defined in this way.
83379 +
83380 + @Param[in] h_FmPcd FM PCD module descriptor.
83381 + @Param[in] p_Params A structure of parameters to define the tree.
83382 +
83383 + @Return A handle to the initialized object on success; NULL code otherwise.
83384 +
83385 + @Cautions Allowed only following FM_PCD_Init().
83386 +*//***************************************************************************/
83387 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
83388 + t_FmPcdCcTreeParams *p_Params);
83389 +
83390 +/**************************************************************************//**
83391 + @Function FM_PCD_CcRootDelete
83392 +
83393 + @Description Deleting an built tree.
83394 +
83395 + @Param[in] h_CcTree A handle to a CC tree.
83396 +
83397 + @Return E_OK on success; Error code otherwise.
83398 +
83399 + @Cautions Allowed only following FM_PCD_Init().
83400 +*//***************************************************************************/
83401 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
83402 +
83403 +/**************************************************************************//**
83404 + @Function FM_PCD_CcRootModifyNextEngine
83405 +
83406 + @Description Modify the Next Engine Parameters in the entry of the tree.
83407 +
83408 + @Param[in] h_CcTree A handle to the tree
83409 + @Param[in] grpId A Group index in the tree
83410 + @Param[in] index Entry index in the group defined by grpId
83411 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
83412 +
83413 + @Return E_OK on success; Error code otherwise.
83414 +
83415 + @Cautions Allowed only following FM_PCD_CcBuildTree().
83416 +*//***************************************************************************/
83417 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
83418 + uint8_t grpId,
83419 + uint8_t index,
83420 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83421 +
83422 +/**************************************************************************//**
83423 + @Function FM_PCD_MatchTableSet
83424 +
83425 + @Description This routine should be called for each CC (coarse classification)
83426 + node. The whole CC tree should be built bottom up so that each
83427 + node points to already defined nodes.
83428 +
83429 + @Param[in] h_FmPcd FM PCD module descriptor.
83430 + @Param[in] p_Param A structure of parameters defining the CC node
83431 +
83432 + @Return A handle to the initialized object on success; NULL code otherwise.
83433 +
83434 + @Cautions Allowed only following FM_PCD_Init().
83435 +*//***************************************************************************/
83436 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
83437 +
83438 +/**************************************************************************//**
83439 + @Function FM_PCD_MatchTableDelete
83440 +
83441 + @Description Deleting an built node.
83442 +
83443 + @Param[in] h_CcNode A handle to a CC node.
83444 +
83445 + @Return E_OK on success; Error code otherwise.
83446 +
83447 + @Cautions Allowed only following FM_PCD_Init().
83448 +*//***************************************************************************/
83449 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
83450 +
83451 +/**************************************************************************//**
83452 + @Function FM_PCD_MatchTableModifyMissNextEngine
83453 +
83454 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
83455 +
83456 + @Param[in] h_CcNode A handle to the node
83457 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83458 +
83459 + @Return E_OK on success; Error code otherwise.
83460 +
83461 + @Cautions Allowed only following FM_PCD_MatchTableSet();
83462 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
83463 + When configuring nextEngine = e_FM_PCD_CC, note that
83464 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83465 + from the currently changed table.
83466 +
83467 +*//***************************************************************************/
83468 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
83469 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83470 +
83471 +/**************************************************************************//**
83472 + @Function FM_PCD_MatchTableRemoveKey
83473 +
83474 + @Description Remove the key (including next engine parameters of this key)
83475 + defined by the index of the relevant node.
83476 +
83477 + @Param[in] h_CcNode A handle to the node
83478 + @Param[in] keyIndex Key index for removing
83479 +
83480 + @Return E_OK on success; Error code otherwise.
83481 +
83482 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83483 + node and the nodes that lead to it.
83484 +*//***************************************************************************/
83485 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
83486 +
83487 +/**************************************************************************//**
83488 + @Function FM_PCD_MatchTableAddKey
83489 +
83490 + @Description Add the key (including next engine parameters of this key in the
83491 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
83492 + may be used by user that don't care about the position of the
83493 + key in the table - in that case, the key will be automatically
83494 + added by the driver in the last available entry.
83495 +
83496 + @Param[in] h_CcNode A handle to the node
83497 + @Param[in] keyIndex Key index for adding.
83498 + @Param[in] keySize Key size of added key
83499 + @Param[in] p_KeyParams A pointer to the parameters includes
83500 + new key with Next Engine Parameters
83501 +
83502 + @Return E_OK on success; Error code otherwise.
83503 +
83504 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83505 + node and the nodes that lead to it.
83506 +*//***************************************************************************/
83507 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
83508 + uint16_t keyIndex,
83509 + uint8_t keySize,
83510 + t_FmPcdCcKeyParams *p_KeyParams);
83511 +
83512 +/**************************************************************************//**
83513 + @Function FM_PCD_MatchTableModifyNextEngine
83514 +
83515 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
83516 +
83517 + @Param[in] h_CcNode A handle to the node
83518 + @Param[in] keyIndex Key index for Next Engine modifications
83519 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83520 +
83521 + @Return E_OK on success; Error code otherwise.
83522 +
83523 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83524 + When configuring nextEngine = e_FM_PCD_CC, note that
83525 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83526 + from the currently changed table.
83527 +
83528 +*//***************************************************************************/
83529 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
83530 + uint16_t keyIndex,
83531 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83532 +
83533 +/**************************************************************************//**
83534 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
83535 +
83536 + @Description Modify the key and Next Engine Parameters of this key in the
83537 + index defined by the keyIndex.
83538 +
83539 + @Param[in] h_CcNode A handle to the node
83540 + @Param[in] keyIndex Key index for adding
83541 + @Param[in] keySize Key size of added key
83542 + @Param[in] p_KeyParams A pointer to the parameters includes
83543 + modified key and modified Next Engine Parameters
83544 +
83545 + @Return E_OK on success; Error code otherwise.
83546 +
83547 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83548 + node and the nodes that lead to it.
83549 + When configuring nextEngine = e_FM_PCD_CC, note that
83550 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83551 + from the currently changed table.
83552 +*//***************************************************************************/
83553 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
83554 + uint16_t keyIndex,
83555 + uint8_t keySize,
83556 + t_FmPcdCcKeyParams *p_KeyParams);
83557 +
83558 +/**************************************************************************//**
83559 + @Function FM_PCD_MatchTableModifyKey
83560 +
83561 + @Description Modify the key in the index defined by the keyIndex.
83562 +
83563 + @Param[in] h_CcNode A handle to the node
83564 + @Param[in] keyIndex Key index for adding
83565 + @Param[in] keySize Key size of added key
83566 + @Param[in] p_Key A pointer to the new key
83567 + @Param[in] p_Mask A pointer to the new mask if relevant,
83568 + otherwise pointer to NULL
83569 +
83570 + @Return E_OK on success; Error code otherwise.
83571 +
83572 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83573 + node and the nodes that lead to it.
83574 +*//***************************************************************************/
83575 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
83576 + uint16_t keyIndex,
83577 + uint8_t keySize,
83578 + uint8_t *p_Key,
83579 + uint8_t *p_Mask);
83580 +
83581 +/**************************************************************************//**
83582 + @Function FM_PCD_MatchTableFindNRemoveKey
83583 +
83584 + @Description Remove the key (including next engine parameters of this key)
83585 + defined by the key and mask. Note that this routine will search
83586 + the node to locate the index of the required key (& mask) to remove.
83587 +
83588 + @Param[in] h_CcNode A handle to the node
83589 + @Param[in] keySize Key size of the one to remove.
83590 + @Param[in] p_Key A pointer to the requested key to remove.
83591 + @Param[in] p_Mask A pointer to the mask if relevant,
83592 + otherwise pointer to NULL
83593 +
83594 + @Return E_OK on success; Error code otherwise.
83595 +
83596 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83597 + node and the nodes that lead to it.
83598 +*//***************************************************************************/
83599 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
83600 + uint8_t keySize,
83601 + uint8_t *p_Key,
83602 + uint8_t *p_Mask);
83603 +
83604 +/**************************************************************************//**
83605 + @Function FM_PCD_MatchTableFindNModifyNextEngine
83606 +
83607 + @Description Modify the Next Engine Parameters in the relevant key entry of
83608 + the node. Note that this routine will search the node to locate
83609 + the index of the required key (& mask) to modify.
83610 +
83611 + @Param[in] h_CcNode A handle to the node
83612 + @Param[in] keySize Key size of the one to modify.
83613 + @Param[in] p_Key A pointer to the requested key to modify.
83614 + @Param[in] p_Mask A pointer to the mask if relevant,
83615 + otherwise pointer to NULL
83616 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83617 +
83618 + @Return E_OK on success; Error code otherwise.
83619 +
83620 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83621 + When configuring nextEngine = e_FM_PCD_CC, note that
83622 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83623 + from the currently changed table.
83624 +*//***************************************************************************/
83625 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
83626 + uint8_t keySize,
83627 + uint8_t *p_Key,
83628 + uint8_t *p_Mask,
83629 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83630 +
83631 +/**************************************************************************//**
83632 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
83633 +
83634 + @Description Modify the key and Next Engine Parameters of this key in the
83635 + index defined by the keyIndex. Note that this routine will search
83636 + the node to locate the index of the required key (& mask) to modify.
83637 +
83638 + @Param[in] h_CcNode A handle to the node
83639 + @Param[in] keySize Key size of the one to modify.
83640 + @Param[in] p_Key A pointer to the requested key to modify.
83641 + @Param[in] p_Mask A pointer to the mask if relevant,
83642 + otherwise pointer to NULL
83643 + @Param[in] p_KeyParams A pointer to the parameters includes
83644 + modified key and modified Next Engine Parameters
83645 +
83646 + @Return E_OK on success; Error code otherwise.
83647 +
83648 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83649 + node and the nodes that lead to it.
83650 + When configuring nextEngine = e_FM_PCD_CC, note that
83651 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83652 + from the currently changed table.
83653 +*//***************************************************************************/
83654 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
83655 + uint8_t keySize,
83656 + uint8_t *p_Key,
83657 + uint8_t *p_Mask,
83658 + t_FmPcdCcKeyParams *p_KeyParams);
83659 +
83660 +/**************************************************************************//**
83661 + @Function FM_PCD_MatchTableFindNModifyKey
83662 +
83663 + @Description Modify the key in the index defined by the keyIndex. Note that
83664 + this routine will search the node to locate the index of the
83665 + required key (& mask) to modify.
83666 +
83667 + @Param[in] h_CcNode A handle to the node
83668 + @Param[in] keySize Key size of the one to modify.
83669 + @Param[in] p_Key A pointer to the requested key to modify.
83670 + @Param[in] p_Mask A pointer to the mask if relevant,
83671 + otherwise pointer to NULL
83672 + @Param[in] p_NewKey A pointer to the new key
83673 + @Param[in] p_NewMask A pointer to the new mask if relevant,
83674 + otherwise pointer to NULL
83675 +
83676 + @Return E_OK on success; Error code otherwise.
83677 +
83678 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83679 + node and the nodes that lead to it.
83680 +*//***************************************************************************/
83681 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
83682 + uint8_t keySize,
83683 + uint8_t *p_Key,
83684 + uint8_t *p_Mask,
83685 + uint8_t *p_NewKey,
83686 + uint8_t *p_NewMask);
83687 +
83688 +/**************************************************************************//**
83689 + @Function FM_PCD_MatchTableGetKeyCounter
83690 +
83691 + @Description This routine may be used to get a counter of specific key in a CC
83692 + Node; This counter reflects how many frames passed that were matched
83693 + this key.
83694 +
83695 + @Param[in] h_CcNode A handle to the node
83696 + @Param[in] keyIndex Key index for adding
83697 +
83698 + @Return The specific key counter.
83699 +
83700 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83701 +*//***************************************************************************/
83702 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
83703 +
83704 +/**************************************************************************//**
83705 + @Function FM_PCD_MatchTableGetKeyStatistics
83706 +
83707 + @Description This routine may be used to get statistics counters of specific key
83708 + in a CC Node.
83709 +
83710 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83711 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83712 + these counters reflect how many frames passed that were matched
83713 + this key; The total frames count will be returned in the counter
83714 + of the first range (as only one frame length range was defined).
83715 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83716 + frame count will be separated to frame length counters, based on
83717 + provided frame length ranges.
83718 +
83719 + @Param[in] h_CcNode A handle to the node
83720 + @Param[in] keyIndex Key index for adding
83721 + @Param[out] p_KeyStatistics Key statistics counters
83722 +
83723 + @Return The specific key statistics.
83724 +
83725 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83726 +*//***************************************************************************/
83727 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
83728 + uint16_t keyIndex,
83729 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
83730 +
83731 +/**************************************************************************//**
83732 + @Function FM_PCD_MatchTableGetMissStatistics
83733 +
83734 + @Description This routine may be used to get statistics counters of miss entry
83735 + in a CC Node.
83736 +
83737 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83738 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83739 + these counters reflect how many frames were not matched to any
83740 + existing key and therefore passed through the miss entry; The
83741 + total frames count will be returned in the counter of the
83742 + first range (as only one frame length range was defined).
83743 +
83744 + @Param[in] h_CcNode A handle to the node
83745 + @Param[out] p_MissStatistics Statistics counters for 'miss'
83746 +
83747 + @Return The statistics for 'miss'.
83748 +
83749 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83750 +*//***************************************************************************/
83751 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
83752 + t_FmPcdCcKeyStatistics *p_MissStatistics);
83753 +
83754 +/**************************************************************************//**
83755 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
83756 +
83757 + @Description This routine may be used to get statistics counters of specific key
83758 + in a CC Node.
83759 +
83760 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83761 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83762 + these counters reflect how many frames passed that were matched
83763 + this key; The total frames count will be returned in the counter
83764 + of the first range (as only one frame length range was defined).
83765 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83766 + frame count will be separated to frame length counters, based on
83767 + provided frame length ranges.
83768 + Note that this routine will search the node to locate the index
83769 + of the required key based on received key parameters.
83770 +
83771 + @Param[in] h_CcNode A handle to the node
83772 + @Param[in] keySize Size of the requested key
83773 + @Param[in] p_Key A pointer to the requested key
83774 + @Param[in] p_Mask A pointer to the mask if relevant,
83775 + otherwise pointer to NULL
83776 + @Param[out] p_KeyStatistics Key statistics counters
83777 +
83778 + @Return The specific key statistics.
83779 +
83780 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83781 +*//***************************************************************************/
83782 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
83783 + uint8_t keySize,
83784 + uint8_t *p_Key,
83785 + uint8_t *p_Mask,
83786 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
83787 +
83788 +/**************************************************************************//*
83789 + @Function FM_PCD_MatchTableGetNextEngine
83790 +
83791 + @Description Gets NextEngine of the relevant keyIndex.
83792 +
83793 + @Param[in] h_CcNode A handle to the node.
83794 + @Param[in] keyIndex keyIndex in the relevant node.
83795 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
83796 + the relevant keyIndex of the CC Node
83797 + received as parameter to this function
83798 +
83799 + @Return E_OK on success; Error code otherwise.
83800 +
83801 + @Cautions Allowed only following FM_PCD_Init().
83802 +*//***************************************************************************/
83803 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
83804 + uint16_t keyIndex,
83805 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83806 +
83807 +/**************************************************************************//*
83808 + @Function FM_PCD_MatchTableGetIndexedHashBucket
83809 +
83810 + @Description This routine simulates KeyGen operation on the provided key and
83811 + calculates to which hash bucket it will be mapped.
83812 +
83813 + @Param[in] h_CcNode A handle to the node.
83814 + @Param[in] kgKeySize Key size as it was configured in the KG
83815 + scheme that leads to this hash.
83816 + @Param[in] p_KgKey Pointer to the key; must be like the key
83817 + that the KG is generated, i.e. the same
83818 + extraction and with mask if exist.
83819 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
83820 + scheme that leads to this hash.
83821 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
83822 + @Param[out] p_BucketIndex Index to the bucket of the provided key
83823 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
83824 + provided key.
83825 +
83826 + @Return E_OK on success; Error code otherwise.
83827 +
83828 + @Cautions Allowed only following FM_PCD_HashTableSet()
83829 +*//***************************************************************************/
83830 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
83831 + uint8_t kgKeySize,
83832 + uint8_t *p_KgKey,
83833 + uint8_t kgHashShift,
83834 + t_Handle *p_CcNodeBucketHandle,
83835 + uint8_t *p_BucketIndex,
83836 + uint16_t *p_LastIndex);
83837 +
83838 +/**************************************************************************//**
83839 + @Function FM_PCD_HashTableSet
83840 +
83841 + @Description This routine initializes a hash table structure.
83842 + KeyGen hash result determines the hash bucket.
83843 + Next, KeyGen key is compared against all keys of this
83844 + bucket (exact match).
83845 + Number of sets (number of buckets) of the hash equals to the
83846 + number of 1-s in 'hashResMask' in the provided parameters.
83847 + Number of hash table ways is then calculated by dividing
83848 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
83849 + number of keys that a hash bucket may hold.
83850 + The hash table is initialized empty and keys may be
83851 + added to it following the initialization. Keys masks are not
83852 + supported in current hash table implementation.
83853 + The initialized hash table can be integrated as a node in a
83854 + CC tree.
83855 +
83856 + @Param[in] h_FmPcd FM PCD module descriptor.
83857 + @Param[in] p_Param A structure of parameters defining the hash table
83858 +
83859 + @Return A handle to the initialized object on success; NULL code otherwise.
83860 +
83861 + @Cautions Allowed only following FM_PCD_Init().
83862 +*//***************************************************************************/
83863 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
83864 +
83865 +/**************************************************************************//**
83866 + @Function FM_PCD_HashTableDelete
83867 +
83868 + @Description This routine deletes the provided hash table and released all
83869 + its allocated resources.
83870 +
83871 + @Param[in] h_HashTbl A handle to a hash table
83872 +
83873 + @Return E_OK on success; Error code otherwise.
83874 +
83875 + @Cautions Allowed only following FM_PCD_HashTableSet().
83876 +*//***************************************************************************/
83877 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
83878 +
83879 +/**************************************************************************//**
83880 + @Function FM_PCD_HashTableAddKey
83881 +
83882 + @Description This routine adds the provided key (including next engine
83883 + parameters of this key) to the hash table.
83884 + The key is added as the last key of the bucket that it is
83885 + mapped to.
83886 +
83887 + @Param[in] h_HashTbl A handle to a hash table
83888 + @Param[in] keySize Key size of added key
83889 + @Param[in] p_KeyParams A pointer to the parameters includes
83890 + new key with next engine parameters; The pointer
83891 + to the key mask must be NULL, as masks are not
83892 + supported in hash table implementation.
83893 +
83894 + @Return E_OK on success; Error code otherwise.
83895 +
83896 + @Cautions Allowed only following FM_PCD_HashTableSet().
83897 +*//***************************************************************************/
83898 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
83899 + uint8_t keySize,
83900 + t_FmPcdCcKeyParams *p_KeyParams);
83901 +
83902 +/**************************************************************************//**
83903 + @Function FM_PCD_HashTableRemoveKey
83904 +
83905 + @Description This routine removes the requested key (including next engine
83906 + parameters of this key) from the hash table.
83907 +
83908 + @Param[in] h_HashTbl A handle to a hash table
83909 + @Param[in] keySize Key size of the one to remove.
83910 + @Param[in] p_Key A pointer to the requested key to remove.
83911 +
83912 + @Return E_OK on success; Error code otherwise.
83913 +
83914 + @Cautions Allowed only following FM_PCD_HashTableSet().
83915 +*//***************************************************************************/
83916 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
83917 + uint8_t keySize,
83918 + uint8_t *p_Key);
83919 +
83920 +/**************************************************************************//**
83921 + @Function FM_PCD_HashTableModifyNextEngine
83922 +
83923 + @Description This routine modifies the next engine for the provided key. The
83924 + key should be previously added to the hash table.
83925 +
83926 + @Param[in] h_HashTbl A handle to a hash table
83927 + @Param[in] keySize Key size of the key to modify.
83928 + @Param[in] p_Key A pointer to the requested key to modify.
83929 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
83930 + parameters.
83931 +
83932 + @Return E_OK on success; Error code otherwise.
83933 +
83934 + @Cautions Allowed only following FM_PCD_HashTableSet().
83935 + When configuring nextEngine = e_FM_PCD_CC, note that
83936 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83937 + from the currently changed table.
83938 +*//***************************************************************************/
83939 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
83940 + uint8_t keySize,
83941 + uint8_t *p_Key,
83942 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83943 +
83944 +/**************************************************************************//**
83945 + @Function FM_PCD_HashTableModifyMissNextEngine
83946 +
83947 + @Description This routine modifies the next engine on key match miss.
83948 +
83949 + @Param[in] h_HashTbl A handle to a hash table
83950 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
83951 + parameters.
83952 +
83953 + @Return E_OK on success; Error code otherwise.
83954 +
83955 + @Cautions Allowed only following FM_PCD_HashTableSet().
83956 + When configuring nextEngine = e_FM_PCD_CC, note that
83957 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83958 + from the currently changed table.
83959 +*//***************************************************************************/
83960 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
83961 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83962 +
83963 +/**************************************************************************//*
83964 + @Function FM_PCD_HashTableGetMissNextEngine
83965 +
83966 + @Description Gets NextEngine in case of key match miss.
83967 +
83968 + @Param[in] h_HashTbl A handle to a hash table
83969 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
83970 + hash table.
83971 +
83972 + @Return E_OK on success; Error code otherwise.
83973 +
83974 + @Cautions Allowed only following FM_PCD_HashTableSet().
83975 +*//***************************************************************************/
83976 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
83977 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83978 +
83979 +/**************************************************************************//**
83980 + @Function FM_PCD_HashTableFindNGetKeyStatistics
83981 +
83982 + @Description This routine may be used to get statistics counters of specific key
83983 + in a hash table.
83984 +
83985 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
83986 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
83987 + these counters reflect how many frames passed that were matched
83988 + this key; The total frames count will be returned in the counter
83989 + of the first range (as only one frame length range was defined).
83990 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
83991 + frame count will be separated to frame length counters, based on
83992 + provided frame length ranges.
83993 + Note that this routine will identify the bucket of this key in
83994 + the hash table and will search the bucket to locate the index
83995 + of the required key based on received key parameters.
83996 +
83997 + @Param[in] h_HashTbl A handle to a hash table
83998 + @Param[in] keySize Size of the requested key
83999 + @Param[in] p_Key A pointer to the requested key
84000 + @Param[out] p_KeyStatistics Key statistics counters
84001 +
84002 + @Return The specific key statistics.
84003 +
84004 + @Cautions Allowed only following FM_PCD_HashTableSet().
84005 +*//***************************************************************************/
84006 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
84007 + uint8_t keySize,
84008 + uint8_t *p_Key,
84009 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84010 +
84011 +/**************************************************************************//**
84012 + @Function FM_PCD_HashTableGetMissStatistics
84013 +
84014 + @Description This routine may be used to get statistics counters of 'miss'
84015 + entry of the a hash table.
84016 +
84017 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84018 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84019 + these counters reflect how many frames were not matched to any
84020 + existing key and therefore passed through the miss entry;
84021 +
84022 + @Param[in] h_HashTbl A handle to a hash table
84023 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84024 +
84025 + @Return The statistics for 'miss'.
84026 +
84027 + @Cautions Allowed only following FM_PCD_HashTableSet().
84028 +*//***************************************************************************/
84029 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
84030 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84031 +
84032 +/**************************************************************************//**
84033 + @Function FM_PCD_ManipNodeSet
84034 +
84035 + @Description This routine should be called for defining a manipulation
84036 + node. A manipulation node must be defined before the CC node
84037 + that precedes it.
84038 +
84039 + @Param[in] h_FmPcd FM PCD module descriptor.
84040 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
84041 +
84042 + @Return A handle to the initialized object on success; NULL code otherwise.
84043 +
84044 + @Cautions Allowed only following FM_PCD_Init().
84045 +*//***************************************************************************/
84046 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
84047 +
84048 +/**************************************************************************//**
84049 + @Function FM_PCD_ManipNodeDelete
84050 +
84051 + @Description Delete an existing manipulation node.
84052 +
84053 + @Param[in] h_ManipNode A handle to a manipulation node.
84054 +
84055 + @Return E_OK on success; Error code otherwise.
84056 +
84057 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84058 +*//***************************************************************************/
84059 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
84060 +
84061 +/**************************************************************************//**
84062 + @Function FM_PCD_ManipGetStatistics
84063 +
84064 + @Description Retrieve the manipulation statistics.
84065 +
84066 + @Param[in] h_ManipNode A handle to a manipulation node.
84067 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
84068 +
84069 + @Return E_OK on success; Error code otherwise.
84070 +
84071 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84072 +*//***************************************************************************/
84073 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
84074 +
84075 +/**************************************************************************//**
84076 + @Function FM_PCD_ManipNodeReplace
84077 +
84078 + @Description Change existing manipulation node to be according to new requirement.
84079 +
84080 + @Param[in] h_ManipNode A handle to a manipulation node.
84081 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
84082 +
84083 + @Return E_OK on success; Error code otherwise.
84084 +
84085 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84086 +*//***************************************************************************/
84087 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
84088 +
84089 +#if (DPAA_VERSION >= 11)
84090 +/**************************************************************************//**
84091 + @Function FM_PCD_FrmReplicSetGroup
84092 +
84093 + @Description Initialize a Frame Replicator group.
84094 +
84095 + @Param[in] h_FmPcd FM PCD module descriptor.
84096 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
84097 + the frame replicator group.
84098 +
84099 + @Return A handle to the initialized object on success; NULL code otherwise.
84100 +
84101 + @Cautions Allowed only following FM_PCD_Init().
84102 +*//***************************************************************************/
84103 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
84104 +
84105 +/**************************************************************************//**
84106 + @Function FM_PCD_FrmReplicDeleteGroup
84107 +
84108 + @Description Delete a Frame Replicator group.
84109 +
84110 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84111 +
84112 + @Return E_OK on success; Error code otherwise.
84113 +
84114 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
84115 +*//***************************************************************************/
84116 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
84117 +
84118 +/**************************************************************************//**
84119 + @Function FM_PCD_FrmReplicAddMember
84120 +
84121 + @Description Add the member in the index defined by the memberIndex.
84122 +
84123 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84124 + @Param[in] memberIndex member index for adding.
84125 + @Param[in] p_MemberParams A pointer to the new member parameters.
84126 +
84127 + @Return E_OK on success; Error code otherwise.
84128 +
84129 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84130 +*//***************************************************************************/
84131 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
84132 + uint16_t memberIndex,
84133 + t_FmPcdCcNextEngineParams *p_MemberParams);
84134 +
84135 +/**************************************************************************//**
84136 + @Function FM_PCD_FrmReplicRemoveMember
84137 +
84138 + @Description Remove the member defined by the index from the relevant group.
84139 +
84140 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84141 + @Param[in] memberIndex member index for removing.
84142 +
84143 + @Return E_OK on success; Error code otherwise.
84144 +
84145 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84146 +*//***************************************************************************/
84147 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
84148 + uint16_t memberIndex);
84149 +#endif /* (DPAA_VERSION >= 11) */
84150 +
84151 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84152 +/**************************************************************************//**
84153 + @Function FM_PCD_StatisticsSetNode
84154 +
84155 + @Description This routine should be called for defining a statistics node.
84156 +
84157 + @Param[in] h_FmPcd FM PCD module descriptor.
84158 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
84159 +
84160 + @Return A handle to the initialized object on success; NULL code otherwise.
84161 +
84162 + @Cautions Allowed only following FM_PCD_Init().
84163 +*//***************************************************************************/
84164 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
84165 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84166 +
84167 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
84168 +/** @} */ /* end of FM_PCD_Runtime_grp group */
84169 +/** @} */ /* end of FM_PCD_grp group */
84170 +/** @} */ /* end of FM_grp group */
84171 +
84172 +
84173 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
84174 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
84175 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
84176 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
84177 +
84178 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
84179 +
84180 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
84181 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
84182 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
84183 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
84184 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
84185 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
84186 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
84187 +
84188 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
84189 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
84190 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
84191 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
84192 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
84193 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
84194 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
84195 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
84196 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
84197 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
84198 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
84199 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
84200 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
84201 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
84202 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
84203 + FM_PCD_CcRootDelete(__VA_ARGS__)
84204 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
84205 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
84206 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
84207 + FM_PCD_MatchTableDelete(__VA_ARGS__)
84208 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
84209 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
84210 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
84211 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
84212 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
84213 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
84214 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
84215 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
84216 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
84217 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
84218 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
84219 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
84220 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
84221 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
84222 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
84223 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
84224 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
84225 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
84226 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
84227 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
84228 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
84229 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
84230 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
84231 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
84232 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
84233 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
84234 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
84235 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
84236 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
84237 +
84238 +
84239 +#endif /* __FM_PCD_EXT */
84240 --- /dev/null
84241 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84242 @@ -0,0 +1,2608 @@
84243 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
84244 + * All rights reserved.
84245 + *
84246 + * Redistribution and use in source and binary forms, with or without
84247 + * modification, are permitted provided that the following conditions are met:
84248 + * * Redistributions of source code must retain the above copyright
84249 + * notice, this list of conditions and the following disclaimer.
84250 + * * Redistributions in binary form must reproduce the above copyright
84251 + * notice, this list of conditions and the following disclaimer in the
84252 + * documentation and/or other materials provided with the distribution.
84253 + * * Neither the name of Freescale Semiconductor nor the
84254 + * names of its contributors may be used to endorse or promote products
84255 + * derived from this software without specific prior written permission.
84256 + *
84257 + *
84258 + * ALTERNATIVELY, this software may be distributed under the terms of the
84259 + * GNU General Public License ("GPL") as published by the Free Software
84260 + * Foundation, either version 2 of that License or (at your option) any
84261 + * later version.
84262 + *
84263 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
84264 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
84265 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84266 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
84267 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
84268 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
84269 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84270 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84271 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84272 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84273 + */
84274 +
84275 +
84276 +/**************************************************************************//**
84277 + @File fm_port_ext.h
84278 +
84279 + @Description FM-Port Application Programming Interface.
84280 +*//***************************************************************************/
84281 +#ifndef __FM_PORT_EXT
84282 +#define __FM_PORT_EXT
84283 +
84284 +#include "error_ext.h"
84285 +#include "std_ext.h"
84286 +#include "fm_pcd_ext.h"
84287 +#include "fm_ext.h"
84288 +#include "net_ext.h"
84289 +
84290 +
84291 +/**************************************************************************//**
84292 +
84293 + @Group FM_grp Frame Manager API
84294 +
84295 + @Description FM API functions, definitions and enums
84296 +
84297 + @{
84298 +*//***************************************************************************/
84299 +
84300 +/**************************************************************************//**
84301 + @Group FM_PORT_grp FM Port
84302 +
84303 + @Description FM Port API
84304 +
84305 + The FM uses a general module called "port" to represent a Tx port
84306 + (MAC), an Rx port (MAC) or Offline Parsing port.
84307 + The number of ports in an FM varies between SOCs.
84308 + The SW driver manages these ports as sub-modules of the FM, i.e.
84309 + after an FM is initialized, its ports may be initialized and
84310 + operated upon.
84311 +
84312 + The port is initialized aware of its type, but other functions on
84313 + a port may be indifferent to its type. When necessary, the driver
84314 + verifies coherence and returns error if applicable.
84315 +
84316 + On initialization, user specifies the port type and it's index
84317 + (relative to the port's type) - always starting at 0.
84318 +
84319 + @{
84320 +*//***************************************************************************/
84321 +
84322 +/**************************************************************************//**
84323 + @Description An enum for defining port PCD modes.
84324 + This enum defines the superset of PCD engines support - i.e. not
84325 + all engines have to be used, but all have to be enabled. The real
84326 + flow of a specific frame depends on the PCD configuration and the
84327 + frame headers and payload.
84328 + Note: the first engine and the first engine after the parser (if
84329 + exists) should be in order, the order is important as it will
84330 + define the flow of the port. However, as for the rest engines
84331 + (the ones that follows), the order is not important anymore as
84332 + it is defined by the PCD graph itself.
84333 +*//***************************************************************************/
84334 +typedef enum e_FmPortPcdSupport {
84335 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
84336 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
84337 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
84338 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
84339 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
84340 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
84341 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
84342 + /**< Use all PCD engines */
84343 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
84344 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
84345 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
84346 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
84347 +#ifdef FM_CAPWAP_SUPPORT
84348 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
84349 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
84350 +#endif /* FM_CAPWAP_SUPPORT */
84351 +} e_FmPortPcdSupport;
84352 +
84353 +/**************************************************************************//**
84354 + @Description Port interrupts
84355 +*//***************************************************************************/
84356 +typedef enum e_FmPortExceptions {
84357 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
84358 +} e_FmPortExceptions;
84359 +
84360 +
84361 +/**************************************************************************//**
84362 + @Collection General FM Port defines
84363 +*//***************************************************************************/
84364 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
84365 +/* @} */
84366 +
84367 +/**************************************************************************//**
84368 + @Collection FM Frame error
84369 +*//***************************************************************************/
84370 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
84371 +
84372 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
84373 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
84374 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
84375 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
84376 + was chained to FM */
84377 +
84378 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
84379 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
84380 +
84381 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
84382 +
84383 +#ifdef FM_CAPWAP_SUPPORT
84384 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
84385 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
84386 +#endif /* FM_CAPWAP_SUPPORT */
84387 +
84388 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
84389 + error (SGMII and TBI modes), FIFO parity error. PHY
84390 + Sequence error, PHY error control character detected. */
84391 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
84392 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
84393 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
84394 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
84395 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
84396 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
84397 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
84398 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
84399 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
84400 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
84401 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
84402 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
84403 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
84404 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
84405 +/* @} */
84406 +
84407 +
84408 +
84409 +/**************************************************************************//**
84410 + @Group FM_PORT_init_grp FM Port Initialization Unit
84411 +
84412 + @Description FM Port Initialization Unit
84413 +
84414 + @{
84415 +*//***************************************************************************/
84416 +
84417 +/**************************************************************************//**
84418 + @Description Exceptions user callback routine, will be called upon an
84419 + exception passing the exception identification.
84420 +
84421 + @Param[in] h_App - User's application descriptor.
84422 + @Param[in] exception - The exception.
84423 + *//***************************************************************************/
84424 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
84425 +
84426 +/**************************************************************************//**
84427 + @Description User callback function called by driver with received data.
84428 +
84429 + User provides this function. Driver invokes it.
84430 +
84431 + @Param[in] h_App Application's handle originally specified to
84432 + the API Config function
84433 + @Param[in] p_Data A pointer to data received
84434 + @Param[in] length length of received data
84435 + @Param[in] status receive status and errors
84436 + @Param[in] position position of buffer in frame
84437 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84438 +
84439 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
84440 + operation for all ready data.
84441 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
84442 +*//***************************************************************************/
84443 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
84444 + uint8_t *p_Data,
84445 + uint16_t length,
84446 + uint16_t status,
84447 + uint8_t position,
84448 + t_Handle h_BufContext);
84449 +
84450 +/**************************************************************************//**
84451 + @Description User callback function called by driver when transmit completed.
84452 +
84453 + User provides this function. Driver invokes it.
84454 +
84455 + @Param[in] h_App Application's handle originally specified to
84456 + the API Config function
84457 + @Param[in] p_Data A pointer to data received
84458 + @Param[in] status transmit status and errors
84459 + @Param[in] lastBuffer is last buffer in frame
84460 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84461 + *//***************************************************************************/
84462 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
84463 + uint8_t *p_Data,
84464 + uint16_t status,
84465 + t_Handle h_BufContext);
84466 +
84467 +/**************************************************************************//**
84468 + @Description A structure for additional Rx port parameters
84469 +*//***************************************************************************/
84470 +typedef struct t_FmPortRxParams {
84471 + uint32_t errFqid; /**< Error Queue Id. */
84472 + uint32_t dfltFqid; /**< Default Queue Id. */
84473 + uint16_t liodnOffset; /**< Port's LIODN offset. */
84474 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
84475 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
84476 +} t_FmPortRxParams;
84477 +
84478 +/**************************************************************************//**
84479 + @Description A structure for additional non-Rx port parameters
84480 +*//***************************************************************************/
84481 +typedef struct t_FmPortNonRxParams {
84482 + uint32_t errFqid; /**< Error Queue Id. */
84483 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
84484 + 0 means no Tx confirmation for processed
84485 + frames. For OP port - default Rx queue. */
84486 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
84487 + by the FM for dequeue. */
84488 +} t_FmPortNonRxParams;
84489 +
84490 +/**************************************************************************//**
84491 + @Description A structure for additional Rx port parameters
84492 +*//***************************************************************************/
84493 +typedef struct t_FmPortImRxTxParams {
84494 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
84495 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
84496 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
84497 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
84498 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
84499 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
84500 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
84501 +} t_FmPortImRxTxParams;
84502 +
84503 +/**************************************************************************//**
84504 + @Description A union for additional parameters depending on port type
84505 +*//***************************************************************************/
84506 +typedef union u_FmPortSpecificParams {
84507 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
84508 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
84509 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
84510 +} u_FmPortSpecificParams;
84511 +
84512 +/**************************************************************************//**
84513 + @Description A structure representing FM initialization parameters
84514 +*//***************************************************************************/
84515 +typedef struct t_FmPortParams {
84516 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
84517 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
84518 + e_FmPortType portType; /**< Port type */
84519 + uint8_t portId; /**< Port Id - relative to type;
84520 + NOTE: When configuring Offline Parsing port for
84521 + FMANv3 devices (DPAA_VERSION 11 and higher),
84522 + it is highly recommended NOT to use portId=0 due to lack
84523 + of HW resources on portId=0. */
84524 + bool independentModeEnable;
84525 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
84526 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
84527 + used together with LIODN offset. */
84528 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
84529 + type. */
84530 +
84531 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
84532 + t_Handle h_App; /**< A handle to an application layer object; This handle will
84533 + be passed by the driver upon calling the above callbacks */
84534 +} t_FmPortParams;
84535 +
84536 +
84537 +/**************************************************************************//**
84538 + @Function FM_PORT_Config
84539 +
84540 + @Description Creates a descriptor for the FM PORT module.
84541 +
84542 + The routine returns a handle (descriptor) to the FM PORT object.
84543 + This descriptor must be passed as first parameter to all other
84544 + FM PORT function calls.
84545 +
84546 + No actual initialization or configuration of FM hardware is
84547 + done by this routine.
84548 +
84549 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
84550 +
84551 + @Retval Handle to FM object, or NULL for Failure.
84552 +*//***************************************************************************/
84553 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
84554 +
84555 +/**************************************************************************//**
84556 + @Function FM_PORT_Init
84557 +
84558 + @Description Initializes the FM PORT module by defining the software structure
84559 + and configuring the hardware registers.
84560 +
84561 + @Param[in] h_FmPort - FM PORT module descriptor
84562 +
84563 + @Return E_OK on success; Error code otherwise.
84564 +*//***************************************************************************/
84565 +t_Error FM_PORT_Init(t_Handle h_FmPort);
84566 +
84567 +/**************************************************************************//**
84568 + @Function FM_PORT_Free
84569 +
84570 + @Description Frees all resources that were assigned to FM PORT module.
84571 +
84572 + Calling this routine invalidates the descriptor.
84573 +
84574 + @Param[in] h_FmPort - FM PORT module descriptor
84575 +
84576 + @Return E_OK on success; Error code otherwise.
84577 +*//***************************************************************************/
84578 +t_Error FM_PORT_Free(t_Handle h_FmPort);
84579 +
84580 +
84581 +/**************************************************************************//**
84582 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
84583 +
84584 + @Description Configuration functions used to change default values.
84585 +
84586 + @{
84587 +*//***************************************************************************/
84588 +
84589 +/**************************************************************************//**
84590 + @Description enum for defining QM frame dequeue
84591 +*//***************************************************************************/
84592 +typedef enum e_FmPortDeqType {
84593 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
84594 + and Intra-Class Scheduling respected. */
84595 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
84596 + and Intra-Class Scheduling respected. */
84597 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
84598 + and override Intra-Class Scheduling */
84599 +} e_FmPortDeqType;
84600 +
84601 +/**************************************************************************//**
84602 + @Description enum for defining QM frame dequeue
84603 +*//***************************************************************************/
84604 +typedef enum e_FmPortDeqPrefetchOption {
84605 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
84606 + only when a dedicated portID Tnum is waiting. */
84607 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
84608 + one dedicated portId tnum is waiting. */
84609 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
84610 + no dedicated portId tnums are waiting. */
84611 +
84612 +} e_FmPortDeqPrefetchOption;
84613 +
84614 +/**************************************************************************//**
84615 + @Description enum for defining port default color
84616 +*//***************************************************************************/
84617 +typedef enum e_FmPortColor {
84618 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
84619 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
84620 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
84621 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
84622 +} e_FmPortColor;
84623 +
84624 +/**************************************************************************//**
84625 + @Description A structure for defining Dual Tx rate limiting scale
84626 +*//***************************************************************************/
84627 +typedef enum e_FmPortDualRateLimiterScaleDown {
84628 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
84629 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
84630 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
84631 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
84632 +} e_FmPortDualRateLimiterScaleDown;
84633 +
84634 +
84635 +/**************************************************************************//**
84636 + @Description A structure for defining FM port resources
84637 +*//***************************************************************************/
84638 +typedef struct t_FmPortRsrc {
84639 + uint32_t num; /**< Committed required resource */
84640 + uint32_t extra; /**< Extra (not committed) required resource */
84641 +} t_FmPortRsrc;
84642 +
84643 +/**************************************************************************//**
84644 + @Description A structure for defining observed pool depletion
84645 +*//***************************************************************************/
84646 +typedef struct t_FmPortObservedBufPoolDepletion {
84647 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
84648 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
84649 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
84650 + and their sizes. */
84651 +} t_FmPortObservedBufPoolDepletion;
84652 +
84653 +/**************************************************************************//**
84654 + @Description A structure for defining Tx rate limiting
84655 +*//***************************************************************************/
84656 +typedef struct t_FmPortRateLimit {
84657 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
84658 + for OP ports. (note that
84659 + for early chips burst size is
84660 + rounded up to a multiply of 1000 frames).*/
84661 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
84662 + OP ports. Rate limit refers to
84663 + data rate (rather than line rate). */
84664 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
84665 + for some earlier chip revisions */
84666 +} t_FmPortRateLimit;
84667 +
84668 +/**************************************************************************//**
84669 + @Description A structure for defining the parameters of
84670 + the Rx port performance counters
84671 +*//***************************************************************************/
84672 +typedef struct t_FmPortPerformanceCnt {
84673 + uint8_t taskCompVal; /**< Task compare value */
84674 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
84675 + value (unused for H/O) */
84676 + uint8_t dmaCompVal; /**< Dma compare value */
84677 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
84678 +} t_FmPortPerformanceCnt;
84679 +
84680 +
84681 +/**************************************************************************//**
84682 + @Description A structure for defining the sizes of the Deep Sleep
84683 + the Auto Response tables
84684 +*//***************************************************************************/
84685 +typedef struct t_FmPortDsarTablesSizes
84686 +{
84687 + uint16_t maxNumOfArpEntries;
84688 + uint16_t maxNumOfEchoIpv4Entries;
84689 + uint16_t maxNumOfNdpEntries;
84690 + uint16_t maxNumOfEchoIpv6Entries;
84691 + uint16_t maxNumOfSnmpIPV4Entries;
84692 + uint16_t maxNumOfSnmpIPV6Entries;
84693 + uint16_t maxNumOfSnmpOidEntries;
84694 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
84695 +
84696 + uint16_t maxNumOfIpProtFiltering;
84697 + uint16_t maxNumOfTcpPortFiltering;
84698 + uint16_t maxNumOfUdpPortFiltering;
84699 +} t_FmPortDsarTablesSizes;
84700 +
84701 +
84702 +/**************************************************************************//**
84703 + @Function FM_PORT_ConfigDsarSupport
84704 +
84705 + @Description This function will allocate the amount of MURAM needed for
84706 + this max number of entries for Deep Sleep Auto Response.
84707 + it will calculate all needed MURAM for autoresponse including
84708 + necesary common stuff.
84709 +
84710 +
84711 + @Param[in] h_FmPort A handle to a FM Port module.
84712 + @Param[in] params A pointer to a structure containing the maximum
84713 + sizes of the auto response tables
84714 +
84715 + @Return E_OK on success; Error code otherwise.
84716 +
84717 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84718 +*//***************************************************************************/
84719 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
84720 +
84721 +/**************************************************************************//**
84722 + @Function FM_PORT_ConfigNumOfOpenDmas
84723 +
84724 + @Description Calling this routine changes the max number of open DMA's
84725 + available for this port. It changes this parameter in the
84726 + internal driver data base from its default configuration
84727 + [OP: 1]
84728 + [1G-RX, 1G-TX: 1 (+1)]
84729 + [10G-RX, 10G-TX: 8 (+8)]
84730 +
84731 + @Param[in] h_FmPort A handle to a FM Port module.
84732 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
84733 + the open DMA allocation.
84734 +
84735 + @Return E_OK on success; Error code otherwise.
84736 +
84737 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84738 +*//***************************************************************************/
84739 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
84740 +
84741 +/**************************************************************************//**
84742 + @Function FM_PORT_ConfigNumOfTasks
84743 +
84744 + @Description Calling this routine changes the max number of tasks
84745 + available for this port. It changes this parameter in the
84746 + internal driver data base from its default configuration
84747 + [OP: 1]
84748 + [1G-RX, 1G-TX: 3 (+2)]
84749 + [10G-RX, 10G-TX: 16 (+8)]
84750 +
84751 + @Param[in] h_FmPort A handle to a FM Port module.
84752 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
84753 + the tasks allocation.
84754 +
84755 + @Return E_OK on success; Error code otherwise.
84756 +
84757 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84758 +*//***************************************************************************/
84759 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
84760 +
84761 +/**************************************************************************//**
84762 + @Function FM_PORT_ConfigSizeOfFifo
84763 +
84764 + @Description Calling this routine changes the max FIFO size configured for this port.
84765 +
84766 + This function changes the internal driver data base from its
84767 + default configuration. Please refer to the driver's User Guide for
84768 + information on default FIFO sizes in the various devices.
84769 + [OP: 2KB]
84770 + [1G-RX, 1G-TX: 11KB]
84771 + [10G-RX, 10G-TX: 12KB]
84772 +
84773 + @Param[in] h_FmPort A handle to a FM Port module.
84774 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
84775 + the FIFO allocation.
84776 +
84777 + @Return E_OK on success; Error code otherwise.
84778 +
84779 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84780 +*//***************************************************************************/
84781 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
84782 +
84783 +/**************************************************************************//**
84784 + @Function FM_PORT_ConfigDeqHighPriority
84785 +
84786 + @Description Calling this routine changes the dequeue priority in the
84787 + internal driver data base from its default configuration
84788 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
84789 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
84790 +
84791 + May be used for Non-Rx ports only
84792 +
84793 + @Param[in] h_FmPort A handle to a FM Port module.
84794 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
84795 +
84796 + @Return E_OK on success; Error code otherwise.
84797 +
84798 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84799 +*//***************************************************************************/
84800 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
84801 +
84802 +/**************************************************************************//**
84803 + @Function FM_PORT_ConfigDeqType
84804 +
84805 + @Description Calling this routine changes the dequeue type parameter in the
84806 + internal driver data base from its default configuration
84807 + [DEFAULT_PORT_deqType].
84808 +
84809 + May be used for Non-Rx ports only
84810 +
84811 + @Param[in] h_FmPort A handle to a FM Port module.
84812 + @Param[in] deqType According to QM definition.
84813 +
84814 + @Return E_OK on success; Error code otherwise.
84815 +
84816 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84817 +*//***************************************************************************/
84818 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
84819 +
84820 +/**************************************************************************//**
84821 + @Function FM_PORT_ConfigDeqPrefetchOption
84822 +
84823 + @Description Calling this routine changes the dequeue prefetch option parameter in the
84824 + internal driver data base from its default configuration
84825 + [DEFAULT_PORT_deqPrefetchOption]
84826 + Note: Available for some chips only
84827 +
84828 + May be used for Non-Rx ports only
84829 +
84830 + @Param[in] h_FmPort A handle to a FM Port module.
84831 + @Param[in] deqPrefetchOption New option
84832 +
84833 + @Return E_OK on success; Error code otherwise.
84834 +
84835 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84836 +*//***************************************************************************/
84837 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
84838 +
84839 +/**************************************************************************//**
84840 + @Function FM_PORT_ConfigDeqByteCnt
84841 +
84842 + @Description Calling this routine changes the dequeue byte count parameter in
84843 + the internal driver data base from its default configuration
84844 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
84845 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
84846 +
84847 + May be used for Non-Rx ports only
84848 +
84849 + @Param[in] h_FmPort A handle to a FM Port module.
84850 + @Param[in] deqByteCnt New byte count
84851 +
84852 + @Return E_OK on success; Error code otherwise.
84853 +
84854 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84855 +*//***************************************************************************/
84856 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
84857 +
84858 +/**************************************************************************//**
84859 + @Function FM_PORT_ConfigBufferPrefixContent
84860 +
84861 + @Description Defines the structure, size and content of the application buffer.
84862 + The prefix will
84863 + In Tx ports, if 'passPrsResult', the application
84864 + should set a value to their offsets in the prefix of
84865 + the FM will save the first 'privDataSize', than,
84866 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
84867 + and timeStamp, and the packet itself (in this order), to the
84868 + application buffer, and to offset.
84869 + Calling this routine changes the buffer margins definitions
84870 + in the internal driver data base from its default
84871 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
84872 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
84873 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
84874 +
84875 + May be used for all ports
84876 +
84877 + @Param[in] h_FmPort A handle to a FM Port module.
84878 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
84879 + structure of the buffer.
84880 + Out parameter: Start margin - offset
84881 + of data from start of external buffer.
84882 +
84883 + @Return E_OK on success; Error code otherwise.
84884 +
84885 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84886 +*//***************************************************************************/
84887 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
84888 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
84889 +
84890 +/**************************************************************************//**
84891 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
84892 +
84893 + @Description Calling this routine changes the number of checksum bytes to ignore
84894 + parameter in the internal driver data base from its default configuration
84895 + [DEFAULT_PORT_cheksumLastBytesIgnore]
84896 +
84897 + May be used by Tx & Rx ports only
84898 +
84899 + @Param[in] h_FmPort A handle to a FM Port module.
84900 + @Param[in] cheksumLastBytesIgnore New value
84901 +
84902 + @Return E_OK on success; Error code otherwise.
84903 +
84904 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84905 +*//***************************************************************************/
84906 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
84907 +
84908 +/**************************************************************************//**
84909 + @Function FM_PORT_ConfigCutBytesFromEnd
84910 +
84911 + @Description Calling this routine changes the number of bytes to cut from a
84912 + frame's end parameter in the internal driver data base
84913 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
84914 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
84915 + less than 14 bytes, the chop operation is not executed.
84916 +
84917 + May be used for Rx ports only
84918 +
84919 + @Param[in] h_FmPort A handle to a FM Port module.
84920 + @Param[in] cutBytesFromEnd New value
84921 +
84922 + @Return E_OK on success; Error code otherwise.
84923 +
84924 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84925 +*//***************************************************************************/
84926 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
84927 +
84928 +/**************************************************************************//**
84929 + @Function FM_PORT_ConfigPoolDepletion
84930 +
84931 + @Description Calling this routine enables pause frame generation depending on the
84932 + depletion status of BM pools. It also defines the conditions to activate
84933 + this functionality. By default, this functionality is disabled.
84934 +
84935 + May be used for Rx ports only
84936 +
84937 + @Param[in] h_FmPort A handle to a FM Port module.
84938 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
84939 +
84940 + @Return E_OK on success; Error code otherwise.
84941 +
84942 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84943 +*//***************************************************************************/
84944 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
84945 +
84946 +/**************************************************************************//**
84947 + @Function FM_PORT_ConfigObservedPoolDepletion
84948 +
84949 + @Description Calling this routine enables a mechanism to stop port enqueue
84950 + depending on the depletion status of selected BM pools.
84951 + It also defines the conditions to activate
84952 + this functionality. By default, this functionality is disabled.
84953 +
84954 + Note: Available for some chips only
84955 +
84956 + May be used for OP ports only
84957 +
84958 + @Param[in] h_FmPort A handle to a FM Port module.
84959 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
84960 +
84961 + @Return E_OK on success; Error code otherwise.
84962 +
84963 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84964 +*//***************************************************************************/
84965 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
84966 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
84967 +
84968 +/**************************************************************************//**
84969 + @Function FM_PORT_ConfigExtBufPools
84970 +
84971 + @Description This routine should be called for OP ports
84972 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
84973 + re-assembly, the FM needs new BM buffers. By calling this routine the user
84974 + specifies the BM buffer pools that should be used.
84975 +
84976 + Note: Available for some chips only
84977 +
84978 + May be used for OP ports only
84979 +
84980 + @Param[in] h_FmPort A handle to a FM Port module.
84981 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
84982 +
84983 + @Return E_OK on success; Error code otherwise.
84984 +
84985 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
84986 +*//***************************************************************************/
84987 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
84988 +
84989 +/**************************************************************************//**
84990 + @Function FM_PORT_ConfigBackupPools
84991 +
84992 + @Description Calling this routine allows the configuration of some of the BM pools
84993 + defined for this port as backup pools.
84994 + A pool configured to be a backup pool will be used only if all other
84995 + enabled non-backup pools are depleted.
84996 +
84997 + May be used for Rx ports only
84998 +
84999 + @Param[in] h_FmPort A handle to a FM Port module.
85000 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
85001 + be defined as backup pools.
85002 +
85003 + @Return E_OK on success; Error code otherwise.
85004 +
85005 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85006 +*//***************************************************************************/
85007 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
85008 +
85009 +/**************************************************************************//**
85010 + @Function FM_PORT_ConfigFrmDiscardOverride
85011 +
85012 + @Description Calling this routine changes the error frames destination parameter
85013 + in the internal driver data base from its default configuration:
85014 + override = [DEFAULT_PORT_frmDiscardOverride]
85015 +
85016 + May be used for Rx and OP ports only
85017 +
85018 + @Param[in] h_FmPort A handle to a FM Port module.
85019 + @Param[in] override TRUE to override discarding of error frames and
85020 + enqueueing them to error queue.
85021 +
85022 + @Return E_OK on success; Error code otherwise.
85023 +
85024 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85025 +*//***************************************************************************/
85026 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
85027 +
85028 +/**************************************************************************//**
85029 + @Function FM_PORT_ConfigErrorsToDiscard
85030 +
85031 + @Description Calling this routine changes the behaviour on error parameter
85032 + in the internal driver data base from its default configuration:
85033 + [DEFAULT_PORT_errorsToDiscard].
85034 + If a requested error was previously defined as "ErrorsToEnqueue" it's
85035 + definition will change and the frame will be discarded.
85036 + Errors that were not defined either as "ErrorsToEnqueue" nor as
85037 + "ErrorsToDiscard", will be forwarded to CPU.
85038 +
85039 + May be used for Rx and OP ports only
85040 +
85041 + @Param[in] h_FmPort A handle to a FM Port module.
85042 + @Param[in] errs A list of errors to discard
85043 +
85044 + @Return E_OK on success; Error code otherwise.
85045 +
85046 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85047 +*//***************************************************************************/
85048 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
85049 +
85050 +/**************************************************************************//**
85051 + @Function FM_PORT_ConfigDmaSwapData
85052 +
85053 + @Description Calling this routine changes the DMA swap data aparameter
85054 + in the internal driver data base from its default
85055 + configuration [DEFAULT_PORT_dmaSwapData]
85056 +
85057 + May be used for all port types
85058 +
85059 + @Param[in] h_FmPort A handle to a FM Port module.
85060 + @Param[in] swapData New selection
85061 +
85062 + @Return E_OK on success; Error code otherwise.
85063 +
85064 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85065 +*//***************************************************************************/
85066 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
85067 +
85068 +/**************************************************************************//**
85069 + @Function FM_PORT_ConfigDmaIcCacheAttr
85070 +
85071 + @Description Calling this routine changes the internal context cache
85072 + attribute parameter in the internal driver data base
85073 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
85074 +
85075 + May be used for all port types
85076 +
85077 + @Param[in] h_FmPort A handle to a FM Port module.
85078 + @Param[in] intContextCacheAttr New selection
85079 +
85080 + @Return E_OK on success; Error code otherwise.
85081 +
85082 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85083 +*//***************************************************************************/
85084 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
85085 +
85086 +/**************************************************************************//**
85087 + @Function FM_PORT_ConfigDmaHdrAttr
85088 +
85089 + @Description Calling this routine changes the header cache
85090 + attribute parameter in the internal driver data base
85091 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
85092 +
85093 + May be used for all port types
85094 +
85095 + @Param[in] h_FmPort A handle to a FM Port module.
85096 + @Param[in] headerCacheAttr New selection
85097 +
85098 + @Return E_OK on success; Error code otherwise.
85099 +
85100 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85101 +*//***************************************************************************/
85102 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
85103 +
85104 +/**************************************************************************//**
85105 + @Function FM_PORT_ConfigDmaScatterGatherAttr
85106 +
85107 + @Description Calling this routine changes the scatter gather cache
85108 + attribute parameter in the internal driver data base
85109 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
85110 +
85111 + May be used for all port types
85112 +
85113 + @Param[in] h_FmPort A handle to a FM Port module.
85114 + @Param[in] scatterGatherCacheAttr New selection
85115 +
85116 + @Return E_OK on success; Error code otherwise.
85117 +
85118 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85119 +*//***************************************************************************/
85120 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
85121 +
85122 +/**************************************************************************//**
85123 + @Function FM_PORT_ConfigDmaWriteOptimize
85124 +
85125 + @Description Calling this routine changes the write optimization
85126 + parameter in the internal driver data base
85127 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
85128 + Note:
85129 +
85130 + 1. For head optimization, data alignment must be >= 16 (supported by default).
85131 +
85132 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
85133 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
85134 + is extended to be on 16/64 bytes aligned block (chip dependent).
85135 +
85136 + Relevant for non-Tx port types
85137 +
85138 + @Param[in] h_FmPort A handle to a FM Port module.
85139 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
85140 +
85141 + @Return E_OK on success; Error code otherwise.
85142 +
85143 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85144 +*//***************************************************************************/
85145 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
85146 +
85147 +/**************************************************************************//**
85148 + @Function FM_PORT_ConfigNoScatherGather
85149 +
85150 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
85151 + from its default configuration.
85152 +
85153 + @Param[in] h_FmPort A handle to a FM Port module.
85154 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
85155 + FALSE - frame can be stored in scatter gather (S/G) format).
85156 +
85157 + @Return E_OK on success; Error code otherwise.
85158 +
85159 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85160 +*//***************************************************************************/
85161 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
85162 +
85163 +/**************************************************************************//**
85164 + @Function FM_PORT_ConfigDfltColor
85165 +
85166 + @Description Calling this routine changes the internal default color parameter
85167 + in the internal driver data base
85168 + from its default configuration [DEFAULT_PORT_color]
85169 +
85170 + May be used for all port types
85171 +
85172 + @Param[in] h_FmPort A handle to a FM Port module.
85173 + @Param[in] color New selection
85174 +
85175 + @Return E_OK on success; Error code otherwise.
85176 +
85177 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85178 +*//***************************************************************************/
85179 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
85180 +
85181 +/**************************************************************************//**
85182 + @Function FM_PORT_ConfigSyncReq
85183 +
85184 + @Description Calling this routine changes the synchronization attribute parameter
85185 + in the internal driver data base from its default configuration:
85186 + syncReq = [DEFAULT_PORT_syncReq]
85187 +
85188 + May be used for all port types
85189 +
85190 + @Param[in] h_FmPort A handle to a FM Port module.
85191 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
85192 +
85193 + @Return E_OK on success; Error code otherwise.
85194 +
85195 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85196 +*//***************************************************************************/
85197 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
85198 +
85199 +/**************************************************************************//**
85200 + @Function FM_PORT_ConfigForwardReuseIntContext
85201 +
85202 + @Description This routine is relevant for Rx ports that are routed to OP port.
85203 + It changes the internal context reuse option in the internal
85204 + driver data base from its default configuration:
85205 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
85206 +
85207 + May be used for Rx ports only
85208 +
85209 + @Param[in] h_FmPort A handle to a FM Port module.
85210 + @Param[in] reuse TRUE to reuse internal context on frames
85211 + forwarded to OP port.
85212 +
85213 + @Return E_OK on success; Error code otherwise.
85214 +
85215 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85216 +*//***************************************************************************/
85217 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
85218 +
85219 +/**************************************************************************//**
85220 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
85221 +
85222 + @Description This routine should be called if no Tx confirmation
85223 + is done, and yet buffers should not be released to the BM.
85224 + Normally, buffers are returned using the Tx confirmation
85225 + process. When Tx confirmation is not used (defFqid=0),
85226 + buffers are typically released to the BM. This routine
85227 + may be called to avoid this behavior and not release the
85228 + buffers.
85229 +
85230 + May be used for Tx ports only
85231 +
85232 + @Param[in] h_FmPort A handle to a FM Port module.
85233 +
85234 + @Return E_OK on success; Error code otherwise.
85235 +
85236 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85237 +*//***************************************************************************/
85238 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
85239 +
85240 +/**************************************************************************//**
85241 + @Function FM_PORT_ConfigIMMaxRxBufLength
85242 +
85243 + @Description Changes the maximum receive buffer length from its default
85244 + configuration: Closest rounded down power of 2 value of the
85245 + data buffer size.
85246 +
85247 + The maximum receive buffer length directly affects the structure
85248 + of received frames (single- or multi-buffered) and the performance
85249 + of both the FM and the driver.
85250 +
85251 + The selection between single- or multi-buffered frames should be
85252 + done according to the characteristics of the specific application.
85253 + The recommended mode is to use a single data buffer per packet,
85254 + as this mode provides the best performance. However, the user can
85255 + select to use multiple data buffers per packet.
85256 +
85257 + @Param[in] h_FmPort A handle to a FM Port module.
85258 + @Param[in] newVal Maximum receive buffer length (in bytes).
85259 +
85260 + @Return E_OK on success; Error code otherwise.
85261 +
85262 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85263 + This routine is to be used only if Independent-Mode is enabled.
85264 +*//***************************************************************************/
85265 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
85266 +
85267 +/**************************************************************************//**
85268 + @Function FM_PORT_ConfigIMRxBdRingLength
85269 +
85270 + @Description Changes the receive BD ring length from its default
85271 + configuration:[DEFAULT_PORT_rxBdRingLength]
85272 +
85273 + @Param[in] h_FmPort A handle to a FM Port module.
85274 + @Param[in] newVal The desired BD ring length.
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 + This routine is to be used only if Independent-Mode is enabled.
85280 +*//***************************************************************************/
85281 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85282 +
85283 +/**************************************************************************//**
85284 + @Function FM_PORT_ConfigIMTxBdRingLength
85285 +
85286 + @Description Changes the transmit BD ring length from its default
85287 + configuration:[DEFAULT_PORT_txBdRingLength]
85288 +
85289 + @Param[in] h_FmPort A handle to a FM Port module.
85290 + @Param[in] newVal The desired BD ring length.
85291 +
85292 + @Return E_OK on success; Error code otherwise.
85293 +
85294 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85295 + This routine is to be used only if Independent-Mode is enabled.
85296 +*//***************************************************************************/
85297 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85298 +
85299 +/**************************************************************************//**
85300 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
85301 +
85302 + @Description Configures memory partition and attributes for FMan-Controller
85303 + data structures (e.g. BD rings).
85304 + Calling this routine changes the internal driver data base
85305 + from its default configuration
85306 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
85307 +
85308 + @Param[in] h_FmPort A handle to a FM Port module.
85309 + @Param[in] memId Memory partition ID.
85310 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
85311 +
85312 + @Return E_OK on success; Error code otherwise.
85313 +*//***************************************************************************/
85314 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
85315 + uint8_t memId,
85316 + uint32_t memAttributes);
85317 +
85318 +/**************************************************************************//**
85319 + @Function FM_PORT_ConfigIMPolling
85320 +
85321 + @Description Changes the Rx flow from interrupt driven (default) to polling.
85322 +
85323 + @Param[in] h_FmPort A handle to a FM Port module.
85324 +
85325 + @Return E_OK on success; Error code otherwise.
85326 +
85327 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85328 + This routine is to be used only if Independent-Mode is enabled.
85329 +*//***************************************************************************/
85330 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
85331 +
85332 +/**************************************************************************//**
85333 + @Function FM_PORT_ConfigMaxFrameLength
85334 +
85335 + @Description Changes the definition of the max size of frame that should be
85336 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
85337 + This parameter is used for confirmation of the minimum Fifo
85338 + size calculations and only for Tx ports or ports working in
85339 + independent mode. This should be larger than the maximum possible
85340 + MTU that will be used for this port (i.e. its MAC).
85341 +
85342 + @Param[in] h_FmPort A handle to a FM Port module.
85343 + @Param[in] length Max size of frame
85344 +
85345 + @Return E_OK on success; Error code otherwise.
85346 +
85347 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85348 + This routine is to be used only if Independent-Mode is enabled.
85349 +*//***************************************************************************/
85350 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
85351 +
85352 +/**************************************************************************//*
85353 + @Function FM_PORT_ConfigTxFifoMinFillLevel
85354 +
85355 + @Description Calling this routine changes the fifo minimum
85356 + fill level parameter in the internal driver data base
85357 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
85358 +
85359 + May be used for Tx ports only
85360 +
85361 + @Param[in] h_FmPort A handle to a FM Port module.
85362 + @Param[in] minFillLevel New value
85363 +
85364 + @Return E_OK on success; Error code otherwise.
85365 +
85366 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85367 +*//***************************************************************************/
85368 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
85369 +
85370 +/**************************************************************************//*
85371 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
85372 +
85373 + @Description Calling this routine changes the fifo dequeue
85374 + pipeline depth parameter in the internal driver data base
85375 +
85376 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
85377 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
85378 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
85379 +
85380 + May be used for Tx/OP ports only
85381 +
85382 + @Param[in] h_FmPort A handle to a FM Port module.
85383 + @Param[in] deqPipelineDepth New value
85384 +
85385 + @Return E_OK on success; Error code otherwise.
85386 +
85387 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85388 +*//***************************************************************************/
85389 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
85390 +
85391 +/**************************************************************************//*
85392 + @Function FM_PORT_ConfigTxFifoLowComfLevel
85393 +
85394 + @Description Calling this routine changes the fifo low comfort level
85395 + parameter in internal driver data base
85396 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
85397 +
85398 + May be used for Tx ports only
85399 +
85400 + @Param[in] h_FmPort A handle to a FM Port module.
85401 + @Param[in] fifoLowComfLevel New value
85402 +
85403 + @Return E_OK on success; Error code otherwise.
85404 +
85405 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85406 +*//***************************************************************************/
85407 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
85408 +
85409 +/**************************************************************************//*
85410 + @Function FM_PORT_ConfigRxFifoThreshold
85411 +
85412 + @Description Calling this routine changes the threshold of the FIFO
85413 + fill level parameter in the internal driver data base
85414 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
85415 +
85416 + If the total number of buffers which are
85417 + currently in use and associated with the
85418 + specific RX port exceed this threshold, the
85419 + BMI will signal the MAC to send a pause frame
85420 + over the link.
85421 +
85422 + May be used for Rx ports only
85423 +
85424 + @Param[in] h_FmPort A handle to a FM Port module.
85425 + @Param[in] fifoThreshold New value
85426 +
85427 + @Return E_OK on success; Error code otherwise.
85428 +
85429 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85430 +*//***************************************************************************/
85431 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
85432 +
85433 +/**************************************************************************//*
85434 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
85435 +
85436 + @Description Calling this routine changes the priority elevation level
85437 + parameter in the internal driver data base from its default
85438 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
85439 +
85440 + If the total number of buffers which are currently in use and
85441 + associated with the specific RX port exceed the amount specified
85442 + in priElevationLevel, BMI will signal the main FM's DMA to
85443 + elevate the FM priority on the system bus.
85444 +
85445 + May be used for Rx ports only
85446 +
85447 + @Param[in] h_FmPort A handle to a FM Port module.
85448 + @Param[in] priElevationLevel New value
85449 +
85450 + @Return E_OK on success; Error code otherwise.
85451 +
85452 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85453 +*//***************************************************************************/
85454 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
85455 +
85456 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
85457 +/**************************************************************************//*
85458 + @Function FM_PORT_ConfigBCBWorkaround
85459 +
85460 + @Description Configures BCB errata workaround.
85461 +
85462 + When BCB errata is applicable, the workaround is always
85463 + performed by FM Controller. Thus, this functions doesn't
85464 + actually enable errata workaround but rather allows driver
85465 + to perform adjustments required due to errata workaround
85466 + execution in FM controller.
85467 +
85468 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
85469 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
85470 + set by FM_PORT_SetErrorsRoute() function.
85471 +
85472 + @Param[in] h_FmPort A handle to a FM Port module.
85473 +
85474 + @Return E_OK on success; Error code otherwise.
85475 +
85476 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85477 +*//***************************************************************************/
85478 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
85479 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
85480 +
85481 +#if (DPAA_VERSION >= 11)
85482 +/**************************************************************************//*
85483 + @Function FM_PORT_ConfigInternalBuffOffset
85484 +
85485 + @Description Configures internal buffer offset.
85486 +
85487 + May be used for Rx and OP ports only
85488 +
85489 + @Param[in] h_FmPort A handle to a FM Port module.
85490 + @Param[in] val New value
85491 +
85492 + @Return E_OK on success; Error code otherwise.
85493 +
85494 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85495 +*//***************************************************************************/
85496 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
85497 +#endif /* (DPAA_VERSION >= 11) */
85498 +
85499 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
85500 +/** @} */ /* end of FM_PORT_init_grp group */
85501 +
85502 +
85503 +/**************************************************************************//**
85504 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
85505 +
85506 + @Description FM Port Runtime control unit API functions, definitions and enums.
85507 +
85508 + @{
85509 +*//***************************************************************************/
85510 +
85511 +/**************************************************************************//**
85512 + @Description enum for defining FM Port counters
85513 +*//***************************************************************************/
85514 +typedef enum e_FmPortCounters {
85515 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
85516 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
85517 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
85518 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
85519 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
85520 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
85521 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
85522 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
85523 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
85524 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
85525 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
85526 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
85527 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
85528 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
85529 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
85530 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
85531 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
85532 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
85533 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
85534 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
85535 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
85536 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
85537 +} e_FmPortCounters;
85538 +
85539 +typedef struct t_FmPortBmiStats {
85540 + uint32_t cntCycle;
85541 + uint32_t cntTaskUtil;
85542 + uint32_t cntQueueUtil;
85543 + uint32_t cntDmaUtil;
85544 + uint32_t cntFifoUtil;
85545 + uint32_t cntRxPauseActivation;
85546 + uint32_t cntFrame;
85547 + uint32_t cntDiscardFrame;
85548 + uint32_t cntDeallocBuf;
85549 + uint32_t cntRxBadFrame;
85550 + uint32_t cntRxLargeFrame;
85551 + uint32_t cntRxFilterFrame;
85552 + uint32_t cntRxListDmaErr;
85553 + uint32_t cntRxOutOfBuffersDiscard;
85554 + uint32_t cntWredDiscard;
85555 + uint32_t cntLengthErr;
85556 + uint32_t cntUnsupportedFormat;
85557 +} t_FmPortBmiStats;
85558 +
85559 +/**************************************************************************//**
85560 + @Description Structure for Port id parameters.
85561 + Fields commented 'IN' are passed by the port module to be used
85562 + by the FM module.
85563 + Fields commented 'OUT' will be filled by FM before returning to port.
85564 +*//***************************************************************************/
85565 +typedef struct t_FmPortCongestionGrps {
85566 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
85567 + to define the size of the following array */
85568 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
85569 + /**< An array of CG indexes;
85570 + Note that the size of the array should be
85571 + 'numOfCongestionGrpsToConsider'. */
85572 +#if (DPAA_VERSION >= 11)
85573 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
85574 + /**< a matrix that represents the map between the CG ids
85575 + defined in 'congestionGrpsToConsider' to the priorties
85576 + mapping array. */
85577 +#endif /* (DPAA_VERSION >= 11) */
85578 +} t_FmPortCongestionGrps;
85579 +
85580 +/**************************************************************************//**
85581 + @Description Structure for Deep Sleep Auto Response ARP Entry
85582 +*//***************************************************************************/
85583 +typedef struct t_FmPortDsarArpEntry
85584 +{
85585 + uint32_t ipAddress;
85586 + uint8_t mac[6];
85587 + bool isVlan;
85588 + uint16_t vid;
85589 +} t_FmPortDsarArpEntry;
85590 +
85591 +/**************************************************************************//**
85592 + @Description Structure for Deep Sleep Auto Response ARP info
85593 +*//***************************************************************************/
85594 +typedef struct t_FmPortDsarArpInfo
85595 +{
85596 + uint8_t tableSize;
85597 + t_FmPortDsarArpEntry *p_AutoResTable;
85598 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85599 +} t_FmPortDsarArpInfo;
85600 +
85601 +/**************************************************************************//**
85602 + @Description Structure for Deep Sleep Auto Response NDP Entry
85603 +*//***************************************************************************/
85604 +typedef struct t_FmPortDsarNdpEntry
85605 +{
85606 + uint32_t ipAddress[4];
85607 + uint8_t mac[6];
85608 + bool isVlan;
85609 + uint16_t vid;
85610 +} t_FmPortDsarNdpEntry;
85611 +
85612 +/**************************************************************************//**
85613 + @Description Structure for Deep Sleep Auto Response NDP info
85614 +*//***************************************************************************/
85615 +typedef struct t_FmPortDsarNdpInfo
85616 +{
85617 + uint32_t multicastGroup;
85618 +
85619 + uint8_t tableSizeAssigned;
85620 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
85621 + Note that all IP adresses must be from the same multicast group.
85622 + This will be checked and if not operation will fail. */
85623 + uint8_t tableSizeTmp;
85624 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
85625 + Note that all temp IP adresses must be from the same multicast group.
85626 + This will be checked and if not operation will fail. */
85627 +
85628 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85629 +
85630 +} t_FmPortDsarNdpInfo;
85631 +
85632 +/**************************************************************************//**
85633 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
85634 +*//***************************************************************************/
85635 +typedef struct t_FmPortDsarEchoIpv4Info
85636 +{
85637 + uint8_t tableSize;
85638 + t_FmPortDsarArpEntry *p_AutoResTable;
85639 +} t_FmPortDsarEchoIpv4Info;
85640 +
85641 +/**************************************************************************//**
85642 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
85643 +*//***************************************************************************/
85644 +typedef struct t_FmPortDsarEchoIpv6Info
85645 +{
85646 + uint8_t tableSize;
85647 + t_FmPortDsarNdpEntry *p_AutoResTable;
85648 +} t_FmPortDsarEchoIpv6Info;
85649 +
85650 +/**************************************************************************//**
85651 +@Description Deep Sleep Auto Response SNMP OIDs table entry
85652 +
85653 +*//***************************************************************************/
85654 +typedef struct {
85655 + uint16_t oidSize;
85656 + uint8_t *oidVal; /* only the oid string */
85657 + uint16_t resSize;
85658 + uint8_t *resVal; /* resVal will be the entire reply,
85659 + i.e. "Type|Length|Value" */
85660 +} t_FmPortDsarOidsEntry;
85661 +
85662 +/**************************************************************************//**
85663 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
85664 + Refer to the FMan Controller spec for more details.
85665 +*//***************************************************************************/
85666 +typedef struct
85667 +{
85668 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
85669 + bool isVlan;
85670 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
85671 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
85672 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
85673 +
85674 +/**************************************************************************//**
85675 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
85676 + Refer to the FMan Controller spec for more details.
85677 +*//***************************************************************************/
85678 +typedef struct
85679 +{
85680 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
85681 + bool isVlan;
85682 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
85683 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
85684 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
85685 +
85686 +/**************************************************************************//**
85687 + @Description Deep Sleep Auto Response SNMP Descriptor
85688 +
85689 +*//***************************************************************************/
85690 +typedef struct
85691 +{
85692 + uint16_t control; /**< Control bits [0-15]. */
85693 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
85694 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
85695 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
85696 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
85697 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
85698 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
85699 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
85700 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
85701 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
85702 +} t_FmPortDsarSnmpInfo;
85703 +
85704 +/**************************************************************************//**
85705 + @Description Structure for Deep Sleep Auto Response filtering Entry
85706 +*//***************************************************************************/
85707 +typedef struct t_FmPortDsarFilteringEntry
85708 +{
85709 + uint16_t srcPort;
85710 + uint16_t dstPort;
85711 + uint16_t srcPortMask;
85712 + uint16_t dstPortMask;
85713 +} t_FmPortDsarFilteringEntry;
85714 +
85715 +/**************************************************************************//**
85716 + @Description Structure for Deep Sleep Auto Response filtering info
85717 +*//***************************************************************************/
85718 +typedef struct t_FmPortDsarFilteringInfo
85719 +{
85720 + /* IP protocol filtering parameters */
85721 + uint8_t ipProtTableSize;
85722 + uint8_t *p_IpProtTablePtr;
85723 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85724 + hit will pass the packet to UDP/TCP filters if needed and if not
85725 + to the classification tree. If the classification tree will pass
85726 + the packet to a queue it will cause a wake interupt.
85727 + When FALSE it the other way around. */
85728 + /* UDP port filtering parameters */
85729 + uint8_t udpPortsTableSize;
85730 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
85731 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85732 + hit will pass the packet to classification tree.
85733 + If the classification tree will pass the packet to a queue it
85734 + will cause a wake interupt.
85735 + When FALSE it the other way around. */
85736 + /* TCP port filtering parameters */
85737 + uint16_t tcpFlagsMask;
85738 + uint8_t tcpPortsTableSize;
85739 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
85740 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
85741 + hit will pass the packet to classification tree.
85742 + If the classification tree will pass the packet to a queue it
85743 + will cause a wake interupt.
85744 + When FALSE it the other way around. */
85745 +} t_FmPortDsarFilteringInfo;
85746 +
85747 +/**************************************************************************//**
85748 + @Description Structure for Deep Sleep Auto Response parameters
85749 +*//***************************************************************************/
85750 +typedef struct t_FmPortDsarParams
85751 +{
85752 + t_Handle h_FmPortTx;
85753 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
85754 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
85755 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
85756 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
85757 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
85758 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
85759 +} t_FmPortDsarParams;
85760 +
85761 +/**************************************************************************//**
85762 + @Function FM_PORT_EnterDsar
85763 +
85764 + @Description Enter Deep Sleep Auto Response mode.
85765 + This function write the apropriate values to in the relevant
85766 + tables in the MURAM.
85767 +
85768 + @Param[in] h_FmPortRx - FM PORT module descriptor
85769 + @Param[in] params - Auto Response parameters
85770 +
85771 + @Return E_OK on success; Error code otherwise.
85772 +
85773 + @Cautions Allowed only following FM_PORT_Init().
85774 +*//***************************************************************************/
85775 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
85776 +
85777 +/**************************************************************************//**
85778 + @Function FM_PORT_EnterDsarFinal
85779 +
85780 + @Description Enter Deep Sleep Auto Response mode.
85781 + This function sets the Tx port in independent mode as needed
85782 + and redirect the receive flow to go through the
85783 + Dsar Fman-ctrl code
85784 +
85785 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
85786 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
85787 +
85788 + @Return E_OK on success; Error code otherwise.
85789 +
85790 + @Cautions Allowed only following FM_PORT_Init().
85791 +*//***************************************************************************/
85792 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
85793 +
85794 +/**************************************************************************//**
85795 + @Function FM_PORT_ExitDsar
85796 +
85797 + @Description Exit Deep Sleep Auto Response mode.
85798 + This function reverse the AR mode and put the ports back into
85799 + their original wake mode
85800 +
85801 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
85802 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
85803 +
85804 + @Return E_OK on success; Error code otherwise.
85805 +
85806 + @Cautions Allowed only following FM_PORT_EnterDsar().
85807 +*//***************************************************************************/
85808 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
85809 +
85810 +/**************************************************************************//**
85811 + @Function FM_PORT_IsInDsar
85812 +
85813 + @Description This function returns TRUE if the port was set as Auto Response
85814 + and FALSE if not. Once Exit AR mode it will return FALSE as well
85815 + until re-enabled once more.
85816 +
85817 + @Param[in] h_FmPort - FM PORT module descriptor
85818 +
85819 + @Return E_OK on success; Error code otherwise.
85820 +*//***************************************************************************/
85821 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
85822 +
85823 +typedef struct t_FmPortDsarStats
85824 +{
85825 + uint32_t arpArCnt;
85826 + uint32_t echoIcmpv4ArCnt;
85827 + uint32_t ndpArCnt;
85828 + uint32_t echoIcmpv6ArCnt;
85829 + uint32_t snmpGetCnt;
85830 + uint32_t snmpGetNextCnt;
85831 +} t_FmPortDsarStats;
85832 +
85833 +/**************************************************************************//**
85834 + @Function FM_PORT_GetDsarStats
85835 +
85836 + @Description Return statistics for Deep Sleep Auto Response
85837 +
85838 + @Param[in] h_FmPortRx - FM PORT module descriptor
85839 + @Param[out] stats - structure containing the statistics counters
85840 +
85841 + @Return E_OK on success; Error code otherwise.
85842 +*//***************************************************************************/
85843 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
85844 +
85845 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
85846 +/**************************************************************************//**
85847 + @Function FM_PORT_DumpRegs
85848 +
85849 + @Description Dump all regs.
85850 +
85851 + Calling this routine invalidates the descriptor.
85852 +
85853 + @Param[in] h_FmPort - FM PORT module descriptor
85854 +
85855 + @Return E_OK on success; Error code otherwise.
85856 +
85857 + @Cautions Allowed only following FM_PORT_Init().
85858 +*//***************************************************************************/
85859 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
85860 +#endif /* (defined(DEBUG_ERRORS) && ... */
85861 +
85862 +/**************************************************************************//**
85863 + @Function FM_PORT_GetBufferDataOffset
85864 +
85865 + @Description Relevant for Rx ports.
85866 + Returns the data offset from the beginning of the data buffer
85867 +
85868 + @Param[in] h_FmPort - FM PORT module descriptor
85869 +
85870 + @Return data offset.
85871 +
85872 + @Cautions Allowed only following FM_PORT_Init().
85873 +*//***************************************************************************/
85874 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
85875 +
85876 +/**************************************************************************//**
85877 + @Function FM_PORT_GetBufferICInfo
85878 +
85879 + @Description Returns the Internal Context offset from the beginning of the data buffer
85880 +
85881 + @Param[in] h_FmPort - FM PORT module descriptor
85882 + @Param[in] p_Data - A pointer to the data buffer.
85883 +
85884 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
85885 + configured for this port.
85886 +
85887 + @Cautions Allowed only following FM_PORT_Init().
85888 +*//***************************************************************************/
85889 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
85890 +
85891 +/**************************************************************************//**
85892 + @Function FM_PORT_GetBufferPrsResult
85893 +
85894 + @Description Returns the pointer to the parse result in the data buffer.
85895 + In Rx ports this is relevant after reception, if parse
85896 + result is configured to be part of the data passed to the
85897 + application. For non Rx ports it may be used to get the pointer
85898 + of the area in the buffer where parse result should be
85899 + initialized - if so configured.
85900 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
85901 + configuration.
85902 +
85903 + @Param[in] h_FmPort - FM PORT module descriptor
85904 + @Param[in] p_Data - A pointer to the data buffer.
85905 +
85906 + @Return Parse result pointer on success, NULL if parse result was not
85907 + configured for this port.
85908 +
85909 + @Cautions Allowed only following FM_PORT_Init().
85910 +*//***************************************************************************/
85911 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
85912 +
85913 +/**************************************************************************//**
85914 + @Function FM_PORT_GetBufferTimeStamp
85915 +
85916 + @Description Returns the time stamp in the data buffer.
85917 + Relevant for Rx ports for getting the buffer time stamp.
85918 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
85919 + configuration.
85920 +
85921 + @Param[in] h_FmPort - FM PORT module descriptor
85922 + @Param[in] p_Data - A pointer to the data buffer.
85923 +
85924 + @Return A pointer to the hash result on success, NULL otherwise.
85925 +
85926 + @Cautions Allowed only following FM_PORT_Init().
85927 +*//***************************************************************************/
85928 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
85929 +
85930 +/**************************************************************************//**
85931 + @Function FM_PORT_GetBufferHashResult
85932 +
85933 + @Description Given a data buffer, on the condition that hash result was defined
85934 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
85935 + this routine will return the pointer to the hash result location in the
85936 + buffer prefix.
85937 +
85938 + @Param[in] h_FmPort - FM PORT module descriptor
85939 + @Param[in] p_Data - A pointer to the data buffer.
85940 +
85941 + @Return A pointer to the hash result on success, NULL otherwise.
85942 +
85943 + @Cautions Allowed only following FM_PORT_Init().
85944 +*//***************************************************************************/
85945 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
85946 +
85947 +/**************************************************************************//**
85948 + @Function FM_PORT_Disable
85949 +
85950 + @Description Gracefully disable an FM port. The port will not start new tasks after all
85951 + tasks associated with the port are terminated.
85952 +
85953 + @Param[in] h_FmPort A handle to a FM Port module.
85954 +
85955 + @Return E_OK on success; Error code otherwise.
85956 +
85957 + @Cautions Allowed only following FM_PORT_Init().
85958 + This is a blocking routine, it returns after port is
85959 + gracefully stopped, i.e. the port will not except new frames,
85960 + but it will finish all frames or tasks which were already began
85961 +*//***************************************************************************/
85962 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
85963 +
85964 +/**************************************************************************//**
85965 + @Function FM_PORT_Enable
85966 +
85967 + @Description A runtime routine provided to allow disable/enable of port.
85968 +
85969 + @Param[in] h_FmPort A handle to a FM Port module.
85970 +
85971 + @Return E_OK on success; Error code otherwise.
85972 +
85973 + @Cautions Allowed only following FM_PORT_Init().
85974 +*//***************************************************************************/
85975 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
85976 +
85977 +/**************************************************************************//**
85978 + @Function FM_PORT_SetRateLimit
85979 +
85980 + @Description Calling this routine enables rate limit algorithm.
85981 + By default, this functionality is disabled.
85982 + Note that rate-limit mechanism uses the FM time stamp.
85983 + The selected rate limit specified here would be
85984 + rounded DOWN to the nearest 16M.
85985 +
85986 + May be used for Tx and OP ports only
85987 +
85988 + @Param[in] h_FmPort A handle to a FM Port module.
85989 + @Param[in] p_RateLimit A structure of rate limit parameters
85990 +
85991 + @Return E_OK on success; Error code otherwise.
85992 +
85993 + @Cautions Allowed only following FM_PORT_Init().
85994 + If rate limit is set on a port that need to send PFC frames,
85995 + it might violate the stop transmit timing.
85996 +*//***************************************************************************/
85997 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
85998 +
85999 +/**************************************************************************//**
86000 + @Function FM_PORT_DeleteRateLimit
86001 +
86002 + @Description Calling this routine disables and clears rate limit
86003 + initialization.
86004 +
86005 + May be used for Tx and OP ports only
86006 +
86007 + @Param[in] h_FmPort A handle to a FM Port module.
86008 +
86009 + @Return E_OK on success; Error code otherwise.
86010 +
86011 + @Cautions Allowed only following FM_PORT_Init().
86012 +*//***************************************************************************/
86013 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
86014 +
86015 +/**************************************************************************//**
86016 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
86017 +
86018 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
86019 + This WQ will be blocked upon receiving a PFC frame with this priority.
86020 +
86021 + May be used for Tx ports only.
86022 +
86023 + @Param[in] h_FmPort A handle to a FM Port module.
86024 + @Param[in] prio PFC priority (0-7).
86025 + @Param[in] wq Work Queue (0-7).
86026 +
86027 + @Return E_OK on success; Error code otherwise.
86028 +
86029 + @Cautions Allowed only following FM_PORT_Init().
86030 +*//***************************************************************************/
86031 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
86032 +
86033 +/**************************************************************************//**
86034 + @Function FM_PORT_SetStatisticsCounters
86035 +
86036 + @Description Calling this routine enables/disables port's statistics counters.
86037 + By default, counters are enabled.
86038 +
86039 + May be used for all port types
86040 +
86041 + @Param[in] h_FmPort A handle to a FM Port module.
86042 + @Param[in] enable TRUE to enable, FALSE to disable.
86043 +
86044 + @Return E_OK on success; Error code otherwise.
86045 +
86046 + @Cautions Allowed only following FM_PORT_Init().
86047 +*//***************************************************************************/
86048 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
86049 +
86050 +/**************************************************************************//**
86051 + @Function FM_PORT_SetFrameQueueCounters
86052 +
86053 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
86054 + By default, counters are enabled.
86055 +
86056 + May be used for all ports
86057 +
86058 + @Param[in] h_FmPort A handle to a FM Port module.
86059 + @Param[in] enable TRUE to enable, FALSE to disable.
86060 +
86061 + @Return E_OK on success; Error code otherwise.
86062 +
86063 + @Cautions Allowed only following FM_PORT_Init().
86064 +*//***************************************************************************/
86065 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
86066 +
86067 +/**************************************************************************//**
86068 + @Function FM_PORT_AnalyzePerformanceParams
86069 +
86070 + @Description User may call this routine to so the driver will analyze if the
86071 + basic performance parameters are correct and also the driver may
86072 + suggest of improvements; The basic parameters are FIFO sizes, number
86073 + of DMAs and number of TNUMs for the port.
86074 +
86075 + May be used for all port types
86076 +
86077 + @Param[in] h_FmPort A handle to a FM Port module.
86078 +
86079 + @Return E_OK on success; Error code otherwise.
86080 +
86081 + @Cautions Allowed only following FM_PORT_Init().
86082 +*//***************************************************************************/
86083 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
86084 +
86085 +
86086 +/**************************************************************************//**
86087 + @Function FM_PORT_SetAllocBufCounter
86088 +
86089 + @Description Calling this routine enables/disables BM pool allocate
86090 + buffer counters.
86091 + By default, counters are enabled.
86092 +
86093 + May be used for Rx ports only
86094 +
86095 + @Param[in] h_FmPort A handle to a FM Port module.
86096 + @Param[in] poolId BM pool id.
86097 + @Param[in] enable TRUE to enable, FALSE to disable.
86098 +
86099 + @Return E_OK on success; Error code otherwise.
86100 +
86101 + @Cautions Allowed only following FM_PORT_Init().
86102 +*//***************************************************************************/
86103 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
86104 +
86105 +/**************************************************************************//**
86106 + @Function FM_PORT_GetBmiCounters
86107 +
86108 + @Description Read port's BMI stat counters and place them into
86109 + a designated structure of counters.
86110 +
86111 + @Param[in] h_FmPort A handle to a FM Port module.
86112 + @Param[out] p_BmiStats counters structure
86113 +
86114 + @Return E_OK on success; Error code otherwise.
86115 +
86116 + @Cautions Allowed only following FM_PORT_Init().
86117 +*//***************************************************************************/
86118 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
86119 +
86120 +/**************************************************************************//**
86121 + @Function FM_PORT_GetCounter
86122 +
86123 + @Description Reads one of the FM PORT counters.
86124 +
86125 + @Param[in] h_FmPort A handle to a FM Port module.
86126 + @Param[in] fmPortCounter The requested counter.
86127 +
86128 + @Return Counter's current value.
86129 +
86130 + @Cautions Allowed only following FM_PORT_Init().
86131 + Note that it is user's responsibility to call this routine only
86132 + for enabled counters, and there will be no indication if a
86133 + disabled counter is accessed.
86134 +*//***************************************************************************/
86135 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
86136 +
86137 +/**************************************************************************//**
86138 + @Function FM_PORT_ModifyCounter
86139 +
86140 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86141 +
86142 + @Param[in] h_FmPort A handle to a FM Port module.
86143 + @Param[in] fmPortCounter The requested counter.
86144 + @Param[in] value The requested value to be written into the counter.
86145 +
86146 + @Return E_OK on success; Error code otherwise.
86147 +
86148 + @Cautions Allowed only following FM_PORT_Init().
86149 +*//***************************************************************************/
86150 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
86151 +
86152 +/**************************************************************************//**
86153 + @Function FM_PORT_GetAllocBufCounter
86154 +
86155 + @Description Reads one of the FM PORT buffer counters.
86156 +
86157 + @Param[in] h_FmPort A handle to a FM Port module.
86158 + @Param[in] poolId The requested pool.
86159 +
86160 + @Return Counter's current value.
86161 +
86162 + @Cautions Allowed only following FM_PORT_Init().
86163 + Note that it is user's responsibility to call this routine only
86164 + for enabled counters, and there will be no indication if a
86165 + disabled counter is accessed.
86166 +*//***************************************************************************/
86167 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
86168 +
86169 +/**************************************************************************//**
86170 + @Function FM_PORT_ModifyAllocBufCounter
86171 +
86172 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86173 +
86174 + @Param[in] h_FmPort A handle to a FM Port module.
86175 + @Param[in] poolId The requested pool.
86176 + @Param[in] value The requested value to be written into the counter.
86177 +
86178 + @Return E_OK on success; Error code otherwise.
86179 +
86180 + @Cautions Allowed only following FM_PORT_Init().
86181 +*//***************************************************************************/
86182 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
86183 +
86184 +/**************************************************************************//**
86185 + @Function FM_PORT_AddCongestionGrps
86186 +
86187 + @Description This routine effects the corresponding Tx port.
86188 + It should be called in order to enable pause
86189 + frame transmission in case of congestion in one or more
86190 + of the congestion groups relevant to this port.
86191 + Each call to this routine may add one or more congestion
86192 + groups to be considered relevant to this port.
86193 +
86194 + May be used for Rx, or RX+OP ports only (depending on chip)
86195 +
86196 + @Param[in] h_FmPort A handle to a FM Port module.
86197 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86198 + id's to consider.
86199 +
86200 + @Return E_OK on success; Error code otherwise.
86201 +
86202 + @Cautions Allowed only following FM_PORT_Init().
86203 +*//***************************************************************************/
86204 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86205 +
86206 +/**************************************************************************//**
86207 + @Function FM_PORT_RemoveCongestionGrps
86208 +
86209 + @Description This routine effects the corresponding Tx port. It should be
86210 + called when congestion groups were
86211 + defined for this port and are no longer relevant, or pause
86212 + frames transmitting is not required on their behalf.
86213 + Each call to this routine may remove one or more congestion
86214 + groups to be considered relevant to this port.
86215 +
86216 + May be used for Rx, or RX+OP ports only (depending on chip)
86217 +
86218 + @Param[in] h_FmPort A handle to a FM Port module.
86219 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86220 + id's to consider.
86221 +
86222 + @Return E_OK on success; Error code otherwise.
86223 +
86224 + @Cautions Allowed only following FM_PORT_Init().
86225 +*//***************************************************************************/
86226 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86227 +
86228 +/**************************************************************************//**
86229 + @Function FM_PORT_IsStalled
86230 +
86231 + @Description A routine for checking whether the specified port is stalled.
86232 +
86233 + @Param[in] h_FmPort A handle to a FM Port module.
86234 +
86235 + @Return TRUE if port is stalled, FALSE otherwize
86236 +
86237 + @Cautions Allowed only following FM_PORT_Init().
86238 +*//***************************************************************************/
86239 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
86240 +
86241 +/**************************************************************************//**
86242 + @Function FM_PORT_ReleaseStalled
86243 +
86244 + @Description This routine may be called in case the port was stalled and may
86245 + now be released.
86246 + Note that this routine is available only on older FMan revisions
86247 + (FMan v2, DPAA v1.0 only).
86248 +
86249 + @Param[in] h_FmPort A handle to a FM Port module.
86250 +
86251 + @Return E_OK on success; Error code otherwise.
86252 +
86253 + @Cautions Allowed only following FM_PORT_Init().
86254 +*//***************************************************************************/
86255 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
86256 +
86257 +/**************************************************************************//**
86258 + @Function FM_PORT_SetRxL4ChecksumVerify
86259 +
86260 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
86261 + set/clear the L3/L4 checksum verification (on RX side).
86262 + Note that this takes affect only if hw-parser is enabled!
86263 +
86264 + @Param[in] h_FmPort A handle to a FM Port module.
86265 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
86266 + on frames or not.
86267 +
86268 + @Return E_OK on success; Error code otherwise.
86269 +
86270 + @Cautions Allowed only following FM_PORT_Init().
86271 +*//***************************************************************************/
86272 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
86273 +
86274 +/**************************************************************************//**
86275 + @Function FM_PORT_SetErrorsRoute
86276 +
86277 + @Description Errors selected for this routine will cause a frame with that error
86278 + to be enqueued to error queue.
86279 + Errors not selected for this routine will cause a frame with that error
86280 + to be enqueued to the one of the other port queues.
86281 + By default all errors are defined to be enqueued to error queue.
86282 + Errors that were configured to be discarded (at initialization)
86283 + may not be selected here.
86284 +
86285 + May be used for Rx and OP ports only
86286 +
86287 + @Param[in] h_FmPort A handle to a FM Port module.
86288 + @Param[in] errs A list of errors to enqueue to error queue
86289 +
86290 + @Return E_OK on success; Error code otherwise.
86291 +
86292 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86293 +*//***************************************************************************/
86294 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86295 +
86296 +/**************************************************************************//**
86297 + @Function FM_PORT_SetIMExceptions
86298 +
86299 + @Description Calling this routine enables/disables FM PORT interrupts.
86300 +
86301 + @Param[in] h_FmPort FM PORT module descriptor.
86302 + @Param[in] exception The exception to be selected.
86303 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
86304 +
86305 + @Return E_OK on success; Error code otherwise.
86306 +
86307 + @Cautions Allowed only following FM_PORT_Init().
86308 + This routine should NOT be called from guest-partition
86309 + (i.e. guestId != NCSW_MASTER_ID)
86310 +*//***************************************************************************/
86311 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
86312 +
86313 +/**************************************************************************//*
86314 + @Function FM_PORT_SetPerformanceCounters
86315 +
86316 + @Description Calling this routine enables/disables port's performance counters.
86317 + By default, counters are enabled.
86318 +
86319 + May be used for all port types
86320 +
86321 + @Param[in] h_FmPort A handle to a FM Port module.
86322 + @Param[in] enable TRUE to enable, FALSE to disable.
86323 +
86324 + @Return E_OK on success; Error code otherwise.
86325 +
86326 + @Cautions Allowed only following FM_PORT_Init().
86327 +*//***************************************************************************/
86328 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
86329 +
86330 +/**************************************************************************//*
86331 + @Function FM_PORT_SetPerformanceCountersParams
86332 +
86333 + @Description Calling this routine defines port's performance
86334 + counters parameters.
86335 +
86336 + May be used for all port types
86337 +
86338 + @Param[in] h_FmPort A handle to a FM Port module.
86339 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
86340 + counters parameters.
86341 +
86342 + @Return E_OK on success; Error code otherwise.
86343 +
86344 + @Cautions Allowed only following FM_PORT_Init().
86345 +*//***************************************************************************/
86346 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
86347 +
86348 +/**************************************************************************//**
86349 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
86350 +
86351 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
86352 +
86353 + @{
86354 +*//***************************************************************************/
86355 +
86356 +/**************************************************************************//**
86357 + @Description A structure defining the KG scheme after the parser.
86358 + This is relevant only to change scheme selection mode - from
86359 + direct to indirect and vice versa, or when the scheme is selected directly,
86360 + to select the scheme id.
86361 +
86362 +*//***************************************************************************/
86363 +typedef struct t_FmPcdKgSchemeSelect {
86364 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
86365 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
86366 + Relevant only when 'direct' is TRUE. */
86367 +} t_FmPcdKgSchemeSelect;
86368 +
86369 +/**************************************************************************//**
86370 + @Description A structure of scheme parameters
86371 +*//***************************************************************************/
86372 +typedef struct t_FmPcdPortSchemesParams {
86373 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86374 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
86375 + port to be bound to */
86376 +} t_FmPcdPortSchemesParams;
86377 +
86378 +/**************************************************************************//**
86379 + @Description Union for defining port protocol parameters for parser
86380 +*//***************************************************************************/
86381 +typedef union u_FmPcdHdrPrsOpts {
86382 + /* MPLS */
86383 + struct {
86384 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
86385 + interpreted as described in HW spec table. When the bit
86386 + is cleared, the parser will advance to MPLS next parse */
86387 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
86388 + } mplsPrsOptions;
86389 + /* VLAN */
86390 + struct {
86391 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
86392 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86393 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
86394 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86395 + } vlanPrsOptions;
86396 + /* PPP */
86397 + struct{
86398 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
86399 + } pppoePrsOptions;
86400 +
86401 + /* IPV6 */
86402 + struct{
86403 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
86404 + } ipv6PrsOptions;
86405 +
86406 + /* UDP */
86407 + struct{
86408 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86409 + } udpPrsOptions;
86410 +
86411 + /* TCP */
86412 + struct {
86413 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86414 + } tcpPrsOptions;
86415 +} u_FmPcdHdrPrsOpts;
86416 +
86417 +/**************************************************************************//**
86418 + @Description A structure for defining each header for the parser
86419 +*//***************************************************************************/
86420 +typedef struct t_FmPcdPrsAdditionalHdrParams {
86421 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
86422 + to indicate that sw parser is to run first
86423 + (before HW parser, and independent of the
86424 + existence of any protocol), in this case,
86425 + swPrsEnable must be set, and all other
86426 + parameters are irrelevant. */
86427 + bool errDisable; /**< TRUE to disable error indication */
86428 + bool swPrsEnable; /**< Enable jump to SW parser when this
86429 + header is recognized by the HW parser. */
86430 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
86431 + attachments exists for the same header,
86432 + (in the main sw parser code) use this
86433 + index to distinguish between them. */
86434 + bool usePrsOpts; /**< TRUE to use parser options. */
86435 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
86436 + defining the parser options selected.*/
86437 +} t_FmPcdPrsAdditionalHdrParams;
86438 +
86439 +/**************************************************************************//**
86440 + @Description struct for defining port PCD parameters
86441 +*//***************************************************************************/
86442 +typedef struct t_FmPortPcdPrsParams {
86443 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
86444 + port information into the parser result. This information
86445 + may be extracted by Keygen and be used for frames
86446 + distribution when a per-port distinction is required,
86447 + it may also be used as a port logical id for analyzing
86448 + incoming frames. */
86449 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
86450 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
86451 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
86452 + NOTE: this field is not valid when the FM is in "guest" mode
86453 + and IPC is not available. */
86454 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
86455 + special parameters */
86456 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
86457 + /**< 'numOfHdrsWithAdditionalParams' structures
86458 + of additional parameters
86459 + for each header that requires them */
86460 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
86461 + indicate a VLAN tag (in addition to the TPID values
86462 + 0x8100 and 0x88A8). */
86463 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
86464 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
86465 + indicate a VLAN tag (in addition to the TPID values
86466 + 0x8100 and 0x88A8). */
86467 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
86468 +} t_FmPortPcdPrsParams;
86469 +
86470 +/**************************************************************************//**
86471 + @Description struct for defining coarse alassification parameters
86472 +*//***************************************************************************/
86473 +typedef struct t_FmPortPcdCcParams {
86474 + t_Handle h_CcTree; /**< A handle to a CC tree */
86475 +} t_FmPortPcdCcParams;
86476 +
86477 +/**************************************************************************//**
86478 + @Description struct for defining keygen parameters
86479 +*//***************************************************************************/
86480 +typedef struct t_FmPortPcdKgParams {
86481 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86482 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
86483 + /**< Array of 'numOfSchemes' schemes handles for the
86484 + port to be bound to */
86485 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
86486 + regardless of parser result */
86487 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
86488 + as returned by FM_PCD_KgSetScheme */
86489 +} t_FmPortPcdKgParams;
86490 +
86491 +/**************************************************************************//**
86492 + @Description struct for defining policer parameters
86493 +*//***************************************************************************/
86494 +typedef struct t_FmPortPcdPlcrParams {
86495 + t_Handle h_Profile; /**< Selected profile handle */
86496 +} t_FmPortPcdPlcrParams;
86497 +
86498 +/**************************************************************************//**
86499 + @Description struct for defining port PCD parameters
86500 +*//***************************************************************************/
86501 +typedef struct t_FmPortPcdParams {
86502 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
86503 + Describes the active PCD engines for this port. */
86504 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
86505 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
86506 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
86507 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
86508 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
86509 + following cases:
86510 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
86511 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
86512 + or if any flow uses a KG scheme were policer
86513 + profile is not generated
86514 + ('bypassPlcrProfileGeneration selected'). */
86515 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
86516 +#if (DPAA_VERSION >= 11)
86517 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
86518 +#endif /* (DPAA_VERSION >= 11) */
86519 +} t_FmPortPcdParams;
86520 +
86521 +/**************************************************************************//**
86522 + @Description A structure for defining the Parser starting point
86523 +*//***************************************************************************/
86524 +typedef struct t_FmPcdPrsStart {
86525 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
86526 + start parsing */
86527 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
86528 + 'parsingOffset' */
86529 +} t_FmPcdPrsStart;
86530 +
86531 +#if (DPAA_VERSION >= 11)
86532 +/**************************************************************************//**
86533 + @Description struct for defining external buffer margins
86534 +*//***************************************************************************/
86535 +typedef struct t_FmPortVSPAllocParams {
86536 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
86537 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
86538 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
86539 + if relevant function called for Rx port */
86540 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
86541 +} t_FmPortVSPAllocParams;
86542 +#endif /* (DPAA_VERSION >= 11) */
86543 +
86544 +
86545 +/**************************************************************************//**
86546 + @Function FM_PORT_SetPCD
86547 +
86548 + @Description Calling this routine defines the port's PCD configuration.
86549 + It changes it from its default configuration which is PCD
86550 + disabled (BMI to BMI) and configures it according to the passed
86551 + parameters.
86552 +
86553 + May be used for Rx and OP ports only
86554 +
86555 + @Param[in] h_FmPort A handle to a FM Port module.
86556 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
86557 + configuration.
86558 +
86559 + @Return E_OK on success; Error code otherwise.
86560 +
86561 + @Cautions Allowed only following FM_PORT_Init().
86562 +*//***************************************************************************/
86563 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
86564 +
86565 +/**************************************************************************//**
86566 + @Function FM_PORT_DeletePCD
86567 +
86568 + @Description Calling this routine releases the port's PCD configuration.
86569 + The port returns to its default configuration which is PCD
86570 + disabled (BMI to BMI) and all PCD configuration is removed.
86571 +
86572 + May be used for Rx and OP ports which are
86573 + in PCD mode only
86574 +
86575 + @Param[in] h_FmPort A handle to a FM Port module.
86576 +
86577 + @Return E_OK on success; Error code otherwise.
86578 +
86579 + @Cautions Allowed only following FM_PORT_Init().
86580 +*//***************************************************************************/
86581 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
86582 +
86583 +/**************************************************************************//**
86584 + @Function FM_PORT_AttachPCD
86585 +
86586 + @Description This routine may be called after FM_PORT_DetachPCD was called,
86587 + to return to the originally configured PCD support flow.
86588 + The couple of routines are used to allow PCD configuration changes
86589 + that demand that PCD will not be used while changes take place.
86590 +
86591 + May be used for Rx and OP ports which are
86592 + in PCD mode only
86593 +
86594 + @Param[in] h_FmPort A handle to a FM Port module.
86595 +
86596 + @Return E_OK on success; Error code otherwise.
86597 +
86598 + @Cautions Allowed only following FM_PORT_Init().
86599 +*//***************************************************************************/
86600 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
86601 +
86602 +/**************************************************************************//**
86603 + @Function FM_PORT_DetachPCD
86604 +
86605 + @Description Calling this routine detaches the port from its PCD functionality.
86606 + The port returns to its default flow which is BMI to BMI.
86607 +
86608 + May be used for Rx and OP ports which are
86609 + in PCD mode only
86610 +
86611 + @Param[in] h_FmPort A handle to a FM Port module.
86612 +
86613 + @Return E_OK on success; Error code otherwise.
86614 +
86615 + @Cautions Allowed only following FM_PORT_AttachPCD().
86616 +*//***************************************************************************/
86617 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
86618 +
86619 +/**************************************************************************//**
86620 + @Function FM_PORT_PcdPlcrAllocProfiles
86621 +
86622 + @Description This routine may be called only for ports that use the Policer in
86623 + order to allocate private policer profiles.
86624 +
86625 + @Param[in] h_FmPort A handle to a FM Port module.
86626 + @Param[in] numOfProfiles The number of required policer profiles
86627 +
86628 + @Return E_OK on success; Error code otherwise.
86629 +
86630 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86631 + and before FM_PORT_SetPCD().
86632 +*//***************************************************************************/
86633 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
86634 +
86635 +/**************************************************************************//**
86636 + @Function FM_PORT_PcdPlcrFreeProfiles
86637 +
86638 + @Description This routine should be called for freeing private policer profiles.
86639 +
86640 + @Param[in] h_FmPort A handle to a FM Port module.
86641 +
86642 + @Return E_OK on success; Error code otherwise.
86643 +
86644 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
86645 + and before FM_PORT_SetPCD().
86646 +*//***************************************************************************/
86647 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
86648 +
86649 +#if (DPAA_VERSION >= 11)
86650 +/**************************************************************************//**
86651 + @Function FM_PORT_VSPAlloc
86652 +
86653 + @Description This routine allocated VSPs per port and forces the port to work
86654 + in VSP mode. Note that the port is initialized by default with the
86655 + physical-storage-profile only.
86656 +
86657 + @Param[in] h_FmPort A handle to a FM Port module.
86658 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
86659 +
86660 + @Return E_OK on success; Error code otherwise.
86661 +
86662 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
86663 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
86664 +*//***************************************************************************/
86665 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
86666 +#endif /* (DPAA_VERSION >= 11) */
86667 +
86668 +/**************************************************************************//**
86669 + @Function FM_PORT_PcdKgModifyInitialScheme
86670 +
86671 + @Description This routine may be called only for ports that use the keygen in
86672 + order to change the initial scheme frame should be routed to.
86673 + The change may be of a scheme id (in case of direct mode),
86674 + from direct to indirect, or from indirect to direct - specifying the scheme id.
86675 +
86676 + @Param[in] h_FmPort A handle to a FM Port module.
86677 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
86678 + a scheme is direct/indirect, and if direct - scheme id.
86679 +
86680 + @Return E_OK on success; Error code otherwise.
86681 +
86682 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86683 +*//***************************************************************************/
86684 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
86685 +
86686 +/**************************************************************************//**
86687 + @Function FM_PORT_PcdPlcrModifyInitialProfile
86688 +
86689 + @Description This routine may be called for ports with flows
86690 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
86691 + only, to change the initial Policer profile frame should be
86692 + routed to. The change may be of a profile and/or absolute/direct
86693 + mode selection.
86694 +
86695 + @Param[in] h_FmPort A handle to a FM Port module.
86696 + @Param[in] h_Profile Policer profile handle
86697 +
86698 + @Return E_OK on success; Error code otherwise.
86699 +
86700 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86701 +*//***************************************************************************/
86702 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
86703 +
86704 +/**************************************************************************//**
86705 + @Function FM_PORT_PcdCcModifyTree
86706 +
86707 + @Description This routine may be called for ports that use coarse classification tree
86708 + if the user wishes to replace the tree. The routine may not be called while port
86709 + receives packets using the PCD functionalities, therefor port must be first detached
86710 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
86711 +
86712 + @Param[in] h_FmPort A handle to a FM Port module.
86713 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
86714 + the BuildTree routine.
86715 +
86716 + @Return E_OK on success; Error code otherwise.
86717 +
86718 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
86719 +*//***************************************************************************/
86720 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
86721 +
86722 +/**************************************************************************//**
86723 + @Function FM_PORT_PcdKgBindSchemes
86724 +
86725 + @Description These routines may be called for adding more schemes for the
86726 + port to be bound to. The selected schemes are not added,
86727 + just this specific port starts using them.
86728 +
86729 + @Param[in] h_FmPort A handle to a FM Port module.
86730 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
86731 +
86732 + @Return E_OK on success; Error code otherwise.
86733 +
86734 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86735 +*//***************************************************************************/
86736 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
86737 +
86738 +/**************************************************************************//**
86739 + @Function FM_PORT_PcdKgUnbindSchemes
86740 +
86741 + @Description These routines may be called for adding more schemes for the
86742 + port to be bound to. The selected schemes are not removed or invalidated,
86743 + just this specific port stops using them.
86744 +
86745 + @Param[in] h_FmPort A handle to a FM Port module.
86746 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
86747 +
86748 + @Return E_OK on success; Error code otherwise.
86749 +
86750 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
86751 +*//***************************************************************************/
86752 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
86753 +
86754 +/**************************************************************************//**
86755 + @Function FM_PORT_GetIPv4OptionsCount
86756 +
86757 + @Description TODO
86758 +
86759 + @Param[in] h_FmPort A handle to a FM Port module.
86760 + @Param[out] p_Ipv4OptionsCount will hold the counter value
86761 +
86762 + @Return E_OK on success; Error code otherwise.
86763 +
86764 + @Cautions Allowed only following FM_PORT_Init()
86765 +*//***************************************************************************/
86766 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
86767 +
86768 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
86769 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
86770 +
86771 +
86772 +/**************************************************************************//**
86773 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
86774 +
86775 + @Description FM Port Runtime data unit API functions, definitions and enums.
86776 + This API is valid only if working in Independent-Mode.
86777 +
86778 + @{
86779 +*//***************************************************************************/
86780 +
86781 +/**************************************************************************//**
86782 + @Function FM_PORT_ImTx
86783 +
86784 + @Description Tx function, called to transmit a data buffer on the port.
86785 +
86786 + @Param[in] h_FmPort A handle to a FM Port module.
86787 + @Param[in] p_Data A pointer to an LCP data buffer.
86788 + @Param[in] length Size of data for transmission.
86789 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
86790 + of a frame, including a single buffer frame
86791 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86792 +
86793 + @Return E_OK on success; Error code otherwise.
86794 +
86795 + @Cautions Allowed only following FM_PORT_Init().
86796 + NOTE - This routine can be used only when working in
86797 + Independent-Mode mode.
86798 +*//***************************************************************************/
86799 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
86800 + uint8_t *p_Data,
86801 + uint16_t length,
86802 + bool lastBuffer,
86803 + t_Handle h_BufContext);
86804 +
86805 +/**************************************************************************//**
86806 + @Function FM_PORT_ImTxConf
86807 +
86808 + @Description Tx port confirmation routine, optional, may be called to verify
86809 + transmission of all frames. The procedure performed by this
86810 + routine will be performed automatically on next buffer transmission,
86811 + but if desired, calling this routine will invoke this action on
86812 + demand.
86813 +
86814 + @Param[in] h_FmPort A handle to a FM Port module.
86815 +
86816 + @Cautions Allowed only following FM_PORT_Init().
86817 + NOTE - This routine can be used only when working in
86818 + Independent-Mode mode.
86819 +*//***************************************************************************/
86820 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
86821 +
86822 +/**************************************************************************//**
86823 + @Function FM_PORT_ImRx
86824 +
86825 + @Description Rx function, may be called to poll for received buffers.
86826 + Normally, Rx process is invoked by the driver on Rx interrupt.
86827 + Alternatively, this routine may be called on demand.
86828 +
86829 + @Param[in] h_FmPort A handle to a FM Port module.
86830 +
86831 + @Return E_OK on success; Error code otherwise.
86832 +
86833 + @Cautions Allowed only following FM_PORT_Init().
86834 + NOTE - This routine can be used only when working in
86835 + Independent-Mode mode.
86836 +*//***************************************************************************/
86837 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
86838 +
86839 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
86840 +/** @} */ /* end of FM_PORT_grp group */
86841 +/** @} */ /* end of FM_grp group */
86842 +
86843 +
86844 +
86845 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
86846 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
86847 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
86848 +
86849 +
86850 +#endif /* __FM_PORT_EXT */
86851 --- /dev/null
86852 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
86853 @@ -0,0 +1,619 @@
86854 +/*
86855 + * Copyright 2008-2012 Freescale Semiconductor Inc.
86856 + *
86857 + * Redistribution and use in source and binary forms, with or without
86858 + * modification, are permitted provided that the following conditions are met:
86859 + * * Redistributions of source code must retain the above copyright
86860 + * notice, this list of conditions and the following disclaimer.
86861 + * * Redistributions in binary form must reproduce the above copyright
86862 + * notice, this list of conditions and the following disclaimer in the
86863 + * documentation and/or other materials provided with the distribution.
86864 + * * Neither the name of Freescale Semiconductor nor the
86865 + * names of its contributors may be used to endorse or promote products
86866 + * derived from this software without specific prior written permission.
86867 + *
86868 + *
86869 + * ALTERNATIVELY, this software may be distributed under the terms of the
86870 + * GNU General Public License ("GPL") as published by the Free Software
86871 + * Foundation, either version 2 of that License or (at your option) any
86872 + * later version.
86873 + *
86874 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
86875 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
86876 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
86877 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
86878 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
86879 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
86880 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
86881 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
86882 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
86883 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
86884 + */
86885 +
86886 +
86887 +/**************************************************************************//**
86888 + @File fm_rtc_ext.h
86889 +
86890 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
86891 +
86892 + @Cautions None.
86893 +*//***************************************************************************/
86894 +
86895 +#ifndef __FM_RTC_EXT_H__
86896 +#define __FM_RTC_EXT_H__
86897 +
86898 +
86899 +#include "error_ext.h"
86900 +#include "std_ext.h"
86901 +#include "fsl_fman_rtc.h"
86902 +
86903 +/**************************************************************************//**
86904 +
86905 + @Group FM_grp Frame Manager API
86906 +
86907 + @Description FM API functions, definitions and enums
86908 +
86909 + @{
86910 +*//***************************************************************************/
86911 +
86912 +/**************************************************************************//**
86913 + @Group fm_rtc_grp FM RTC
86914 +
86915 + @Description FM RTC functions, definitions and enums.
86916 +
86917 + @{
86918 +*//***************************************************************************/
86919 +
86920 +/**************************************************************************//**
86921 + @Group fm_rtc_init_grp FM RTC Initialization Unit
86922 +
86923 + @Description FM RTC initialization API.
86924 +
86925 + @{
86926 +*//***************************************************************************/
86927 +
86928 +/**************************************************************************//**
86929 + @Description FM RTC Alarm Polarity Options.
86930 +*//***************************************************************************/
86931 +typedef enum e_FmRtcAlarmPolarity
86932 +{
86933 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
86934 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
86935 +} e_FmRtcAlarmPolarity;
86936 +
86937 +/**************************************************************************//**
86938 + @Description FM RTC Trigger Polarity Options.
86939 +*//***************************************************************************/
86940 +typedef enum e_FmRtcTriggerPolarity
86941 +{
86942 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
86943 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
86944 +} e_FmRtcTriggerPolarity;
86945 +
86946 +/**************************************************************************//**
86947 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
86948 +*//***************************************************************************/
86949 +typedef enum e_FmSrcClock
86950 +{
86951 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
86952 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
86953 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
86954 +}e_FmSrcClk;
86955 +
86956 +/**************************************************************************//**
86957 + @Description FM RTC configuration parameters structure.
86958 +
86959 + This structure should be passed to FM_RTC_Config().
86960 +*//***************************************************************************/
86961 +typedef struct t_FmRtcParams
86962 +{
86963 + t_Handle h_Fm; /**< FM Handle*/
86964 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
86965 + t_Handle h_App; /**< A handle to an application layer object; This handle will
86966 + be passed by the driver upon calling the above callbacks */
86967 +} t_FmRtcParams;
86968 +
86969 +
86970 +/**************************************************************************//**
86971 + @Function FM_RTC_Config
86972 +
86973 + @Description Configures the FM RTC module according to user's parameters.
86974 +
86975 + The driver assigns default values to some FM RTC parameters.
86976 + These parameters can be overwritten using the advanced
86977 + configuration routines.
86978 +
86979 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
86980 +
86981 + @Return Handle to the new FM RTC object; NULL pointer on failure.
86982 +
86983 + @Cautions None
86984 +*//***************************************************************************/
86985 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
86986 +
86987 +/**************************************************************************//**
86988 + @Function FM_RTC_Init
86989 +
86990 + @Description Initializes the FM RTC driver and hardware.
86991 +
86992 + @Param[in] h_FmRtc - Handle to FM RTC object.
86993 +
86994 + @Return E_OK on success; Error code otherwise.
86995 +
86996 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
86997 +*//***************************************************************************/
86998 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
86999 +
87000 +/**************************************************************************//**
87001 + @Function FM_RTC_Free
87002 +
87003 + @Description Frees the FM RTC object and all allocated resources.
87004 +
87005 + @Param[in] h_FmRtc - Handle to FM RTC object.
87006 +
87007 + @Return E_OK on success; Error code otherwise.
87008 +
87009 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87010 +*//***************************************************************************/
87011 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
87012 +
87013 +
87014 +/**************************************************************************//**
87015 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
87016 +
87017 + @Description FM RTC advanced configuration functions.
87018 +
87019 + @{
87020 +*//***************************************************************************/
87021 +
87022 +/**************************************************************************//**
87023 + @Function FM_RTC_ConfigPeriod
87024 +
87025 + @Description Configures the period of the timestamp if different than
87026 + default [DEFAULT_clockPeriod].
87027 +
87028 + @Param[in] h_FmRtc - Handle to FM RTC object.
87029 + @Param[in] period - Period in nano-seconds.
87030 +
87031 + @Return E_OK on success; Error code otherwise.
87032 +
87033 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87034 +*//***************************************************************************/
87035 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
87036 +
87037 +/**************************************************************************//**
87038 + @Function FM_RTC_ConfigSourceClock
87039 +
87040 + @Description Configures the source clock of the RTC.
87041 +
87042 + @Param[in] h_FmRtc - Handle to FM RTC object.
87043 + @Param[in] srcClk - Source clock selection.
87044 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
87045 +
87046 + @Return E_OK on success; Error code otherwise.
87047 +
87048 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87049 +*//***************************************************************************/
87050 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
87051 + e_FmSrcClk srcClk,
87052 + uint32_t freqInMhz);
87053 +
87054 +/**************************************************************************//**
87055 + @Function FM_RTC_ConfigPulseRealignment
87056 +
87057 + @Description Configures the RTC to automatic FIPER pulse realignment in
87058 + response to timer adjustments [DEFAULT_pulseRealign]
87059 +
87060 + In this mode, the RTC clock is identical to the source clock.
87061 + This feature can be useful when the system contains an external
87062 + RTC with inherent frequency compensation.
87063 +
87064 + @Param[in] h_FmRtc - Handle to FM RTC object.
87065 + @Param[in] enable - TRUE to enable automatic realignment.
87066 +
87067 + @Return E_OK on success; Error code otherwise.
87068 +
87069 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87070 +*//***************************************************************************/
87071 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
87072 +
87073 +/**************************************************************************//**
87074 + @Function FM_RTC_ConfigFrequencyBypass
87075 +
87076 + @Description Configures the RTC to bypass the frequency compensation
87077 + mechanism. [DEFAULT_bypass]
87078 +
87079 + In this mode, the RTC clock is identical to the source clock.
87080 + This feature can be useful when the system contains an external
87081 + RTC with inherent frequency compensation.
87082 +
87083 + @Param[in] h_FmRtc - Handle to FM RTC object.
87084 + @Param[in] enabled - TRUE to bypass frequency compensation;
87085 + FALSE otherwise.
87086 +
87087 + @Return E_OK on success; Error code otherwise.
87088 +
87089 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87090 +*//***************************************************************************/
87091 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
87092 +
87093 +/**************************************************************************//**
87094 + @Function FM_RTC_ConfigInvertedInputClockPhase
87095 +
87096 + @Description Configures the RTC to invert the source clock phase on input.
87097 + [DEFAULT_invertInputClkPhase]
87098 +
87099 + @Param[in] h_FmRtc - Handle to FM RTC object.
87100 + @Param[in] inverted - TRUE to invert the source clock phase on input.
87101 + FALSE otherwise.
87102 +
87103 + @Return E_OK on success; Error code otherwise.
87104 +
87105 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87106 +*//***************************************************************************/
87107 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
87108 +
87109 +/**************************************************************************//**
87110 + @Function FM_RTC_ConfigInvertedOutputClockPhase
87111 +
87112 + @Description Configures the RTC to invert the output clock phase.
87113 + [DEFAULT_invertOutputClkPhase]
87114 +
87115 + @Param[in] h_FmRtc - Handle to FM RTC object.
87116 + @Param[in] inverted - TRUE to invert the output clock phase.
87117 + FALSE otherwise.
87118 +
87119 + @Return E_OK on success; Error code otherwise.
87120 +
87121 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87122 +*//***************************************************************************/
87123 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
87124 +
87125 +/**************************************************************************//**
87126 + @Function FM_RTC_ConfigOutputClockDivisor
87127 +
87128 + @Description Configures the divisor for generating the output clock from
87129 + the RTC clock. [DEFAULT_outputClockDivisor]
87130 +
87131 + @Param[in] h_FmRtc - Handle to FM RTC object.
87132 + @Param[in] divisor - Divisor for generation of the output clock.
87133 +
87134 + @Return E_OK on success; Error code otherwise.
87135 +
87136 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87137 +*//***************************************************************************/
87138 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
87139 +
87140 +/**************************************************************************//**
87141 + @Function FM_RTC_ConfigAlarmPolarity
87142 +
87143 + @Description Configures the polarity (active-high/active-low) of a specific
87144 + alarm signal. [DEFAULT_alarmPolarity]
87145 +
87146 + @Param[in] h_FmRtc - Handle to FM RTC object.
87147 + @Param[in] alarmId - Alarm ID.
87148 + @Param[in] alarmPolarity - Alarm polarity.
87149 +
87150 + @Return E_OK on success; Error code otherwise.
87151 +
87152 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87153 +*//***************************************************************************/
87154 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
87155 + uint8_t alarmId,
87156 + e_FmRtcAlarmPolarity alarmPolarity);
87157 +
87158 +/**************************************************************************//**
87159 + @Function FM_RTC_ConfigExternalTriggerPolarity
87160 +
87161 + @Description Configures the polarity (rising/falling edge) of a specific
87162 + external trigger signal. [DEFAULT_triggerPolarity]
87163 +
87164 + @Param[in] h_FmRtc - Handle to FM RTC object.
87165 + @Param[in] triggerId - Trigger ID.
87166 + @Param[in] triggerPolarity - Trigger polarity.
87167 +
87168 + @Return E_OK on success; Error code otherwise.
87169 +
87170 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87171 +*//***************************************************************************/
87172 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
87173 + uint8_t triggerId,
87174 + e_FmRtcTriggerPolarity triggerPolarity);
87175 +
87176 +/** @} */ /* end of fm_rtc_adv_config_grp */
87177 +/** @} */ /* end of fm_rtc_init_grp */
87178 +
87179 +
87180 +/**************************************************************************//**
87181 + @Group fm_rtc_control_grp FM RTC Control Unit
87182 +
87183 + @Description FM RTC runtime control API.
87184 +
87185 + @{
87186 +*//***************************************************************************/
87187 +
87188 +/**************************************************************************//**
87189 + @Function t_FmRtcExceptionsCallback
87190 +
87191 + @Description Exceptions user callback routine, used for RTC different mechanisms.
87192 +
87193 + @Param[in] h_App - User's application descriptor.
87194 + @Param[in] id - source id.
87195 +*//***************************************************************************/
87196 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
87197 +
87198 +/**************************************************************************//**
87199 + @Description FM RTC alarm parameters.
87200 +*//***************************************************************************/
87201 +typedef struct t_FmRtcAlarmParams {
87202 + uint8_t alarmId; /**< 0 or 1 */
87203 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
87204 + should go off - must be a multiple of
87205 + the RTC period */
87206 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
87207 + reaches alarmTime */
87208 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
87209 +} t_FmRtcAlarmParams;
87210 +
87211 +/**************************************************************************//**
87212 + @Description FM RTC Periodic Pulse parameters.
87213 +*//***************************************************************************/
87214 +typedef struct t_FmRtcPeriodicPulseParams {
87215 + uint8_t periodicPulseId; /**< 0 or 1 */
87216 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
87217 + a multiple of the RTC period */
87218 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
87219 + periodicPulsePeriod. */
87220 +} t_FmRtcPeriodicPulseParams;
87221 +
87222 +/**************************************************************************//**
87223 + @Description FM RTC Periodic Pulse parameters.
87224 +*//***************************************************************************/
87225 +typedef struct t_FmRtcExternalTriggerParams {
87226 + uint8_t externalTriggerId; /**< 0 or 1 */
87227 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
87228 + an external signal */
87229 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
87230 + periodicPulsePeriod. */
87231 +} t_FmRtcExternalTriggerParams;
87232 +
87233 +
87234 +/**************************************************************************//**
87235 + @Function FM_RTC_Enable
87236 +
87237 + @Description Enable the RTC (time count is started).
87238 +
87239 + The user can select to resume the time count from previous
87240 + point, or to restart the time count.
87241 +
87242 + @Param[in] h_FmRtc - Handle to FM RTC object.
87243 + @Param[in] resetClock - Restart the time count from zero.
87244 +
87245 + @Return E_OK on success; Error code otherwise.
87246 +
87247 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87248 +*//***************************************************************************/
87249 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
87250 +
87251 +/**************************************************************************//**
87252 + @Function FM_RTC_Disable
87253 +
87254 + @Description Disables the RTC (time count is stopped).
87255 +
87256 + @Param[in] h_FmRtc - Handle to FM RTC object.
87257 +
87258 + @Return E_OK on success; Error code otherwise.
87259 +
87260 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87261 +*//***************************************************************************/
87262 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
87263 +
87264 +/**************************************************************************//**
87265 + @Function FM_RTC_SetClockOffset
87266 +
87267 + @Description Sets the clock offset (usually relative to another clock).
87268 +
87269 + The user can pass a negative offset value.
87270 +
87271 + @Param[in] h_FmRtc - Handle to FM RTC object.
87272 + @Param[in] offset - New clock offset (in nanoseconds).
87273 +
87274 + @Return E_OK on success; Error code otherwise.
87275 +
87276 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87277 +*//***************************************************************************/
87278 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
87279 +
87280 +/**************************************************************************//**
87281 + @Function FM_RTC_SetAlarm
87282 +
87283 + @Description Schedules an alarm event to a given RTC time.
87284 +
87285 + @Param[in] h_FmRtc - Handle to FM RTC object.
87286 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
87287 +
87288 + @Return E_OK on success; Error code otherwise.
87289 +
87290 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87291 + Must be called only prior to FM_RTC_Enable().
87292 +*//***************************************************************************/
87293 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
87294 +
87295 +/**************************************************************************//**
87296 + @Function FM_RTC_SetPeriodicPulse
87297 +
87298 + @Description Sets a periodic pulse.
87299 +
87300 + @Param[in] h_FmRtc - Handle to FM RTC object.
87301 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
87302 +
87303 + @Return E_OK on success; Error code otherwise.
87304 +
87305 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87306 + Must be called only prior to FM_RTC_Enable().
87307 +*//***************************************************************************/
87308 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
87309 +
87310 +/**************************************************************************//**
87311 + @Function FM_RTC_ClearPeriodicPulse
87312 +
87313 + @Description Clears a periodic pulse.
87314 +
87315 + @Param[in] h_FmRtc - Handle to FM RTC object.
87316 + @Param[in] periodicPulseId - Periodic pulse id.
87317 +
87318 + @Return E_OK on success; Error code otherwise.
87319 +
87320 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87321 +*//***************************************************************************/
87322 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
87323 +
87324 +/**************************************************************************//**
87325 + @Function FM_RTC_SetExternalTrigger
87326 +
87327 + @Description Sets an external trigger indication and define a callback
87328 + routine to be called on such event.
87329 +
87330 + @Param[in] h_FmRtc - Handle to FM RTC object.
87331 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
87332 +
87333 + @Return E_OK on success; Error code otherwise.
87334 +
87335 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87336 +*//***************************************************************************/
87337 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
87338 +
87339 +/**************************************************************************//**
87340 + @Function FM_RTC_ClearExternalTrigger
87341 +
87342 + @Description Clears external trigger indication.
87343 +
87344 + @Param[in] h_FmRtc - Handle to FM RTC object.
87345 + @Param[in] id - External Trigger id.
87346 +
87347 + @Return E_OK on success; Error code otherwise.
87348 +
87349 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87350 +*//***************************************************************************/
87351 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
87352 +
87353 +/**************************************************************************//**
87354 + @Function FM_RTC_GetExternalTriggerTimeStamp
87355 +
87356 + @Description Reads the External Trigger TimeStamp.
87357 +
87358 + @Param[in] h_FmRtc - Handle to FM RTC object.
87359 + @Param[in] triggerId - External Trigger id.
87360 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
87361 +
87362 + @Return E_OK on success; Error code otherwise.
87363 +
87364 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87365 +*//***************************************************************************/
87366 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
87367 + uint8_t triggerId,
87368 + uint64_t *p_TimeStamp);
87369 +
87370 +/**************************************************************************//**
87371 + @Function FM_RTC_GetCurrentTime
87372 +
87373 + @Description Returns the current RTC time.
87374 +
87375 + @Param[in] h_FmRtc - Handle to FM RTC object.
87376 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
87377 +
87378 + @Return E_OK on success; Error code otherwise.
87379 +
87380 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87381 +*//***************************************************************************/
87382 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
87383 +
87384 +/**************************************************************************//**
87385 + @Function FM_RTC_SetCurrentTime
87386 +
87387 + @Description Sets the current RTC time.
87388 +
87389 + @Param[in] h_FmRtc - Handle to FM RTC object.
87390 + @Param[in] ts - The new time stamp (in nanoseconds).
87391 +
87392 + @Return E_OK on success; Error code otherwise.
87393 +
87394 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87395 +*//***************************************************************************/
87396 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
87397 +
87398 +/**************************************************************************//**
87399 + @Function FM_RTC_GetFreqCompensation
87400 +
87401 + @Description Retrieves the frequency compensation value
87402 +
87403 + @Param[in] h_FmRtc - Handle to FM RTC object.
87404 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
87405 +
87406 + @Return E_OK on success; Error code otherwise.
87407 +
87408 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87409 +*//***************************************************************************/
87410 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
87411 +
87412 +/**************************************************************************//**
87413 + @Function FM_RTC_SetFreqCompensation
87414 +
87415 + @Description Sets a new frequency compensation value.
87416 +
87417 + @Param[in] h_FmRtc - Handle to FM RTC object.
87418 + @Param[in] freqCompensation - The new frequency compensation value to set.
87419 +
87420 + @Return E_OK on success; Error code otherwise.
87421 +
87422 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87423 +*//***************************************************************************/
87424 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
87425 +
87426 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
87427 +/**************************************************************************//**
87428 +*@Function FM_RTC_EnableInterrupt
87429 +*
87430 +*@Description Enable interrupt of FM RTC.
87431 +*
87432 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87433 +*@Param[in] events - Interrupt events.
87434 +*
87435 +*@Return E_OK on success; Error code otherwise.
87436 +*//***************************************************************************/
87437 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
87438 +
87439 +/**************************************************************************//**
87440 +*@Function FM_RTC_DisableInterrupt
87441 +*
87442 +*@Description Disable interrupt of FM RTC.
87443 +*
87444 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87445 +*@Param[in] events - Interrupt events.
87446 +*
87447 +*@Return E_OK on success; Error code otherwise.
87448 +*//***************************************************************************/
87449 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
87450 +#endif
87451 +
87452 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87453 +/**************************************************************************//**
87454 + @Function FM_RTC_DumpRegs
87455 +
87456 + @Description Dumps all FM registers
87457 +
87458 + @Param[in] h_FmRtc A handle to an FM RTC Module.
87459 +
87460 + @Return E_OK on success;
87461 +
87462 + @Cautions Allowed only FM_Init().
87463 +*//***************************************************************************/
87464 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
87465 +#endif /* (defined(DEBUG_ERRORS) && ... */
87466 +
87467 +/** @} */ /* end of fm_rtc_control_grp */
87468 +/** @} */ /* end of fm_rtc_grp */
87469 +/** @} */ /* end of FM_grp group */
87470 +
87471 +
87472 +#endif /* __FM_RTC_EXT_H__ */
87473 --- /dev/null
87474 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87475 @@ -0,0 +1,411 @@
87476 +/*
87477 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87478 + *
87479 + * Redistribution and use in source and binary forms, with or without
87480 + * modification, are permitted provided that the following conditions are met:
87481 + * * Redistributions of source code must retain the above copyright
87482 + * notice, this list of conditions and the following disclaimer.
87483 + * * Redistributions in binary form must reproduce the above copyright
87484 + * notice, this list of conditions and the following disclaimer in the
87485 + * documentation and/or other materials provided with the distribution.
87486 + * * Neither the name of Freescale Semiconductor nor the
87487 + * names of its contributors may be used to endorse or promote products
87488 + * derived from this software without specific prior written permission.
87489 + *
87490 + *
87491 + * ALTERNATIVELY, this software may be distributed under the terms of the
87492 + * GNU General Public License ("GPL") as published by the Free Software
87493 + * Foundation, either version 2 of that License or (at your option) any
87494 + * later version.
87495 + *
87496 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87497 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87498 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87499 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87500 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87501 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87502 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87503 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87504 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87505 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87506 + */
87507 +
87508 +
87509 +/**************************************************************************//**
87510 + @File fm_vsp_ext.h
87511 +
87512 + @Description FM Virtual Storage-Profile ...
87513 +*//***************************************************************************/
87514 +#ifndef __FM_VSP_EXT_H
87515 +#define __FM_VSP_EXT_H
87516 +
87517 +#include "std_ext.h"
87518 +#include "error_ext.h"
87519 +#include "string_ext.h"
87520 +#include "debug_ext.h"
87521 +
87522 +#include "fm_ext.h"
87523 +
87524 +
87525 +/**************************************************************************//**
87526 +
87527 + @Group FM_grp Frame Manager API
87528 +
87529 + @Description FM API functions, definitions and enums
87530 +
87531 + @{
87532 +*//***************************************************************************/
87533 +
87534 +/**************************************************************************//**
87535 + @Group FM_VSP_grp FM Virtual-Storage-Profile
87536 +
87537 + @Description FM Virtual-Storage-Profile API
87538 +
87539 + @{
87540 +*//***************************************************************************/
87541 +
87542 +/**************************************************************************//**
87543 + @Group FM_VSP_init_grp FM VSP Initialization Unit
87544 +
87545 + @Description FM VSP initialization API.
87546 +
87547 + @{
87548 +*//***************************************************************************/
87549 +
87550 +/**************************************************************************//**
87551 + @Description Virtual Storage Profile
87552 +*//***************************************************************************/
87553 +typedef struct t_FmVspParams {
87554 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
87555 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
87556 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
87557 + parameter associated with Rx / OP port */
87558 + uint16_t liodnOffset; /**< VSP's LIODN offset */
87559 + struct {
87560 + e_FmPortType portType; /**< Port type */
87561 + uint8_t portId; /**< Port Id - relative to type */
87562 + } portParams;
87563 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
87564 + defined in relevant FM object */
87565 +} t_FmVspParams;
87566 +
87567 +
87568 +/**************************************************************************//**
87569 + @Function FM_VSP_Config
87570 +
87571 + @Description Creates descriptor for the FM VSP module.
87572 +
87573 + The routine returns a handle (descriptor) to the FM VSP object.
87574 + This descriptor must be passed as first parameter to all other
87575 + FM VSP function calls.
87576 +
87577 + No actual initialization or configuration of FM hardware is
87578 + done by this routine.
87579 +
87580 +@Param[in] p_FmVspParams Pointer to data structure of parameters
87581 +
87582 + @Retval Handle to FM VSP object, or NULL for Failure.
87583 +*//***************************************************************************/
87584 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
87585 +
87586 +/**************************************************************************//**
87587 + @Function FM_VSP_Init
87588 +
87589 + @Description Initializes the FM VSP module
87590 +
87591 + @Param[in] h_FmVsp - FM VSP module descriptor
87592 +
87593 + @Return E_OK on success; Error code otherwise.
87594 +*//***************************************************************************/
87595 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
87596 +
87597 +/**************************************************************************//**
87598 + @Function FM_VSP_Free
87599 +
87600 + @Description Frees all resources that were assigned to FM VSP module.
87601 +
87602 + Calling this routine invalidates the descriptor.
87603 +
87604 + @Param[in] h_FmVsp - FM VSP module descriptor
87605 +
87606 + @Return E_OK on success; Error code otherwise.
87607 +*//***************************************************************************/
87608 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
87609 +
87610 +
87611 +/**************************************************************************//**
87612 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
87613 +
87614 + @Description FM VSP advanced configuration functions.
87615 +
87616 + @{
87617 +*//***************************************************************************/
87618 +
87619 +/**************************************************************************//**
87620 + @Function FM_VSP_ConfigBufferPrefixContent
87621 +
87622 + @Description Defines the structure, size and content of the application buffer.
87623 +
87624 + The prefix will
87625 + In VSPs defined for Tx ports, if 'passPrsResult', the application
87626 + should set a value to their offsets in the prefix of
87627 + the FM will save the first 'privDataSize', than,
87628 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
87629 + and timeStamp, and the packet itself (in this order), to the
87630 + application buffer, and to offset.
87631 +
87632 + Calling this routine changes the buffer margins definitions
87633 + in the internal driver data base from its default
87634 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
87635 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
87636 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
87637 +
87638 + @Param[in] h_FmVsp A handle to a FM VSP module.
87639 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
87640 + structure of the buffer.
87641 + Out parameter: Start margin - offset
87642 + of data from start of external buffer.
87643 +
87644 + @Return E_OK on success; Error code otherwise.
87645 +
87646 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87647 +*//***************************************************************************/
87648 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
87649 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
87650 +
87651 +/**************************************************************************//**
87652 + @Function FM_VSP_ConfigDmaSwapData
87653 +
87654 + @Description Calling this routine changes the DMA swap data parameter
87655 + in the internal driver data base from its default
87656 + configuration [DEFAULT_FM_SP_dmaSwapData]
87657 +
87658 + @Param[in] h_FmVsp A handle to a FM VSP module.
87659 + @Param[in] swapData New selection
87660 +
87661 + @Return E_OK on success; Error code otherwise.
87662 +
87663 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87664 +*//***************************************************************************/
87665 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
87666 +
87667 +/**************************************************************************//**
87668 + @Function FM_VSP_ConfigDmaIcCacheAttr
87669 +
87670 + @Description Calling this routine changes the internal context cache
87671 + attribute parameter in the internal driver data base
87672 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
87673 +
87674 + @Param[in] h_FmVsp A handle to a FM VSP module.
87675 + @Param[in] intContextCacheAttr New selection
87676 +
87677 + @Return E_OK on success; Error code otherwise.
87678 +
87679 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87680 +*//***************************************************************************/
87681 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
87682 + e_FmDmaCacheOption intContextCacheAttr);
87683 +
87684 +/**************************************************************************//**
87685 + @Function FM_VSP_ConfigDmaHdrAttr
87686 +
87687 + @Description Calling this routine changes the header cache
87688 + attribute parameter in the internal driver data base
87689 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
87690 +
87691 + @Param[in] h_FmVsp A handle to a FM VSP module.
87692 + @Param[in] headerCacheAttr New selection
87693 +
87694 + @Return E_OK on success; Error code otherwise.
87695 +
87696 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87697 +*//***************************************************************************/
87698 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
87699 +
87700 +/**************************************************************************//**
87701 + @Function FM_VSP_ConfigDmaScatterGatherAttr
87702 +
87703 + @Description Calling this routine changes the scatter gather cache
87704 + attribute parameter in the internal driver data base
87705 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
87706 +
87707 + @Param[in] h_FmVsp A handle to a FM VSP module.
87708 + @Param[in] scatterGatherCacheAttr New selection
87709 +
87710 + @Return E_OK on success; Error code otherwise.
87711 +
87712 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87713 +*//***************************************************************************/
87714 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
87715 + e_FmDmaCacheOption scatterGatherCacheAttr);
87716 +
87717 +/**************************************************************************//**
87718 + @Function FM_VSP_ConfigDmaWriteOptimize
87719 +
87720 + @Description Calling this routine changes the write optimization
87721 + parameter in the internal driver data base
87722 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
87723 +
87724 + @Param[in] h_FmVsp A handle to a FM VSP module.
87725 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
87726 +
87727 + @Return E_OK on success; Error code otherwise.
87728 +
87729 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87730 +*//***************************************************************************/
87731 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
87732 +
87733 +/**************************************************************************//**
87734 + @Function FM_VSP_ConfigNoScatherGather
87735 +
87736 + @Description Calling this routine changes the possibility to receive S/G frame
87737 + in the internal driver data base
87738 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
87739 +
87740 + @Param[in] h_FmVsp A handle to a FM VSP module.
87741 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
87742 +
87743 + @Return E_OK on success; Error code otherwise.
87744 +
87745 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87746 +*//***************************************************************************/
87747 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
87748 +
87749 +/**************************************************************************//**
87750 + @Function FM_VSP_ConfigPoolDepletion
87751 +
87752 + @Description Calling this routine enables pause frame generation depending on the
87753 + depletion status of BM pools. It also defines the conditions to activate
87754 + this functionality. By default, this functionality is disabled.
87755 +
87756 + @Param[in] h_FmVsp A handle to a FM VSP module.
87757 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
87758 +
87759 + @Return E_OK on success; Error code otherwise.
87760 +
87761 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87762 +*//***************************************************************************/
87763 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
87764 +
87765 +/**************************************************************************//**
87766 + @Function FM_VSP_ConfigBackupPools
87767 +
87768 + @Description Calling this routine allows the configuration of some of the BM pools
87769 + defined for this port as backup pools.
87770 + A pool configured to be a backup pool will be used only if all other
87771 + enabled non-backup pools are depleted.
87772 +
87773 + @Param[in] h_FmVsp A handle to a FM VSP module.
87774 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
87775 + be defined as backup pools.
87776 +
87777 + @Return E_OK on success; Error code otherwise.
87778 +
87779 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
87780 +*//***************************************************************************/
87781 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
87782 +
87783 +/** @} */ /* end of FM_VSP_adv_config_grp group */
87784 +/** @} */ /* end of FM_VSP_init_grp group */
87785 +
87786 +
87787 +/**************************************************************************//**
87788 + @Group FM_VSP_control_grp FM VSP Control Unit
87789 +
87790 + @Description FM VSP runtime control API.
87791 +
87792 + @{
87793 +*//***************************************************************************/
87794 +
87795 +/**************************************************************************//**
87796 + @Function FM_VSP_GetBufferDataOffset
87797 +
87798 + @Description Relevant for Rx ports.
87799 + Returns the data offset from the beginning of the data buffer
87800 +
87801 + @Param[in] h_FmVsp - FM PORT module descriptor
87802 +
87803 + @Return data offset.
87804 +
87805 + @Cautions Allowed only following FM_VSP_Init().
87806 +*//***************************************************************************/
87807 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
87808 +
87809 +/**************************************************************************//**
87810 + @Function FM_VSP_GetBufferICInfo
87811 +
87812 + @Description Returns the Internal Context offset from the beginning of the data buffer
87813 +
87814 + @Param[in] h_FmVsp - FM PORT module descriptor
87815 + @Param[in] p_Data - A pointer to the data buffer.
87816 +
87817 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
87818 + configured for this port.
87819 +
87820 + @Cautions Allowed only following FM_VSP_Init().
87821 +*//***************************************************************************/
87822 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
87823 +
87824 +/**************************************************************************//**
87825 + @Function FM_VSP_GetBufferPrsResult
87826 +
87827 + @Description Returns the pointer to the parse result in the data buffer.
87828 + In Rx ports this is relevant after reception, if parse
87829 + result is configured to be part of the data passed to the
87830 + application. For non Rx ports it may be used to get the pointer
87831 + of the area in the buffer where parse result should be
87832 + initialized - if so configured.
87833 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
87834 + configuration.
87835 +
87836 + @Param[in] h_FmVsp - FM PORT module descriptor
87837 + @Param[in] p_Data - A pointer to the data buffer.
87838 +
87839 + @Return Parse result pointer on success, NULL if parse result was not
87840 + configured for this port.
87841 +
87842 + @Cautions Allowed only following FM_VSP_Init().
87843 +*//***************************************************************************/
87844 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
87845 +
87846 +/**************************************************************************//**
87847 + @Function FM_VSP_GetBufferTimeStamp
87848 +
87849 + @Description Returns the time stamp in the data buffer.
87850 + Relevant for Rx ports for getting the buffer time stamp.
87851 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
87852 + configuration.
87853 +
87854 + @Param[in] h_FmVsp - FM PORT module descriptor
87855 + @Param[in] p_Data - A pointer to the data buffer.
87856 +
87857 + @Return A pointer to the hash result on success, NULL otherwise.
87858 +
87859 + @Cautions Allowed only following FM_VSP_Init().
87860 +*//***************************************************************************/
87861 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
87862 +
87863 +/**************************************************************************//**
87864 + @Function FM_VSP_GetBufferHashResult
87865 +
87866 + @Description Given a data buffer, on the condition that hash result was defined
87867 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
87868 + this routine will return the pointer to the hash result location in the
87869 + buffer prefix.
87870 +
87871 + @Param[in] h_FmVsp - FM PORT module descriptor
87872 + @Param[in] p_Data - A pointer to the data buffer.
87873 +
87874 + @Return A pointer to the hash result on success, NULL otherwise.
87875 +
87876 + @Cautions Allowed only following FM_VSP_Init().
87877 +*//***************************************************************************/
87878 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
87879 +
87880 +
87881 +/** @} */ /* end of FM_VSP_control_grp group */
87882 +/** @} */ /* end of FM_VSP_grp group */
87883 +/** @} */ /* end of FM_grp group */
87884 +
87885 +
87886 +#endif /* __FM_VSP_EXT_H */
87887 --- /dev/null
87888 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
87889 @@ -0,0 +1,76 @@
87890 +/*
87891 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87892 + *
87893 + * Redistribution and use in source and binary forms, with or without
87894 + * modification, are permitted provided that the following conditions are met:
87895 + * * Redistributions of source code must retain the above copyright
87896 + * notice, this list of conditions and the following disclaimer.
87897 + * * Redistributions in binary form must reproduce the above copyright
87898 + * notice, this list of conditions and the following disclaimer in the
87899 + * documentation and/or other materials provided with the distribution.
87900 + * * Neither the name of Freescale Semiconductor nor the
87901 + * names of its contributors may be used to endorse or promote products
87902 + * derived from this software without specific prior written permission.
87903 + *
87904 + *
87905 + * ALTERNATIVELY, this software may be distributed under the terms of the
87906 + * GNU General Public License ("GPL") as published by the Free Software
87907 + * Foundation, either version 2 of that License or (at your option) any
87908 + * later version.
87909 + *
87910 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87911 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87912 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87913 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87914 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87915 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87916 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87917 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87918 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87919 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87920 + */
87921 +
87922 +
87923 +
87924 +#ifndef __MII_ACC_EXT_H
87925 +#define __MII_ACC_EXT_H
87926 +
87927 +
87928 +/**************************************************************************//**
87929 + @Function MII_ReadPhyReg
87930 +
87931 + @Description This routine is called to read a specified PHY
87932 + register value.
87933 +
87934 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
87935 + @Param[in] phyAddr - PHY address (0-31).
87936 + @Param[in] reg - PHY register to read
87937 + @Param[out] p_Data - Gets the register value.
87938 +
87939 + @Return Always zero (success).
87940 +*//***************************************************************************/
87941 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
87942 + uint8_t phyAddr,
87943 + uint8_t reg,
87944 + uint16_t *p_Data);
87945 +
87946 +/**************************************************************************//**
87947 + @Function MII_WritePhyReg
87948 +
87949 + @Description This routine is called to write data to a specified PHY
87950 + register.
87951 +
87952 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
87953 + @Param[in] phyAddr - PHY address (0-31).
87954 + @Param[in] reg - PHY register to write
87955 + @Param[in] data - Data to write in register.
87956 +
87957 + @Return Always zero (success).
87958 +*//***************************************************************************/
87959 +int MII_WritePhyReg(t_Handle h_MiiAccess,
87960 + uint8_t phyAddr,
87961 + uint8_t reg,
87962 + uint16_t data);
87963 +
87964 +
87965 +#endif /* __MII_ACC_EXT_H */
87966 --- /dev/null
87967 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
87968 @@ -0,0 +1,90 @@
87969 +/*
87970 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87971 + *
87972 + * Redistribution and use in source and binary forms, with or without
87973 + * modification, are permitted provided that the following conditions are met:
87974 + * * Redistributions of source code must retain the above copyright
87975 + * notice, this list of conditions and the following disclaimer.
87976 + * * Redistributions in binary form must reproduce the above copyright
87977 + * notice, this list of conditions and the following disclaimer in the
87978 + * documentation and/or other materials provided with the distribution.
87979 + * * Neither the name of Freescale Semiconductor nor the
87980 + * names of its contributors may be used to endorse or promote products
87981 + * derived from this software without specific prior written permission.
87982 + *
87983 + *
87984 + * ALTERNATIVELY, this software may be distributed under the terms of the
87985 + * GNU General Public License ("GPL") as published by the Free Software
87986 + * Foundation, either version 2 of that License or (at your option) any
87987 + * later version.
87988 + *
87989 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87990 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87991 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87992 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87993 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87994 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87995 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87996 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87997 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87998 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87999 + */
88000 +
88001 +
88002 +/**************************************************************************//**
88003 + @File core_ext.h
88004 +
88005 + @Description Generic interface to basic core operations.
88006 +
88007 + The system integrator must ensure that this interface is
88008 + mapped to a specific core implementation, by including the
88009 + appropriate header file.
88010 +*//***************************************************************************/
88011 +#ifndef __CORE_EXT_H
88012 +#define __CORE_EXT_H
88013 +
88014 +#ifdef CONFIG_FMAN_ARM
88015 +#include "arm_ext.h"
88016 +#include <linux/smp.h>
88017 +#else
88018 +#ifdef NCSW_PPC_CORE
88019 +#include "ppc_ext.h"
88020 +#elif defined(NCSW_VXWORKS)
88021 +#include "core_vxw_ext.h"
88022 +#else
88023 +#error "Core is not defined!"
88024 +#endif /* NCSW_CORE */
88025 +
88026 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
88027 +#error "Must define core as little-endian or big-endian!"
88028 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
88029 +
88030 +#ifndef CORE_CACHELINE_SIZE
88031 +#error "Must define the core cache-line size!"
88032 +#endif /* !CORE_CACHELINE_SIZE */
88033 +
88034 +#endif /* CONFIG_FMAN_ARM */
88035 +
88036 +
88037 +/**************************************************************************//**
88038 + @Function CORE_GetId
88039 +
88040 + @Description Returns the core ID in the system.
88041 +
88042 + @Return Core ID.
88043 +*//***************************************************************************/
88044 +uint32_t CORE_GetId(void);
88045 +
88046 +/**************************************************************************//**
88047 + @Function CORE_MemoryBarrier
88048 +
88049 + @Description This routine will cause the core to stop executing any commands
88050 + until all previous memory read/write commands are completely out
88051 + of the core's pipeline.
88052 +
88053 + @Return None.
88054 +*//***************************************************************************/
88055 +void CORE_MemoryBarrier(void);
88056 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
88057 +
88058 +#endif /* __CORE_EXT_H */
88059 --- /dev/null
88060 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88061 @@ -0,0 +1,55 @@
88062 +/*
88063 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88064 + *
88065 + * Redistribution and use in source and binary forms, with or without
88066 + * modification, are permitted provided that the following conditions are met:
88067 + * * Redistributions of source code must retain the above copyright
88068 + * notice, this list of conditions and the following disclaimer.
88069 + * * Redistributions in binary form must reproduce the above copyright
88070 + * notice, this list of conditions and the following disclaimer in the
88071 + * documentation and/or other materials provided with the distribution.
88072 + * * Neither the name of Freescale Semiconductor nor the
88073 + * names of its contributors may be used to endorse or promote products
88074 + * derived from this software without specific prior written permission.
88075 + *
88076 + *
88077 + * ALTERNATIVELY, this software may be distributed under the terms of the
88078 + * GNU General Public License ("GPL") as published by the Free Software
88079 + * Foundation, either version 2 of that License or (at your option) any
88080 + * later version.
88081 + *
88082 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88083 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88084 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88085 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88086 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88087 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88088 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88089 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88090 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88091 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88092 + */
88093 +
88094 +
88095 +/**************************************************************************//**
88096 + @File arm_ext.h
88097 +
88098 + @Description Core API for ARM cores
88099 +
88100 + These routines must be implemented by each specific PowerPC
88101 + core driver.
88102 +*//***************************************************************************/
88103 +#ifndef __ARM_EXT_H
88104 +#define __ARM_EXT_H
88105 +
88106 +#include "part_ext.h"
88107 +
88108 +
88109 +#define CORE_IS_LITTLE_ENDIAN
88110 +
88111 +static __inline__ void CORE_MemoryBarrier(void)
88112 +{
88113 + mb();
88114 +}
88115 +
88116 +#endif /* __PPC_EXT_H */
88117 --- /dev/null
88118 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88119 @@ -0,0 +1,476 @@
88120 +/*
88121 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88122 + *
88123 + * Redistribution and use in source and binary forms, with or without
88124 + * modification, are permitted provided that the following conditions are met:
88125 + * * Redistributions of source code must retain the above copyright
88126 + * notice, this list of conditions and the following disclaimer.
88127 + * * Redistributions in binary form must reproduce the above copyright
88128 + * notice, this list of conditions and the following disclaimer in the
88129 + * documentation and/or other materials provided with the distribution.
88130 + * * Neither the name of Freescale Semiconductor nor the
88131 + * names of its contributors may be used to endorse or promote products
88132 + * derived from this software without specific prior written permission.
88133 + *
88134 + *
88135 + * ALTERNATIVELY, this software may be distributed under the terms of the
88136 + * GNU General Public License ("GPL") as published by the Free Software
88137 + * Foundation, either version 2 of that License or (at your option) any
88138 + * later version.
88139 + *
88140 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88141 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88142 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88143 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88144 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88145 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88146 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88147 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88148 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88149 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88150 + */
88151 +
88152 +
88153 +/**************************************************************************//**
88154 + @File e500v2_ext.h
88155 +
88156 + @Description E500 external definitions prototypes
88157 + This file is not included by the E500
88158 + source file as it is an assembly file. It is used
88159 + only for prototypes exposure, for inclusion
88160 + by user and other modules.
88161 +*//***************************************************************************/
88162 +
88163 +#ifndef __E500V2_EXT_H
88164 +#define __E500V2_EXT_H
88165 +
88166 +#include "std_ext.h"
88167 +
88168 +
88169 +/* Layer 1 Cache Manipulations
88170 + *==============================
88171 + * Should not be called directly by the user.
88172 + */
88173 +void L1DCache_Invalidate (void);
88174 +void L1ICache_Invalidate(void);
88175 +void L1DCache_Enable(void);
88176 +void L1ICache_Enable(void);
88177 +void L1DCache_Disable(void);
88178 +void L1ICache_Disable(void);
88179 +void L1DCache_Flush(void);
88180 +void L1ICache_Flush(void);
88181 +uint32_t L1ICache_IsEnabled(void);
88182 +uint32_t L1DCache_IsEnabled(void);
88183 +/*
88184 + *
88185 + */
88186 +uint32_t L1DCache_LineLock(uint32_t addr);
88187 +uint32_t L1ICache_LineLock(uint32_t addr);
88188 +void L1Cache_BroadCastEnable(void);
88189 +void L1Cache_BroadCastDisable(void);
88190 +
88191 +
88192 +#define CORE_DCacheEnable E500_DCacheEnable
88193 +#define CORE_ICacheEnable E500_ICacheEnable
88194 +#define CORE_DCacheDisable E500_DCacheDisable
88195 +#define CORE_ICacheDisable E500_ICacheDisable
88196 +#define CORE_GetId E500_GetId
88197 +#define CORE_TestAndSet E500_TestAndSet
88198 +#define CORE_MemoryBarrier E500_MemoryBarrier
88199 +#define CORE_InstructionSync E500_InstructionSync
88200 +
88201 +#define CORE_SetDozeMode E500_SetDozeMode
88202 +#define CORE_SetNapMode E500_SetNapMode
88203 +#define CORE_SetSleepMode E500_SetSleepMode
88204 +#define CORE_SetJogMode E500_SetJogMode
88205 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
88206 +
88207 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
88208 +#define CORE_RecoverNapMode E500_RecoverNapMode
88209 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
88210 +#define CORE_RecoverJogMode E500_RecoverJogMode
88211 +
88212 +void E500_SetDozeMode(void);
88213 +void E500_SetNapMode(void);
88214 +void E500_SetSleepMode(void);
88215 +void E500_SetJogMode(void);
88216 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
88217 +
88218 +void E500_RecoverDozeMode(void);
88219 +void E500_RecoverNapMode(void);
88220 +void E500_RecoverSleepMode(void);
88221 +void E500_RecoverJogMode(void);
88222 +
88223 +
88224 +/**************************************************************************//**
88225 + @Group E500_id E500 Application Programming Interface
88226 +
88227 + @Description E500 API functions, definitions and enums
88228 +
88229 + @{
88230 +*//***************************************************************************/
88231 +
88232 +/**************************************************************************//**
88233 + @Group E500_init_grp E500 Initialization Unit
88234 +
88235 + @Description E500 initialization unit API functions, definitions and enums
88236 +
88237 + @{
88238 +*//***************************************************************************/
88239 +
88240 +
88241 +/**************************************************************************//**
88242 + @Function E500_DCacheEnable
88243 +
88244 + @Description Enables the data cache for memory pages that are
88245 + not cache inhibited.
88246 +
88247 + @Return None.
88248 +*//***************************************************************************/
88249 +void E500_DCacheEnable(void);
88250 +
88251 +/**************************************************************************//**
88252 + @Function E500_ICacheEnable
88253 +
88254 + @Description Enables the instruction cache for memory pages that are
88255 + not cache inhibited.
88256 +
88257 + @Return None.
88258 +*//***************************************************************************/
88259 +void E500_ICacheEnable(void);
88260 +
88261 +/**************************************************************************//**
88262 + @Function E500_DCacheDisable
88263 +
88264 + @Description Disables the data cache.
88265 +
88266 + @Return None.
88267 +*//***************************************************************************/
88268 +void E500_DCacheDisable(void);
88269 +
88270 +/**************************************************************************//**
88271 + @Function E500_ICacheDisable
88272 +
88273 + @Description Disables the instruction cache.
88274 +
88275 + @Return None.
88276 +*//***************************************************************************/
88277 +void E500_ICacheDisable(void);
88278 +
88279 +/**************************************************************************//**
88280 + @Function E500_DCacheFlush
88281 +
88282 + @Description Flushes the data cache
88283 +
88284 + @Return None.
88285 +*//***************************************************************************/
88286 +void E500_DCacheFlush(void);
88287 +
88288 +/**************************************************************************//**
88289 + @Function E500_ICacheFlush
88290 +
88291 + @Description Flushes the instruction cache.
88292 +
88293 + @Return None.
88294 +*//***************************************************************************/
88295 +void E500_ICacheFlush(void);
88296 +
88297 +/**************************************************************************//**
88298 + @Function E500_DCacheSetStashId
88299 +
88300 + @Description Set Stash Id for data cache
88301 +
88302 + @Param[in] stashId the stash id to be set.
88303 +
88304 + @Return None.
88305 +*//***************************************************************************/
88306 +void E500_DCacheSetStashId(uint8_t stashId);
88307 +
88308 +/**************************************************************************//**
88309 + @Description E500mc L2 Cache Operation Mode
88310 +*//***************************************************************************/
88311 +typedef enum e_E500mcL2CacheMode
88312 +{
88313 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
88314 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
88315 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
88316 +} e_E500mcL2CacheMode;
88317 +
88318 +#if defined(CORE_E500MC) || defined(CORE_E5500)
88319 +/**************************************************************************//**
88320 + @Function E500_L2CacheEnable
88321 +
88322 + @Description Enables the cache for memory pages that are not cache inhibited.
88323 +
88324 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
88325 +
88326 + @Return None.
88327 +
88328 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88329 + not possible to call this routine for i-cache and than to call
88330 + again for d-cache; The second call will override the first one.
88331 +*//***************************************************************************/
88332 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
88333 +
88334 +/**************************************************************************//**
88335 + @Function E500_L2CacheDisable
88336 +
88337 + @Description Disables the cache (data instruction or both).
88338 +
88339 + @Return None.
88340 +
88341 +*//***************************************************************************/
88342 +void E500_L2CacheDisable(void);
88343 +
88344 +/**************************************************************************//**
88345 + @Function E500_L2CacheFlush
88346 +
88347 + @Description Flushes the cache.
88348 +
88349 + @Return None.
88350 +*//***************************************************************************/
88351 +void E500_L2CacheFlush(void);
88352 +
88353 +/**************************************************************************//**
88354 + @Function E500_L2SetStashId
88355 +
88356 + @Description Set Stash Id
88357 +
88358 + @Param[in] stashId the stash id to be set.
88359 +
88360 + @Return None.
88361 +*//***************************************************************************/
88362 +void E500_L2SetStashId(uint8_t stashId);
88363 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
88364 +
88365 +#ifdef CORE_E6500
88366 +/**************************************************************************//**
88367 + @Function E6500_L2CacheEnable
88368 +
88369 + @Description Enables the cache for memory pages that are not cache inhibited.
88370 +
88371 + @param[in] mode - L2 cache mode: support data & instruction only.
88372 +
88373 + @Return None.
88374 +
88375 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88376 + not possible to call this routine for i-cache and than to call
88377 + again for d-cache; The second call will override the first one.
88378 +*//***************************************************************************/
88379 +void E6500_L2CacheEnable(uintptr_t clusterBase);
88380 +
88381 +/**************************************************************************//**
88382 + @Function E6500_L2CacheDisable
88383 +
88384 + @Description Disables the cache (data instruction or both).
88385 +
88386 + @Return None.
88387 +
88388 +*//***************************************************************************/
88389 +void E6500_L2CacheDisable(uintptr_t clusterBase);
88390 +
88391 +/**************************************************************************//**
88392 + @Function E6500_L2CacheFlush
88393 +
88394 + @Description Flushes the cache.
88395 +
88396 + @Return None.
88397 +*//***************************************************************************/
88398 +void E6500_L2CacheFlush(uintptr_t clusterBase);
88399 +
88400 +/**************************************************************************//**
88401 + @Function E6500_L2SetStashId
88402 +
88403 + @Description Set Stash Id
88404 +
88405 + @Param[in] stashId the stash id to be set.
88406 +
88407 + @Return None.
88408 +*//***************************************************************************/
88409 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
88410 +
88411 +/**************************************************************************//**
88412 + @Function E6500_GetCcsrBase
88413 +
88414 + @Description Obtain SoC CCSR base address
88415 +
88416 + @Param[in] None.
88417 +
88418 + @Return Physical CCSR base address.
88419 +*//***************************************************************************/
88420 +physAddress_t E6500_GetCcsrBase(void);
88421 +#endif /* CORE_E6500 */
88422 +
88423 +/**************************************************************************//**
88424 + @Function E500_AddressBusStreamingEnable
88425 +
88426 + @Description Enables address bus streaming on the CCB.
88427 +
88428 + This setting, along with the ECM streaming configuration
88429 + parameters, enables address bus streaming on the CCB.
88430 +
88431 + @Return None.
88432 +*//***************************************************************************/
88433 +void E500_AddressBusStreamingEnable(void);
88434 +
88435 +/**************************************************************************//**
88436 + @Function E500_AddressBusStreamingDisable
88437 +
88438 + @Description Disables address bus streaming on the CCB.
88439 +
88440 + @Return None.
88441 +*//***************************************************************************/
88442 +void E500_AddressBusStreamingDisable(void);
88443 +
88444 +/**************************************************************************//**
88445 + @Function E500_AddressBroadcastEnable
88446 +
88447 + @Description Enables address broadcast.
88448 +
88449 + The e500 broadcasts cache management instructions (dcbst, dcblc
88450 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88451 + based on ABE. ABE must be set to allow management of external
88452 + L2 caches.
88453 +
88454 + @Return None.
88455 +*//***************************************************************************/
88456 +void E500_AddressBroadcastEnable(void);
88457 +
88458 +/**************************************************************************//**
88459 + @Function E500_AddressBroadcastDisable
88460 +
88461 + @Description Disables address broadcast.
88462 +
88463 + The e500 broadcasts cache management instructions (dcbst, dcblc
88464 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88465 + based on ABE. ABE must be set to allow management of external
88466 + L2 caches.
88467 +
88468 + @Return None.
88469 +*//***************************************************************************/
88470 +void E500_AddressBroadcastDisable(void);
88471 +
88472 +/**************************************************************************//**
88473 + @Function E500_IsTaskletSupported
88474 +
88475 + @Description Checks if tasklets are supported by the e500 interrupt handler.
88476 +
88477 + @Retval TRUE - Tasklets are supported.
88478 + @Retval FALSE - Tasklets are not supported.
88479 +*//***************************************************************************/
88480 +bool E500_IsTaskletSupported(void);
88481 +
88482 +void E500_EnableTimeBase(void);
88483 +void E500_DisableTimeBase(void);
88484 +
88485 +uint64_t E500_GetTimeBaseTime(void);
88486 +
88487 +void E500_GenericIntrInit(void);
88488 +
88489 +t_Error E500_SetIntr(int ppcIntrSrc,
88490 + void (* Isr)(t_Handle handle),
88491 + t_Handle handle);
88492 +
88493 +t_Error E500_ClearIntr(int ppcIntrSrc);
88494 +
88495 +/**************************************************************************//**
88496 + @Function E500_GenericIntrHandler
88497 +
88498 + @Description This is the general e500 interrupt handler.
88499 +
88500 + It is called by the main assembly interrupt handler
88501 + when an exception occurs and no other function has been
88502 + assigned to this exception.
88503 +
88504 + @Param intrEntry - (In) The exception interrupt vector entry.
88505 +*//***************************************************************************/
88506 +void E500_GenericIntrHandler(uint32_t intrEntry);
88507 +
88508 +/**************************************************************************//**
88509 + @Function CriticalIntr
88510 +
88511 + @Description This is the specific critical e500 interrupt handler.
88512 +
88513 + It is called by the main assembly interrupt handler
88514 + when an critical interrupt.
88515 +
88516 + @Param intrEntry - (In) The exception interrupt vector entry.
88517 +*//***************************************************************************/
88518 +void CriticalIntr(uint32_t intrEntry);
88519 +
88520 +
88521 +/**************************************************************************//**
88522 + @Function E500_GetId
88523 +
88524 + @Description Returns the core ID in the system.
88525 +
88526 + @Return Core ID.
88527 +*//***************************************************************************/
88528 +uint32_t E500_GetId(void);
88529 +
88530 +/**************************************************************************//**
88531 + @Function E500_TestAndSet
88532 +
88533 + @Description This routine tries to atomically test-and-set an integer
88534 + in memory to a non-zero value.
88535 +
88536 + The memory will be set only if it is tested as zero, in which
88537 + case the routine returns the new non-zero value; otherwise the
88538 + routine returns zero.
88539 +
88540 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88541 + operation should be made.
88542 +
88543 + @Retval Zero - Operation failed - memory was already set.
88544 + @Retval Non-zero - Operation succeeded - memory has been set.
88545 +*//***************************************************************************/
88546 +int E500_TestAndSet(volatile int *p);
88547 +
88548 +/**************************************************************************//**
88549 + @Function E500_MemoryBarrier
88550 +
88551 + @Description This routine will cause the core to stop executing any commands
88552 + until all previous memory read/write commands are completely out
88553 + of the core's pipeline.
88554 +
88555 + @Return None.
88556 +*//***************************************************************************/
88557 +static __inline__ void E500_MemoryBarrier(void)
88558 +{
88559 +#ifndef CORE_E500V2
88560 + __asm__ ("mbar 1");
88561 +#else /* CORE_E500V2 */
88562 + /**** ERRATA WORK AROUND START ****/
88563 + /* ERRATA num: CPU1 */
88564 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
88565 + guarded loads and stores. */
88566 +
88567 + /* "msync" instruction is used instead */
88568 +
88569 + __asm__ ("msync");
88570 +
88571 + /**** ERRATA WORK AROUND END ****/
88572 +#endif /* CORE_E500V2 */
88573 +}
88574 +
88575 +/**************************************************************************//**
88576 + @Function E500_InstructionSync
88577 +
88578 + @Description This routine will cause the core to wait for previous instructions
88579 + (including any interrupts they generate) to complete before the
88580 + synchronization command executes, which purges all instructions
88581 + from the processor's pipeline and refetches the next instruction.
88582 +
88583 + @Return None.
88584 +*//***************************************************************************/
88585 +static __inline__ void E500_InstructionSync(void)
88586 +{
88587 + __asm__ ("isync");
88588 +}
88589 +
88590 +
88591 +/** @} */ /* end of E500_init_grp group */
88592 +/** @} */ /* end of E500_grp group */
88593 +
88594 +
88595 +#endif /* __E500V2_EXT_H */
88596 --- /dev/null
88597 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
88598 @@ -0,0 +1,141 @@
88599 +/*
88600 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88601 + *
88602 + * Redistribution and use in source and binary forms, with or without
88603 + * modification, are permitted provided that the following conditions are met:
88604 + * * Redistributions of source code must retain the above copyright
88605 + * notice, this list of conditions and the following disclaimer.
88606 + * * Redistributions in binary form must reproduce the above copyright
88607 + * notice, this list of conditions and the following disclaimer in the
88608 + * documentation and/or other materials provided with the distribution.
88609 + * * Neither the name of Freescale Semiconductor nor the
88610 + * names of its contributors may be used to endorse or promote products
88611 + * derived from this software without specific prior written permission.
88612 + *
88613 + *
88614 + * ALTERNATIVELY, this software may be distributed under the terms of the
88615 + * GNU General Public License ("GPL") as published by the Free Software
88616 + * Foundation, either version 2 of that License or (at your option) any
88617 + * later version.
88618 + *
88619 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88620 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88621 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88622 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88623 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88624 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88625 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88626 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88627 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88628 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88629 + */
88630 +
88631 +
88632 +/**************************************************************************//**
88633 + @File ppc_ext.h
88634 +
88635 + @Description Core API for PowerPC cores
88636 +
88637 + These routines must be implemented by each specific PowerPC
88638 + core driver.
88639 +*//***************************************************************************/
88640 +#ifndef __PPC_EXT_H
88641 +#define __PPC_EXT_H
88642 +
88643 +#include "part_ext.h"
88644 +
88645 +
88646 +#define CORE_IS_BIG_ENDIAN
88647 +
88648 +#if defined(CORE_E300) || defined(CORE_E500V2)
88649 +#define CORE_CACHELINE_SIZE 32
88650 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
88651 +#define CORE_CACHELINE_SIZE 64
88652 +#else
88653 +#error "Core not defined!"
88654 +#endif /* defined(CORE_E300) || ... */
88655 +
88656 +
88657 +/**************************************************************************//**
88658 + @Function CORE_TestAndSet
88659 +
88660 + @Description This routine tries to atomically test-and-set an integer
88661 + in memory to a non-zero value.
88662 +
88663 + The memory will be set only if it is tested as zero, in which
88664 + case the routine returns the new non-zero value; otherwise the
88665 + routine returns zero.
88666 +
88667 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88668 + operation should be made.
88669 +
88670 + @Retval Zero - Operation failed - memory was already set.
88671 + @Retval Non-zero - Operation succeeded - memory has been set.
88672 +*//***************************************************************************/
88673 +int CORE_TestAndSet(volatile int *p);
88674 +
88675 +/**************************************************************************//**
88676 + @Function CORE_InstructionSync
88677 +
88678 + @Description This routine will cause the core to wait for previous instructions
88679 + (including any interrupts they generate) to complete before the
88680 + synchronization command executes, which purges all instructions
88681 + from the processor's pipeline and refetches the next instruction.
88682 +
88683 + @Return None.
88684 +*//***************************************************************************/
88685 +void CORE_InstructionSync(void);
88686 +
88687 +/**************************************************************************//**
88688 + @Function CORE_DCacheEnable
88689 +
88690 + @Description Enables the data cache for memory pages that are
88691 + not cache inhibited.
88692 +
88693 + @Return None.
88694 +*//***************************************************************************/
88695 +void CORE_DCacheEnable(void);
88696 +
88697 +/**************************************************************************//**
88698 + @Function CORE_ICacheEnable
88699 +
88700 + @Description Enables the instruction cache for memory pages that are
88701 + not cache inhibited.
88702 +
88703 + @Return None.
88704 +*//***************************************************************************/
88705 +void CORE_ICacheEnable(void);
88706 +
88707 +/**************************************************************************//**
88708 + @Function CORE_DCacheDisable
88709 +
88710 + @Description Disables the data cache.
88711 +
88712 + @Return None.
88713 +*//***************************************************************************/
88714 +void CORE_DCacheDisable(void);
88715 +
88716 +/**************************************************************************//**
88717 + @Function CORE_ICacheDisable
88718 +
88719 + @Description Disables the instruction cache.
88720 +
88721 + @Return None.
88722 +*//***************************************************************************/
88723 +void CORE_ICacheDisable(void);
88724 +
88725 +
88726 +
88727 +#if defined(CORE_E300)
88728 +#include "e300_ext.h"
88729 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
88730 +#include "e500v2_ext.h"
88731 +#if !defined(NCSW_LINUX)
88732 +#include "e500v2_asm_ext.h"
88733 +#endif
88734 +#else
88735 +#error "Core not defined!"
88736 +#endif
88737 +
88738 +
88739 +#endif /* __PPC_EXT_H */
88740 --- /dev/null
88741 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
88742 @@ -0,0 +1,77 @@
88743 +/*
88744 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88745 + *
88746 + * Redistribution and use in source and binary forms, with or without
88747 + * modification, are permitted provided that the following conditions are met:
88748 + * * Redistributions of source code must retain the above copyright
88749 + * notice, this list of conditions and the following disclaimer.
88750 + * * Redistributions in binary form must reproduce the above copyright
88751 + * notice, this list of conditions and the following disclaimer in the
88752 + * documentation and/or other materials provided with the distribution.
88753 + * * Neither the name of Freescale Semiconductor nor the
88754 + * names of its contributors may be used to endorse or promote products
88755 + * derived from this software without specific prior written permission.
88756 + *
88757 + *
88758 + * ALTERNATIVELY, this software may be distributed under the terms of the
88759 + * GNU General Public License ("GPL") as published by the Free Software
88760 + * Foundation, either version 2 of that License or (at your option) any
88761 + * later version.
88762 + *
88763 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88764 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88765 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88766 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88767 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88768 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88769 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88770 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88771 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88772 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88773 + */
88774 +
88775 +#ifndef __DDR_SDT_EXT_H
88776 +#define __DDR_SDT_EXT_H
88777 +
88778 +
88779 +/**************************************************************************//**
88780 + @Group ddr_Generic_Resources
88781 +
88782 + @Description ddr generic functions, definitions and enums.
88783 +
88784 + @{
88785 +*//***************************************************************************/
88786 +
88787 +
88788 +/**************************************************************************//**
88789 + @Description SPD maximum size
88790 +*//***************************************************************************/
88791 +#define SPD_MAX_SIZE 256
88792 +
88793 +/**************************************************************************//**
88794 + @Description DDR types select
88795 +*//***************************************************************************/
88796 +typedef enum e_DdrType
88797 +{
88798 + e_DDR_DDR1,
88799 + e_DDR_DDR2,
88800 + e_DDR_DDR3,
88801 + e_DDR_DDR3L,
88802 + e_DDR_DDR4
88803 +} e_DdrType;
88804 +
88805 +/**************************************************************************//**
88806 + @Description DDR Mode.
88807 +*//***************************************************************************/
88808 +typedef enum e_DdrMode
88809 +{
88810 + e_DDR_BUS_WIDTH_32BIT,
88811 + e_DDR_BUS_WIDTH_64BIT
88812 +} e_DdrMode;
88813 +
88814 +/** @} */ /* end of ddr_Generic_Resources group */
88815 +
88816 +
88817 +
88818 +#endif /* __DDR_SDT_EXT_H */
88819 +
88820 --- /dev/null
88821 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
88822 @@ -0,0 +1,233 @@
88823 +/*
88824 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88825 + *
88826 + * Redistribution and use in source and binary forms, with or without
88827 + * modification, are permitted provided that the following conditions are met:
88828 + * * Redistributions of source code must retain the above copyright
88829 + * notice, this list of conditions and the following disclaimer.
88830 + * * Redistributions in binary form must reproduce the above copyright
88831 + * notice, this list of conditions and the following disclaimer in the
88832 + * documentation and/or other materials provided with the distribution.
88833 + * * Neither the name of Freescale Semiconductor nor the
88834 + * names of its contributors may be used to endorse or promote products
88835 + * derived from this software without specific prior written permission.
88836 + *
88837 + *
88838 + * ALTERNATIVELY, this software may be distributed under the terms of the
88839 + * GNU General Public License ("GPL") as published by the Free Software
88840 + * Foundation, either version 2 of that License or (at your option) any
88841 + * later version.
88842 + *
88843 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88844 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88845 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88846 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88847 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88848 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88849 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88850 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88851 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88852 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88853 + */
88854 +
88855 +
88856 +/**************************************************************************//**
88857 + @File debug_ext.h
88858 +
88859 + @Description Debug mode definitions.
88860 +*//***************************************************************************/
88861 +
88862 +#ifndef __DEBUG_EXT_H
88863 +#define __DEBUG_EXT_H
88864 +
88865 +#include "std_ext.h"
88866 +#include "xx_ext.h"
88867 +#include "memcpy_ext.h"
88868 +#if (DEBUG_ERRORS > 0)
88869 +#include "sprint_ext.h"
88870 +#include "string_ext.h"
88871 +#endif /* DEBUG_ERRORS > 0 */
88872 +
88873 +
88874 +#if (DEBUG_ERRORS > 0)
88875 +
88876 +/* Internally used macros */
88877 +
88878 +#define DUMP_Print XX_Print
88879 +#define DUMP_MAX_LEVELS 6
88880 +#define DUMP_IDX_LEN 6
88881 +#define DUMP_MAX_STR 64
88882 +
88883 +
88884 +#define _CREATE_DUMP_SUBSTR(phrase) \
88885 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
88886 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
88887 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
88888 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
88889 + { \
88890 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
88891 + if (dumpIsArr[dumpTmpLevel]) \
88892 + { \
88893 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
88894 + p_DumpToken = strtok(NULL, "."); \
88895 + } \
88896 + if ((p_DumpToken != NULL) && \
88897 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
88898 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
88899 + }
88900 +
88901 +
88902 +/**************************************************************************//**
88903 + @Group gen_id General Drivers Utilities
88904 +
88905 + @Description External routines.
88906 +
88907 + @{
88908 +*//***************************************************************************/
88909 +
88910 +/**************************************************************************//**
88911 + @Group dump_id Memory and Registers Dump Mechanism
88912 +
88913 + @Description Macros for dumping memory mapped structures.
88914 +
88915 + @{
88916 +*//***************************************************************************/
88917 +
88918 +/**************************************************************************//**
88919 + @Description Declaration of dump mechanism variables.
88920 +
88921 + This macro must be declared at the beginning of each routine
88922 + which uses the dump mechanism macros, before the routine's code
88923 + starts.
88924 +*//***************************************************************************/
88925 +#define DECLARE_DUMP \
88926 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
88927 + char dumpSubStr[DUMP_MAX_STR] = ""; \
88928 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
88929 + char *p_DumpToken = NULL; \
88930 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
88931 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
88932 + /* Prevent warnings if not all used */ \
88933 + UNUSED(dumpIdxStr[0][0]); \
88934 + UNUSED(dumpSubStr[0]); \
88935 + UNUSED(dumpTmpStr[0]); \
88936 + UNUSED(p_DumpToken); \
88937 + UNUSED(dumpArrIdx); \
88938 + UNUSED(dumpArrSize); \
88939 + UNUSED(dumpLevel); \
88940 + UNUSED(dumpTmpLevel); \
88941 + UNUSED(dumpIsArr[0]);
88942 +
88943 +
88944 +/**************************************************************************//**
88945 + @Description Prints a title for a subsequent dumped structure or memory.
88946 +
88947 + The inputs for this macro are the structure/memory title and
88948 + its base addresses.
88949 +*//***************************************************************************/
88950 +#define DUMP_TITLE(addr, msg) \
88951 + DUMP_Print("\r\n"); DUMP_Print msg; \
88952 + if (addr) \
88953 + DUMP_Print(" (%p)", (addr)); \
88954 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
88955 +
88956 +/**************************************************************************//**
88957 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
88958 +
88959 + The inputs for this macro are the sub-structure subtitle.
88960 + A separating line with this subtitle will be printed.
88961 +*//***************************************************************************/
88962 +#define DUMP_SUBTITLE(subtitle) \
88963 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
88964 +
88965 +
88966 +/**************************************************************************//**
88967 + @Description Dumps a memory region in 4-bytes aligned format.
88968 +
88969 + The inputs for this macro are the base addresses and size
88970 + (in bytes) of the memory region.
88971 +*//***************************************************************************/
88972 +#define DUMP_MEMORY(addr, size) \
88973 + MemDisp((uint8_t *)(addr), (int)(size))
88974 +
88975 +
88976 +/**************************************************************************//**
88977 + @Description Declares a dump loop, for dumping a sub-structure array.
88978 +
88979 + The inputs for this macro are:
88980 + - idx: an index variable, for indexing the sub-structure items
88981 + inside the loop. This variable must be declared separately
88982 + in the beginning of the routine.
88983 + - cnt: the number of times to repeat the loop. This number should
88984 + equal the number of items in the sub-structures array.
88985 +
88986 + Note, that the body of the loop must be written inside brackets.
88987 +*//***************************************************************************/
88988 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
88989 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
88990 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
88991 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
88992 +
88993 +
88994 +/**************************************************************************//**
88995 + @Description Dumps a structure's member variable.
88996 +
88997 + The input for this macro is the full reference for the member
88998 + variable, where the structure is referenced using a pointer.
88999 +
89000 + Note, that a members array must be dumped using DUMP_ARR macro,
89001 + rather than using this macro.
89002 +
89003 + If the member variable is part of a sub-structure hierarchy,
89004 + the full hierarchy (including array indexing) must be specified.
89005 +
89006 + Examples: p_Struct->member
89007 + p_Struct->sub.member
89008 + p_Struct->sub[i].member
89009 +*//***************************************************************************/
89010 +#define DUMP_VAR(st, phrase) \
89011 + do { \
89012 + void *addr = (void *)&((st)->phrase); \
89013 + physAddress_t physAddr = XX_VirtToPhys(addr); \
89014 + _CREATE_DUMP_SUBSTR(phrase); \
89015 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
89016 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
89017 + } while (0)
89018 +
89019 +
89020 +/**************************************************************************//**
89021 + @Description Dumps a structure's members array.
89022 +
89023 + The input for this macro is the full reference for the members
89024 + array, where the structure is referenced using a pointer.
89025 +
89026 + If the members array is part of a sub-structure hierarchy,
89027 + the full hierarchy (including array indexing) must be specified.
89028 +
89029 + Examples: p_Struct->array
89030 + p_Struct->sub.array
89031 + p_Struct->sub[i].array
89032 +*//***************************************************************************/
89033 +#define DUMP_ARR(st, phrase) \
89034 + do { \
89035 + physAddress_t physAddr; \
89036 + _CREATE_DUMP_SUBSTR(phrase); \
89037 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
89038 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
89039 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
89040 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
89041 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
89042 + } \
89043 + } while (0)
89044 +
89045 +
89046 +
89047 +#endif /* DEBUG_ERRORS > 0 */
89048 +
89049 +
89050 +/** @} */ /* end of dump_id group */
89051 +/** @} */ /* end of gen_id group */
89052 +
89053 +
89054 +#endif /* __DEBUG_EXT_H */
89055 +
89056 --- /dev/null
89057 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89058 @@ -0,0 +1,447 @@
89059 +/*
89060 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89061 + *
89062 + * Redistribution and use in source and binary forms, with or without
89063 + * modification, are permitted provided that the following conditions are met:
89064 + * * Redistributions of source code must retain the above copyright
89065 + * notice, this list of conditions and the following disclaimer.
89066 + * * Redistributions in binary form must reproduce the above copyright
89067 + * notice, this list of conditions and the following disclaimer in the
89068 + * documentation and/or other materials provided with the distribution.
89069 + * * Neither the name of Freescale Semiconductor nor the
89070 + * names of its contributors may be used to endorse or promote products
89071 + * derived from this software without specific prior written permission.
89072 + *
89073 + *
89074 + * ALTERNATIVELY, this software may be distributed under the terms of the
89075 + * GNU General Public License ("GPL") as published by the Free Software
89076 + * Foundation, either version 2 of that License or (at your option) any
89077 + * later version.
89078 + *
89079 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89080 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89081 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89082 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89083 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89084 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89085 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89086 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89087 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89088 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89089 + */
89090 +
89091 +
89092 +/**************************************************************************//**
89093 +
89094 + @File endian_ext.h
89095 +
89096 + @Description Big/little endian swapping routines.
89097 +*//***************************************************************************/
89098 +
89099 +#ifndef __ENDIAN_EXT_H
89100 +#define __ENDIAN_EXT_H
89101 +
89102 +#include "std_ext.h"
89103 +
89104 +
89105 +/**************************************************************************//**
89106 + @Group gen_id General Drivers Utilities
89107 +
89108 + @Description General usage API. This API is intended for usage by both the
89109 + internal modules and the user's application.
89110 +
89111 + @{
89112 +*//***************************************************************************/
89113 +
89114 +/**************************************************************************//**
89115 + @Group endian_id Big/Little-Endian Conversion
89116 +
89117 + @Description Routines and macros for Big/Little-Endian conversion and
89118 + general byte swapping.
89119 +
89120 + All routines and macros are expecting unsigned values as
89121 + parameters, but will generate the correct result also for
89122 + signed values. Therefore, signed/unsigned casting is allowed.
89123 + @{
89124 +*//***************************************************************************/
89125 +
89126 +/**************************************************************************//**
89127 + @Collection Byte-Swap Macros
89128 +
89129 + Macros for swapping byte order.
89130 +
89131 + @Cautions The parameters of these macros are evaluated multiple times.
89132 + For calculated expressions or expressions that contain function
89133 + calls it is recommended to use the byte-swap routines.
89134 +
89135 + @{
89136 +*//***************************************************************************/
89137 +
89138 +/**************************************************************************//**
89139 + @Description Swaps the byte order of a given 16-bit value.
89140 +
89141 + @Param[in] val - The 16-bit value to swap.
89142 +
89143 + @Return The byte-swapped value..
89144 +
89145 + @Cautions The given value is evaluated multiple times by this macro.
89146 + For calculated expressions or expressions that contain function
89147 + calls it is recommended to use the SwapUint16() routine.
89148 +
89149 + @hideinitializer
89150 +*//***************************************************************************/
89151 +#define SWAP_UINT16(val) \
89152 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
89153 +
89154 +/**************************************************************************//**
89155 + @Description Swaps the byte order of a given 32-bit value.
89156 +
89157 + @Param[in] val - The 32-bit value to swap.
89158 +
89159 + @Return The byte-swapped value..
89160 +
89161 + @Cautions The given value is evaluated multiple times by this macro.
89162 + For calculated expressions or expressions that contain function
89163 + calls it is recommended to use the SwapUint32() routine.
89164 +
89165 + @hideinitializer
89166 +*//***************************************************************************/
89167 +#define SWAP_UINT32(val) \
89168 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
89169 + (((val) & 0x0000FF00) << 8) | \
89170 + (((val) & 0x00FF0000) >> 8) | \
89171 + (((val) & 0xFF000000) >> 24)))
89172 +
89173 +/**************************************************************************//**
89174 + @Description Swaps the byte order of a given 64-bit value.
89175 +
89176 + @Param[in] val - The 64-bit value to swap.
89177 +
89178 + @Return The byte-swapped value..
89179 +
89180 + @Cautions The given value is evaluated multiple times by this macro.
89181 + For calculated expressions or expressions that contain function
89182 + calls it is recommended to use the SwapUint64() routine.
89183 +
89184 + @hideinitializer
89185 +*//***************************************************************************/
89186 +#define SWAP_UINT64(val) \
89187 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
89188 + (((val) & 0x000000000000FF00ULL) << 40) | \
89189 + (((val) & 0x0000000000FF0000ULL) << 24) | \
89190 + (((val) & 0x00000000FF000000ULL) << 8) | \
89191 + (((val) & 0x000000FF00000000ULL) >> 8) | \
89192 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
89193 + (((val) & 0x00FF000000000000ULL) >> 40) | \
89194 + (((val) & 0xFF00000000000000ULL) >> 56)))
89195 +
89196 +/* @} */
89197 +
89198 +/**************************************************************************//**
89199 + @Collection Byte-Swap Routines
89200 +
89201 + Routines for swapping the byte order of a given parameter and
89202 + returning the swapped value.
89203 +
89204 + These inline routines are safer than the byte-swap macros,
89205 + because they evaluate the parameter expression only once.
89206 + @{
89207 +*//***************************************************************************/
89208 +
89209 +/**************************************************************************//**
89210 + @Function SwapUint16
89211 +
89212 + @Description Returns the byte-swapped value of a given 16-bit value.
89213 +
89214 + @Param[in] val - The 16-bit value.
89215 +
89216 + @Return The byte-swapped value of the parameter.
89217 +*//***************************************************************************/
89218 +static __inline__ uint16_t SwapUint16(uint16_t val)
89219 +{
89220 + return (uint16_t)(((val & 0x00FF) << 8) |
89221 + ((val & 0xFF00) >> 8));
89222 +}
89223 +
89224 +/**************************************************************************//**
89225 + @Function SwapUint32
89226 +
89227 + @Description Returns the byte-swapped value of a given 32-bit value.
89228 +
89229 + @Param[in] val - The 32-bit value.
89230 +
89231 + @Return The byte-swapped value of the parameter.
89232 +*//***************************************************************************/
89233 +static __inline__ uint32_t SwapUint32(uint32_t val)
89234 +{
89235 + return (uint32_t)(((val & 0x000000FF) << 24) |
89236 + ((val & 0x0000FF00) << 8) |
89237 + ((val & 0x00FF0000) >> 8) |
89238 + ((val & 0xFF000000) >> 24));
89239 +}
89240 +
89241 +/**************************************************************************//**
89242 + @Function SwapUint64
89243 +
89244 + @Description Returns the byte-swapped value of a given 64-bit value.
89245 +
89246 + @Param[in] val - The 64-bit value.
89247 +
89248 + @Return The byte-swapped value of the parameter.
89249 +*//***************************************************************************/
89250 +static __inline__ uint64_t SwapUint64(uint64_t val)
89251 +{
89252 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
89253 + ((val & 0x000000000000FF00ULL) << 40) |
89254 + ((val & 0x0000000000FF0000ULL) << 24) |
89255 + ((val & 0x00000000FF000000ULL) << 8) |
89256 + ((val & 0x000000FF00000000ULL) >> 8) |
89257 + ((val & 0x0000FF0000000000ULL) >> 24) |
89258 + ((val & 0x00FF000000000000ULL) >> 40) |
89259 + ((val & 0xFF00000000000000ULL) >> 56));
89260 +}
89261 +
89262 +/* @} */
89263 +
89264 +/**************************************************************************//**
89265 + @Collection In-place Byte-Swap-And-Set Routines
89266 +
89267 + Routines for swapping the byte order of a given variable and
89268 + setting the swapped value back to the same variable.
89269 + @{
89270 +*//***************************************************************************/
89271 +
89272 +/**************************************************************************//**
89273 + @Function SwapUint16P
89274 +
89275 + @Description Swaps the byte order of a given 16-bit variable.
89276 +
89277 + @Param[in] p_Val - Pointer to the 16-bit variable.
89278 +
89279 + @Return None.
89280 +*//***************************************************************************/
89281 +static __inline__ void SwapUint16P(uint16_t *p_Val)
89282 +{
89283 + *p_Val = SwapUint16(*p_Val);
89284 +}
89285 +
89286 +/**************************************************************************//**
89287 + @Function SwapUint32P
89288 +
89289 + @Description Swaps the byte order of a given 32-bit variable.
89290 +
89291 + @Param[in] p_Val - Pointer to the 32-bit variable.
89292 +
89293 + @Return None.
89294 +*//***************************************************************************/
89295 +static __inline__ void SwapUint32P(uint32_t *p_Val)
89296 +{
89297 + *p_Val = SwapUint32(*p_Val);
89298 +}
89299 +
89300 +/**************************************************************************//**
89301 + @Function SwapUint64P
89302 +
89303 + @Description Swaps the byte order of a given 64-bit variable.
89304 +
89305 + @Param[in] p_Val - Pointer to the 64-bit variable.
89306 +
89307 + @Return None.
89308 +*//***************************************************************************/
89309 +static __inline__ void SwapUint64P(uint64_t *p_Val)
89310 +{
89311 + *p_Val = SwapUint64(*p_Val);
89312 +}
89313 +
89314 +/* @} */
89315 +
89316 +
89317 +/**************************************************************************//**
89318 + @Collection Little-Endian Conversion Macros
89319 +
89320 + These macros convert given parameters to or from Little-Endian
89321 + format. Use these macros when you want to read or write a specific
89322 + Little-Endian value in memory, without a-priori knowing the CPU
89323 + byte order.
89324 +
89325 + These macros use the byte-swap routines. For conversion of
89326 + constants in initialization structures, you may use the CONST
89327 + versions of these macros (see below), which are using the
89328 + byte-swap macros instead.
89329 + @{
89330 +*//***************************************************************************/
89331 +
89332 +/**************************************************************************//**
89333 + @Description Converts a given 16-bit value from CPU byte order to
89334 + Little-Endian byte order.
89335 +
89336 + @Param[in] val - The 16-bit value to convert.
89337 +
89338 + @Return The converted value.
89339 +
89340 + @hideinitializer
89341 +*//***************************************************************************/
89342 +#define CPU_TO_LE16(val) SwapUint16(val)
89343 +
89344 +/**************************************************************************//**
89345 + @Description Converts a given 32-bit value from CPU byte order to
89346 + Little-Endian byte order.
89347 +
89348 + @Param[in] val - The 32-bit value to convert.
89349 +
89350 + @Return The converted value.
89351 +
89352 + @hideinitializer
89353 +*//***************************************************************************/
89354 +#define CPU_TO_LE32(val) SwapUint32(val)
89355 +
89356 +/**************************************************************************//**
89357 + @Description Converts a given 64-bit value from CPU byte order to
89358 + Little-Endian byte order.
89359 +
89360 + @Param[in] val - The 64-bit value to convert.
89361 +
89362 + @Return The converted value.
89363 +
89364 + @hideinitializer
89365 +*//***************************************************************************/
89366 +#define CPU_TO_LE64(val) SwapUint64(val)
89367 +
89368 +
89369 +/**************************************************************************//**
89370 + @Description Converts a given 16-bit value from Little-Endian byte order to
89371 + CPU byte order.
89372 +
89373 + @Param[in] val - The 16-bit value to convert.
89374 +
89375 + @Return The converted value.
89376 +
89377 + @hideinitializer
89378 +*//***************************************************************************/
89379 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
89380 +
89381 +/**************************************************************************//**
89382 + @Description Converts a given 32-bit value from Little-Endian byte order to
89383 + CPU byte order.
89384 +
89385 + @Param[in] val - The 32-bit value to convert.
89386 +
89387 + @Return The converted value.
89388 +
89389 + @hideinitializer
89390 +*//***************************************************************************/
89391 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
89392 +
89393 +/**************************************************************************//**
89394 + @Description Converts a given 64-bit value from Little-Endian byte order to
89395 + CPU byte order.
89396 +
89397 + @Param[in] val - The 64-bit value to convert.
89398 +
89399 + @Return The converted value.
89400 +
89401 + @hideinitializer
89402 +*//***************************************************************************/
89403 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
89404 +
89405 +/* @} */
89406 +
89407 +/**************************************************************************//**
89408 + @Collection Little-Endian Constant Conversion Macros
89409 +
89410 + These macros convert given constants to or from Little-Endian
89411 + format. Use these macros when you want to read or write a specific
89412 + Little-Endian constant in memory, without a-priori knowing the
89413 + CPU byte order.
89414 +
89415 + These macros use the byte-swap macros, therefore can be used for
89416 + conversion of constants in initialization structures.
89417 +
89418 + @Cautions The parameters of these macros are evaluated multiple times.
89419 + For non-constant expressions, use the non-CONST macro versions.
89420 +
89421 + @{
89422 +*//***************************************************************************/
89423 +
89424 +/**************************************************************************//**
89425 + @Description Converts a given 16-bit constant from CPU byte order to
89426 + Little-Endian byte order.
89427 +
89428 + @Param[in] val - The 16-bit value to convert.
89429 +
89430 + @Return The converted value.
89431 +
89432 + @hideinitializer
89433 +*//***************************************************************************/
89434 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
89435 +
89436 +/**************************************************************************//**
89437 + @Description Converts a given 32-bit constant from CPU byte order to
89438 + Little-Endian byte order.
89439 +
89440 + @Param[in] val - The 32-bit value to convert.
89441 +
89442 + @Return The converted value.
89443 +
89444 + @hideinitializer
89445 +*//***************************************************************************/
89446 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
89447 +
89448 +/**************************************************************************//**
89449 + @Description Converts a given 64-bit constant from CPU byte order to
89450 + Little-Endian byte order.
89451 +
89452 + @Param[in] val - The 64-bit value to convert.
89453 +
89454 + @Return The converted value.
89455 +
89456 + @hideinitializer
89457 +*//***************************************************************************/
89458 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
89459 +
89460 +
89461 +/**************************************************************************//**
89462 + @Description Converts a given 16-bit constant from Little-Endian byte order
89463 + to CPU byte order.
89464 +
89465 + @Param[in] val - The 16-bit value to convert.
89466 +
89467 + @Return The converted value.
89468 +
89469 + @hideinitializer
89470 +*//***************************************************************************/
89471 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
89472 +
89473 +/**************************************************************************//**
89474 + @Description Converts a given 32-bit constant from Little-Endian byte order
89475 + to CPU byte order.
89476 +
89477 + @Param[in] val - The 32-bit value to convert.
89478 +
89479 + @Return The converted value.
89480 +
89481 + @hideinitializer
89482 +*//***************************************************************************/
89483 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
89484 +
89485 +/**************************************************************************//**
89486 + @Description Converts a given 64-bit constant from Little-Endian byte order
89487 + to CPU byte order.
89488 +
89489 + @Param[in] val - The 64-bit value to convert.
89490 +
89491 + @Return The converted value.
89492 +
89493 + @hideinitializer
89494 +*//***************************************************************************/
89495 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
89496 +
89497 +/* @} */
89498 +
89499 +
89500 +/** @} */ /* end of endian_id group */
89501 +/** @} */ /* end of gen_id group */
89502 +
89503 +
89504 +#endif /* __ENDIAN_EXT_H */
89505 +
89506 --- /dev/null
89507 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
89508 @@ -0,0 +1,205 @@
89509 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89510 + * All rights reserved.
89511 + *
89512 + * Redistribution and use in source and binary forms, with or without
89513 + * modification, are permitted provided that the following conditions are met:
89514 + * * Redistributions of source code must retain the above copyright
89515 + * notice, this list of conditions and the following disclaimer.
89516 + * * Redistributions in binary form must reproduce the above copyright
89517 + * notice, this list of conditions and the following disclaimer in the
89518 + * documentation and/or other materials provided with the distribution.
89519 + * * Neither the name of Freescale Semiconductor nor the
89520 + * names of its contributors may be used to endorse or promote products
89521 + * derived from this software without specific prior written permission.
89522 + *
89523 + *
89524 + * ALTERNATIVELY, this software may be distributed under the terms of the
89525 + * GNU General Public License ("GPL") as published by the Free Software
89526 + * Foundation, either version 2 of that License or (at your option) any
89527 + * later version.
89528 + *
89529 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89530 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89531 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89532 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89533 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89534 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89535 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89536 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89537 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89538 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89539 + */
89540 +
89541 +
89542 +/**************************************************************************//**
89543 + @File enet_ext.h
89544 +
89545 + @Description Ethernet generic definitions and enums.
89546 +*//***************************************************************************/
89547 +
89548 +#ifndef __ENET_EXT_H
89549 +#define __ENET_EXT_H
89550 +
89551 +#include "fsl_enet.h"
89552 +
89553 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
89554 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
89555 +
89556 +
89557 +/**************************************************************************//**
89558 + @Description Ethernet Address
89559 +*//***************************************************************************/
89560 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
89561 +
89562 +/**************************************************************************//**
89563 + @Description Ethernet Address Type.
89564 +*//***************************************************************************/
89565 +typedef enum e_EnetAddrType
89566 +{
89567 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
89568 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
89569 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
89570 +} e_EnetAddrType;
89571 +
89572 +/**************************************************************************//**
89573 + @Description Ethernet MAC-PHY Interface
89574 +*//***************************************************************************/
89575 +typedef enum e_EnetInterface
89576 +{
89577 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
89578 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
89579 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
89580 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
89581 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
89582 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
89583 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
89584 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
89585 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
89586 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
89587 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
89588 +} e_EnetInterface;
89589 +
89590 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
89591 + auto-negotiation between MAC and phy
89592 + or backplane;
89593 + Note: 1000BaseX auto-negotiation relates
89594 + only to interface between MAC and phy/backplane,
89595 + SGMII phy can still synchronize with far-end phy
89596 + at 10Mbps, 100Mbps or 1000Mbps */
89597 +
89598 +/**************************************************************************//**
89599 + @Description Ethernet Duplex Mode
89600 +*//***************************************************************************/
89601 +typedef enum e_EnetDuplexMode
89602 +{
89603 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
89604 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
89605 +} e_EnetDuplexMode;
89606 +
89607 +/**************************************************************************//**
89608 + @Description Ethernet Speed (nominal data rate)
89609 +*//***************************************************************************/
89610 +typedef enum e_EnetSpeed
89611 +{
89612 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
89613 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
89614 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
89615 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
89616 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
89617 +} e_EnetSpeed;
89618 +
89619 +/**************************************************************************//**
89620 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
89621 +*//***************************************************************************/
89622 +typedef enum e_EnetMode
89623 +{
89624 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
89625 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
89626 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
89627 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
89628 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
89629 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
89630 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
89631 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
89632 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
89633 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
89634 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
89635 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
89636 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
89637 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
89638 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
89639 + SGMII phy according to Cisco SGMII specification */
89640 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
89641 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
89642 + SGMII phy according to Cisco SGMII specification */
89643 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
89644 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
89645 + SGMII phy according to Cisco SGMII specification */
89646 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
89647 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
89648 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
89649 + MAC and SGMII phy or backplane */
89650 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
89651 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
89652 + MAC and SGMII phy or backplane */
89653 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
89654 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
89655 + MAC and SGMII phy or backplane */
89656 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
89657 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
89658 + QSGMII phy according to Cisco QSGMII specification */
89659 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
89660 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
89661 + MAC and QSGMII phy or backplane */
89662 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
89663 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
89664 +} e_EnetMode;
89665 +
89666 +
89667 +#define IS_ENET_MODE_VALID(mode) \
89668 + (((mode) == e_ENET_MODE_MII_10 ) || \
89669 + ((mode) == e_ENET_MODE_MII_100 ) || \
89670 + ((mode) == e_ENET_MODE_RMII_10 ) || \
89671 + ((mode) == e_ENET_MODE_RMII_100 ) || \
89672 + ((mode) == e_ENET_MODE_SMII_10 ) || \
89673 + ((mode) == e_ENET_MODE_SMII_100 ) || \
89674 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
89675 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
89676 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
89677 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
89678 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
89679 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
89680 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
89681 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
89682 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
89683 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
89684 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
89685 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
89686 + ((mode) == e_ENET_MODE_XGMII_10000) || \
89687 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
89688 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
89689 + ((mode) == e_ENET_MODE_XFI_10000))
89690 +
89691 +
89692 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
89693 +
89694 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
89695 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
89696 +
89697 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
89698 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
89699 + ((uint64_t)(_enetAddr)[1] << 32) | \
89700 + ((uint64_t)(_enetAddr)[2] << 24) | \
89701 + ((uint64_t)(_enetAddr)[3] << 16) | \
89702 + ((uint64_t)(_enetAddr)[4] << 8) | \
89703 + ((uint64_t)(_enetAddr)[5]))
89704 +
89705 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
89706 + do { \
89707 + int i; \
89708 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
89709 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
89710 + } while (0)
89711 +
89712 +
89713 +#endif /* __ENET_EXT_H */
89714 --- /dev/null
89715 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
89716 @@ -0,0 +1,529 @@
89717 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89718 + * All rights reserved.
89719 + *
89720 + * Redistribution and use in source and binary forms, with or without
89721 + * modification, are permitted provided that the following conditions are met:
89722 + * * Redistributions of source code must retain the above copyright
89723 + * notice, this list of conditions and the following disclaimer.
89724 + * * Redistributions in binary form must reproduce the above copyright
89725 + * notice, this list of conditions and the following disclaimer in the
89726 + * documentation and/or other materials provided with the distribution.
89727 + * * Neither the name of Freescale Semiconductor nor the
89728 + * names of its contributors may be used to endorse or promote products
89729 + * derived from this software without specific prior written permission.
89730 + *
89731 + *
89732 + * ALTERNATIVELY, this software may be distributed under the terms of the
89733 + * GNU General Public License ("GPL") as published by the Free Software
89734 + * Foundation, either version 2 of that License or (at your option) any
89735 + * later version.
89736 + *
89737 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89738 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89739 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89740 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89741 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89742 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89743 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89744 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89745 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89746 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89747 + */
89748 +
89749 +
89750 +/**************************************************************************//**
89751 + @File error_ext.h
89752 +
89753 + @Description Error definitions.
89754 +*//***************************************************************************/
89755 +
89756 +#ifndef __ERROR_EXT_H
89757 +#define __ERROR_EXT_H
89758 +
89759 +#if !defined(NCSW_LINUX)
89760 +#include <errno.h>
89761 +#endif
89762 +
89763 +#include "std_ext.h"
89764 +#include "xx_ext.h"
89765 +#include "core_ext.h"
89766 +
89767 +
89768 +
89769 +
89770 +/**************************************************************************//**
89771 + @Group gen_id General Drivers Utilities
89772 +
89773 + @Description External routines.
89774 +
89775 + @{
89776 +*//***************************************************************************/
89777 +
89778 +/**************************************************************************//**
89779 + @Group gen_error_id Errors, Events and Debug
89780 +
89781 + @Description External routines.
89782 +
89783 + @{
89784 +*//***************************************************************************/
89785 +
89786 +/******************************************************************************
89787 +The scheme below provides the bits description for error codes:
89788 +
89789 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
89790 +| Reserved (should be zero) | Module ID |
89791 +
89792 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
89793 +| Error Type |
89794 +******************************************************************************/
89795 +
89796 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
89797 +
89798 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
89799 + /**< Extract module code from error code (#t_Error) */
89800 +
89801 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
89802 + /**< Extract error type (#e_ErrorType) from
89803 + error code (#t_Error) */
89804 +
89805 +
89806 +/**************************************************************************//**
89807 + @Description Error Type Enumeration
89808 +*//***************************************************************************/
89809 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
89810 +{ /* ------------------------------------------------------------ */
89811 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
89812 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
89813 + /* String: none, or device name. */
89814 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
89815 + /* String: none. */
89816 + ,E_NOT_AVAILABLE = EAGAIN
89817 + /**< Resource is unavailable. */
89818 + /* String: none, unless the operation is not the main goal
89819 + of the function (in this case add resource description). */
89820 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
89821 + /* String: description of item for which allocation failed. */
89822 + ,E_INVALID_ADDRESS = EFAULT
89823 + /**< Invalid address. */
89824 + /* String: description of the specific violation. */
89825 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
89826 + /* String: none, unless the operation is not the main goal
89827 + of the function (in this case add resource description). */
89828 + ,E_ALREADY_EXISTS = EEXIST
89829 + /**< Requested resource or item already exists. */
89830 + /* Use when resource duplication or sharing are not allowed.
89831 + String: none, unless the operation is not the main goal
89832 + of the function (in this case add item description). */
89833 + ,E_INVALID_OPERATION = ENODEV
89834 + /**< The operation/command is invalid (unrecognized). */
89835 + /* String: none. */
89836 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
89837 + /* Use for non-enumeration parameters, and
89838 + only when other error types are not suitable.
89839 + String: parameter description + "(should be <attribute>)",
89840 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
89841 + "Channel number (should be even)". */
89842 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
89843 + /* Don't use this error for enumeration parameters.
89844 + String: parameter description + "(should be %d-%d)",
89845 + e.g: "Number of pad characters (should be 0-15)". */
89846 + ,E_NOT_SUPPORTED = ENOSYS
89847 + /**< The function is not supported or not implemented. */
89848 + /* String: none. */
89849 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
89850 + /* String: none. */
89851 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
89852 + /* String: none, unless the function takes in more than one
89853 + handle (in this case add the handle description) */
89854 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
89855 + /* String: none, unless the function takes in more than one
89856 + ID (in this case add the ID description) */
89857 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
89858 + /* String: pointer description. */
89859 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
89860 + /* Use for enumeration values, only when other error types
89861 + are not suitable.
89862 + String: parameter description. */
89863 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
89864 + /* String: none, unless the function takes in more than one
89865 + communication mode indications (in this case add
89866 + parameter description). */
89867 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
89868 + /* String: none, unless the function takes in more than one
89869 + memory types (in this case add memory description,
89870 + e.g: "Data memory", "Buffer descriptors memory"). */
89871 + ,E_INVALID_CLOCK /**< Invalid clock. */
89872 + /* String: none, unless the function takes in more than one
89873 + clocks (in this case add clock description,
89874 + e.g: "Rx clock", "Tx clock"). */
89875 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
89876 + /* String: description of the conflicting settings. */
89877 + ,E_NOT_ALIGNED /**< Non-aligned address. */
89878 + /* String: parameter description + "(should be %d-bytes aligned)",
89879 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
89880 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
89881 + /* Use only when the resource/item is uniquely identified.
89882 + String: none, unless the operation is not the main goal
89883 + of the function (in this case add item description). */
89884 + ,E_FULL /**< Resource is full. */
89885 + /* String: none, unless the operation is not the main goal
89886 + of the function (in this case add resource description). */
89887 + ,E_EMPTY /**< Resource is empty. */
89888 + /* String: none, unless the operation is not the main goal
89889 + of the function (in this case add resource description). */
89890 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
89891 + /* String: none, unless the operation is not the main goal
89892 + of the function (in this case add item description). */
89893 + ,E_READ_FAILED /**< Read access failed on memory/device. */
89894 + /* String: none, or device name. */
89895 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
89896 + /* String: none. */
89897 + ,E_SEND_FAILED /**< Send operation failed on device. */
89898 + /* String: none, or device name. */
89899 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
89900 + /* String: none, or device name. */
89901 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
89902 + /* String: none. */
89903 +
89904 + ,E_DUMMY_LAST /* NEVER USED */
89905 +
89906 +} e_ErrorType;
89907 +
89908 +/**************************************************************************//**
89909 + @Description Event Type Enumeration
89910 +*//***************************************************************************/
89911 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
89912 +{ /* ------------------------------------------------------------ */
89913 + EV_NO_EVENT = 0 /**< No event; Never used. */
89914 +
89915 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
89916 + complete packets);
89917 + Flags: error flags in case of error, zero otherwise. */
89918 + /* String: reason for discard, e.g: "Error in frame",
89919 + "Disordered frame", "Incomplete frame", "No frame object". */
89920 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
89921 + Flags: usually status flags from the buffer descriptor. */
89922 + /* String: none. */
89923 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
89924 + Flags: usually status flags from the buffer descriptor. */
89925 + /* String: none. */
89926 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
89927 + Flags: zero. */
89928 + /* String: none. */
89929 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
89930 + Flags: zero. */
89931 + /* String: none. */
89932 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
89933 + Flags: zero. */
89934 + /* String: none. */
89935 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
89936 + Flags: zero. */
89937 + /* String: none. */
89938 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
89939 + Flags: zero. */
89940 + /* String: none. */
89941 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
89942 + Flags: zero. */
89943 + /* String: none. */
89944 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
89945 + Flags: zero. */
89946 + /* String: none. */
89947 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
89948 + Flags: zero. */
89949 + /* String: object description (name). */
89950 + ,EV_BUS_ERROR /**< Illegal access on bus;
89951 + Flags: the address (if available) or bus identifier */
89952 + /* String: bus/address/module description. */
89953 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
89954 + Flags: zero. */
89955 + /* String: none. */
89956 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
89957 + Flags: zero. */
89958 + /* String: none. */
89959 + ,EV_DUMMY_LAST
89960 +
89961 +} e_Event;
89962 +
89963 +
89964 +/**************************************************************************//**
89965 + @Collection Debug Levels for Errors and Events
89966 +
89967 + The level description refers to errors only.
89968 + For events, classification is done by the user.
89969 +
89970 + The TRACE, INFO and WARNING levels are allowed only when using
89971 + the DBG macro, and are not allowed when using the error macros
89972 + (RETURN_ERROR or REPORT_ERROR).
89973 + @{
89974 +*//***************************************************************************/
89975 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
89976 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
89977 + configuration. */
89978 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
89979 + parameters may be successful. */
89980 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
89981 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
89982 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
89983 +
89984 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
89985 +
89986 +/* @} */
89987 +
89988 +
89989 +
89990 +#define NO_MSG ("")
89991 +
89992 +#ifndef DEBUG_GLOBAL_LEVEL
89993 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
89994 +#endif /* DEBUG_GLOBAL_LEVEL */
89995 +
89996 +#ifndef ERROR_GLOBAL_LEVEL
89997 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
89998 +#endif /* ERROR_GLOBAL_LEVEL */
89999 +
90000 +#ifndef EVENT_GLOBAL_LEVEL
90001 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
90002 +#endif /* EVENT_GLOBAL_LEVEL */
90003 +
90004 +#ifdef EVENT_LOCAL_LEVEL
90005 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
90006 +#else
90007 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
90008 +#endif /* EVENT_LOCAL_LEVEL */
90009 +
90010 +
90011 +#ifndef DEBUG_DYNAMIC_LEVEL
90012 +#define DEBUG_USING_STATIC_LEVEL
90013 +
90014 +#ifdef DEBUG_STATIC_LEVEL
90015 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
90016 +#else
90017 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
90018 +#endif /* DEBUG_STATIC_LEVEL */
90019 +
90020 +#else /* DEBUG_DYNAMIC_LEVEL */
90021 +#ifdef DEBUG_STATIC_LEVEL
90022 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
90023 +#else
90024 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
90025 +#endif /* DEBUG_STATIC_LEVEL */
90026 +#endif /* !DEBUG_DYNAMIC_LEVEL */
90027 +
90028 +
90029 +#ifndef ERROR_DYNAMIC_LEVEL
90030 +
90031 +#ifdef ERROR_STATIC_LEVEL
90032 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
90033 +#else
90034 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
90035 +#endif /* ERROR_STATIC_LEVEL */
90036 +
90037 +#else /* ERROR_DYNAMIC_LEVEL */
90038 +#ifdef ERROR_STATIC_LEVEL
90039 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
90040 +#else
90041 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
90042 +#endif /* ERROR_STATIC_LEVEL */
90043 +#endif /* !ERROR_DYNAMIC_LEVEL */
90044 +
90045 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
90046 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
90047 +
90048 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
90049 +/* No debug/error/event messages at all */
90050 +#define DBG(_level, _vmsg)
90051 +
90052 +#define REPORT_ERROR(_level, _err, _vmsg)
90053 +
90054 +#define RETURN_ERROR(_level, _err, _vmsg) \
90055 + return ERROR_CODE(_err)
90056 +
90057 +#if (REPORT_EVENTS > 0)
90058 +
90059 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90060 + do { \
90061 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90062 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90063 + } \
90064 + } while (0)
90065 +
90066 +#else
90067 +
90068 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90069 +
90070 +#endif /* (REPORT_EVENTS > 0) */
90071 +
90072 +
90073 +#else /* DEBUG_ERRORS > 0 */
90074 +
90075 +extern const char *dbgLevelStrings[];
90076 +extern const char *moduleStrings[];
90077 +#if (REPORT_EVENTS > 0)
90078 +extern const char *eventStrings[];
90079 +#endif /* (REPORT_EVENTS > 0) */
90080 +
90081 +char * ErrTypeStrings (e_ErrorType err);
90082 +
90083 +
90084 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
90085 +/* No need for DBG macro - debug level is higher anyway */
90086 +#define DBG(_level, _vmsg)
90087 +#else
90088 +#define DBG(_level, _vmsg) \
90089 + do { \
90090 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
90091 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
90092 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90093 + moduleStrings[__ERR_MODULE__ >> 16], \
90094 + PRINT_FMT_PARAMS); \
90095 + XX_Print _vmsg; \
90096 + XX_Print("\r\n"); \
90097 + } \
90098 + } while (0)
90099 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
90100 +
90101 +
90102 +#define REPORT_ERROR(_level, _err, _vmsg) \
90103 + do { \
90104 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
90105 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
90106 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90107 + moduleStrings[__ERR_MODULE__ >> 16], \
90108 + PRINT_FMT_PARAMS, \
90109 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
90110 + XX_Print _vmsg; \
90111 + XX_Print("\r\n"); \
90112 + } \
90113 + } while (0)
90114 +
90115 +
90116 +#define RETURN_ERROR(_level, _err, _vmsg) \
90117 + do { \
90118 + REPORT_ERROR(_level, (_err), _vmsg); \
90119 + return ERROR_CODE(_err); \
90120 + } while (0)
90121 +
90122 +
90123 +#if (REPORT_EVENTS > 0)
90124 +
90125 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90126 + do { \
90127 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90128 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
90129 + dbgLevelStrings[_ev##_LEVEL - 1], \
90130 + moduleStrings[__ERR_MODULE__ >> 16], \
90131 + PRINT_FMT_PARAMS, \
90132 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
90133 + (uint16_t)(_flg)); \
90134 + XX_Print _vmsg; \
90135 + XX_Print("\r\n"); \
90136 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90137 + } \
90138 + } while (0)
90139 +
90140 +#else /* not REPORT_EVENTS */
90141 +
90142 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90143 +
90144 +#endif /* (REPORT_EVENTS > 0) */
90145 +
90146 +#endif /* (DEBUG_ERRORS > 0) */
90147 +
90148 +
90149 +/**************************************************************************//**
90150 + @Function ASSERT_COND
90151 +
90152 + @Description Assertion macro.
90153 +
90154 + @Param[in] _cond - The condition being checked, in positive form;
90155 + Failure of the condition triggers the assert.
90156 +*//***************************************************************************/
90157 +#ifdef DISABLE_ASSERTIONS
90158 +#define ASSERT_COND(_cond)
90159 +#else
90160 +#define ASSERT_COND(_cond) \
90161 + do { \
90162 + if (!(_cond)) { \
90163 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
90164 + PRINT_FMT_PARAMS); \
90165 + XX_Exit(1); \
90166 + } \
90167 + } while (0)
90168 +#endif /* DISABLE_ASSERTIONS */
90169 +
90170 +
90171 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
90172 +
90173 +#define CHECK_INIT_PARAMETERS(handle, f_check)
90174 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
90175 +
90176 +#else
90177 +
90178 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
90179 + do { \
90180 + t_Error err = f_check(handle); \
90181 + if (err != E_OK) { \
90182 + RETURN_ERROR(MAJOR, err, NO_MSG); \
90183 + } \
90184 + } while (0)
90185 +
90186 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
90187 + do { \
90188 + t_Error err = f_check(handle); \
90189 + if (err != E_OK) { \
90190 + REPORT_ERROR(MAJOR, err, NO_MSG); \
90191 + return (retval); \
90192 + } \
90193 + } while (0)
90194 +
90195 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
90196 +
90197 +#ifdef DISABLE_SANITY_CHECKS
90198 +
90199 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
90200 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
90201 +#define SANITY_CHECK_RETURN(_cond, _err)
90202 +#define SANITY_CHECK_EXIT(_cond, _err)
90203 +
90204 +#else /* DISABLE_SANITY_CHECKS */
90205 +
90206 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
90207 + do { \
90208 + if (!(_cond)) { \
90209 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
90210 + } \
90211 + } while (0)
90212 +
90213 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
90214 + do { \
90215 + if (!(_cond)) { \
90216 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90217 + return (retval); \
90218 + } \
90219 + } while (0)
90220 +
90221 +#define SANITY_CHECK_RETURN(_cond, _err) \
90222 + do { \
90223 + if (!(_cond)) { \
90224 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90225 + return; \
90226 + } \
90227 + } while (0)
90228 +
90229 +#define SANITY_CHECK_EXIT(_cond, _err) \
90230 + do { \
90231 + if (!(_cond)) { \
90232 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90233 + XX_Exit(1); \
90234 + } \
90235 + } while (0)
90236 +
90237 +#endif /* DISABLE_SANITY_CHECKS */
90238 +
90239 +/** @} */ /* end of Debug/error Utils group */
90240 +
90241 +/** @} */ /* end of General Utils group */
90242 +
90243 +#endif /* __ERROR_EXT_H */
90244 +
90245 +
90246 --- /dev/null
90247 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90248 @@ -0,0 +1,358 @@
90249 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90250 + * All rights reserved.
90251 + *
90252 + * Redistribution and use in source and binary forms, with or without
90253 + * modification, are permitted provided that the following conditions are met:
90254 + * * Redistributions of source code must retain the above copyright
90255 + * notice, this list of conditions and the following disclaimer.
90256 + * * Redistributions in binary form must reproduce the above copyright
90257 + * notice, this list of conditions and the following disclaimer in the
90258 + * documentation and/or other materials provided with the distribution.
90259 + * * Neither the name of Freescale Semiconductor nor the
90260 + * names of its contributors may be used to endorse or promote products
90261 + * derived from this software without specific prior written permission.
90262 + *
90263 + *
90264 + * ALTERNATIVELY, this software may be distributed under the terms of the
90265 + * GNU General Public License ("GPL") as published by the Free Software
90266 + * Foundation, either version 2 of that License or (at your option) any
90267 + * later version.
90268 + *
90269 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90270 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90271 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90272 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90273 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90274 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90275 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90276 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90277 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90278 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90279 + */
90280 +
90281 +
90282 +/**************************************************************************//**
90283 +
90284 + @File list_ext.h
90285 +
90286 + @Description External prototypes for list.c
90287 +*//***************************************************************************/
90288 +
90289 +#ifndef __LIST_EXT_H
90290 +#define __LIST_EXT_H
90291 +
90292 +
90293 +#include "std_ext.h"
90294 +
90295 +
90296 +/**************************************************************************//**
90297 + @Group etc_id Utility Library Application Programming Interface
90298 +
90299 + @Description External routines.
90300 +
90301 + @{
90302 +*//***************************************************************************/
90303 +
90304 +/**************************************************************************//**
90305 + @Group list_id List
90306 +
90307 + @Description List module functions,definitions and enums.
90308 +
90309 + @{
90310 +*//***************************************************************************/
90311 +
90312 +/**************************************************************************//**
90313 + @Description List structure.
90314 +*//***************************************************************************/
90315 +typedef struct List
90316 +{
90317 + struct List *p_Next; /**< A pointer to the next list object */
90318 + struct List *p_Prev; /**< A pointer to the previous list object */
90319 +} t_List;
90320 +
90321 +
90322 +/**************************************************************************//**
90323 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
90324 +
90325 + @Description Macro to get first/last/next/previous entry in a list.
90326 +
90327 + @Param[in] p_List - A pointer to a list.
90328 +*//***************************************************************************/
90329 +#define LIST_FIRST(p_List) (p_List)->p_Next
90330 +#define LIST_LAST(p_List) (p_List)->p_Prev
90331 +#define LIST_NEXT LIST_FIRST
90332 +#define LIST_PREV LIST_LAST
90333 +
90334 +
90335 +/**************************************************************************//**
90336 + @Function LIST_INIT
90337 +
90338 + @Description Macro for initialization of a list struct.
90339 +
90340 + @Param[in] lst - The t_List object to initialize.
90341 +*//***************************************************************************/
90342 +#define LIST_INIT(lst) {&(lst), &(lst)}
90343 +
90344 +
90345 +/**************************************************************************//**
90346 + @Function LIST
90347 +
90348 + @Description Macro to declare of a list.
90349 +
90350 + @Param[in] listName - The list object name.
90351 +*//***************************************************************************/
90352 +#define LIST(listName) t_List listName = LIST_INIT(listName)
90353 +
90354 +
90355 +/**************************************************************************//**
90356 + @Function INIT_LIST
90357 +
90358 + @Description Macro to initialize a list pointer.
90359 +
90360 + @Param[in] p_List - The list pointer.
90361 +*//***************************************************************************/
90362 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
90363 +
90364 +
90365 +/**************************************************************************//**
90366 + @Function LIST_OBJECT
90367 +
90368 + @Description Macro to get the struct (object) for this entry.
90369 +
90370 + @Param[in] type - The type of the struct (object) this list is embedded in.
90371 + @Param[in] member - The name of the t_List object within the struct.
90372 +
90373 + @Return The structure pointer for this entry.
90374 +*//***************************************************************************/
90375 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
90376 +#define LIST_OBJECT(p_List, type, member) \
90377 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
90378 +
90379 +
90380 +/**************************************************************************//**
90381 + @Function LIST_FOR_EACH
90382 +
90383 + @Description Macro to iterate over a list.
90384 +
90385 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90386 + @Param[in] p_Head - A pointer to the head for your list pointer.
90387 +
90388 + @Cautions You can't delete items with this routine.
90389 + For deletion use LIST_FOR_EACH_SAFE().
90390 +*//***************************************************************************/
90391 +#define LIST_FOR_EACH(p_Pos, p_Head) \
90392 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
90393 +
90394 +
90395 +/**************************************************************************//**
90396 + @Function LIST_FOR_EACH_SAFE
90397 +
90398 + @Description Macro to iterate over a list safe against removal of list entry.
90399 +
90400 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90401 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90402 + @Param[in] p_Head - A pointer to the head for your list pointer.
90403 +*//***************************************************************************/
90404 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
90405 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
90406 + p_Pos != (p_Head); \
90407 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
90408 +
90409 +
90410 +/**************************************************************************//**
90411 + @Function LIST_FOR_EACH_OBJECT_SAFE
90412 +
90413 + @Description Macro to iterate over list of given type safely.
90414 +
90415 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90416 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90417 + @Param[in] type - The type of the struct this is embedded in.
90418 + @Param[in] p_Head - A pointer to the head for your list pointer.
90419 + @Param[in] member - The name of the list_struct within the struct.
90420 +
90421 + @Cautions You can't delete items with this routine.
90422 + For deletion use LIST_FOR_EACH_SAFE().
90423 +*//***************************************************************************/
90424 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
90425 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
90426 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
90427 + &p_Pos->member != (p_Head); \
90428 + p_Pos = p_Tmp, \
90429 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
90430 +
90431 +/**************************************************************************//**
90432 + @Function LIST_FOR_EACH_OBJECT
90433 +
90434 + @Description Macro to iterate over list of given type.
90435 +
90436 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90437 + @Param[in] type - The type of the struct this is embedded in.
90438 + @Param[in] p_Head - A pointer to the head for your list pointer.
90439 + @Param[in] member - The name of the list_struct within the struct.
90440 +
90441 + @Cautions You can't delete items with this routine.
90442 + For deletion use LIST_FOR_EACH_SAFE().
90443 +*//***************************************************************************/
90444 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
90445 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
90446 + &p_Pos->member != (p_Head); \
90447 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
90448 +
90449 +
90450 +/**************************************************************************//**
90451 + @Function LIST_Add
90452 +
90453 + @Description Add a new entry to a list.
90454 +
90455 + Insert a new entry after the specified head.
90456 + This is good for implementing stacks.
90457 +
90458 + @Param[in] p_New - A pointer to a new list entry to be added.
90459 + @Param[in] p_Head - A pointer to a list head to add it after.
90460 +
90461 + @Return none.
90462 +*//***************************************************************************/
90463 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
90464 +{
90465 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
90466 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
90467 + LIST_PREV(p_New) = p_Head;
90468 + LIST_NEXT(p_Head) = p_New;
90469 +}
90470 +
90471 +
90472 +/**************************************************************************//**
90473 + @Function LIST_AddToTail
90474 +
90475 + @Description Add a new entry to a list.
90476 +
90477 + Insert a new entry before the specified head.
90478 + This is useful for implementing queues.
90479 +
90480 + @Param[in] p_New - A pointer to a new list entry to be added.
90481 + @Param[in] p_Head - A pointer to a list head to add it before.
90482 +
90483 + @Return none.
90484 +*//***************************************************************************/
90485 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
90486 +{
90487 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
90488 + LIST_PREV(p_New) = LIST_PREV(p_Head);
90489 + LIST_NEXT(p_New) = p_Head;
90490 + LIST_PREV(p_Head) = p_New;
90491 +}
90492 +
90493 +
90494 +/**************************************************************************//**
90495 + @Function LIST_Del
90496 +
90497 + @Description Deletes entry from a list.
90498 +
90499 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90500 +
90501 + @Return none.
90502 +
90503 + @Cautions LIST_IsEmpty() on entry does not return true after this,
90504 + the entry is in an undefined state.
90505 +*//***************************************************************************/
90506 +static __inline__ void LIST_Del(t_List *p_Entry)
90507 +{
90508 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
90509 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
90510 +}
90511 +
90512 +
90513 +/**************************************************************************//**
90514 + @Function LIST_DelAndInit
90515 +
90516 + @Description Deletes entry from list and reinitialize it.
90517 +
90518 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90519 +
90520 + @Return none.
90521 +*//***************************************************************************/
90522 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
90523 +{
90524 + LIST_Del(p_Entry);
90525 + INIT_LIST(p_Entry);
90526 +}
90527 +
90528 +
90529 +/**************************************************************************//**
90530 + @Function LIST_Move
90531 +
90532 + @Description Delete from one list and add as another's head.
90533 +
90534 + @Param[in] p_Entry - A pointer to the list entry to move.
90535 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
90536 +
90537 + @Return none.
90538 +*//***************************************************************************/
90539 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
90540 +{
90541 + LIST_Del(p_Entry);
90542 + LIST_Add(p_Entry, p_Head);
90543 +}
90544 +
90545 +
90546 +/**************************************************************************//**
90547 + @Function LIST_MoveToTail
90548 +
90549 + @Description Delete from one list and add as another's tail.
90550 +
90551 + @Param[in] p_Entry - A pointer to the entry to move.
90552 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
90553 +
90554 + @Return none.
90555 +*//***************************************************************************/
90556 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
90557 +{
90558 + LIST_Del(p_Entry);
90559 + LIST_AddToTail(p_Entry, p_Head);
90560 +}
90561 +
90562 +
90563 +/**************************************************************************//**
90564 + @Function LIST_IsEmpty
90565 +
90566 + @Description Tests whether a list is empty.
90567 +
90568 + @Param[in] p_List - A pointer to the list to test.
90569 +
90570 + @Return 1 if the list is empty, 0 otherwise.
90571 +*//***************************************************************************/
90572 +static __inline__ int LIST_IsEmpty(t_List *p_List)
90573 +{
90574 + return (LIST_FIRST(p_List) == p_List);
90575 +}
90576 +
90577 +
90578 +/**************************************************************************//**
90579 + @Function LIST_Append
90580 +
90581 + @Description Join two lists.
90582 +
90583 + @Param[in] p_NewList - A pointer to the new list to add.
90584 + @Param[in] p_Head - A pointer to the place to add it in the first list.
90585 +
90586 + @Return none.
90587 +*//***************************************************************************/
90588 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
90589 +
90590 +
90591 +/**************************************************************************//**
90592 + @Function LIST_NumOfObjs
90593 +
90594 + @Description Counts number of objects in the list
90595 +
90596 + @Param[in] p_List - A pointer to the list which objects are to be counted.
90597 +
90598 + @Return Number of objects in the list.
90599 +*//***************************************************************************/
90600 +int LIST_NumOfObjs(t_List *p_List);
90601 +
90602 +/** @} */ /* end of list_id group */
90603 +/** @} */ /* end of etc_id group */
90604 +
90605 +
90606 +#endif /* __LIST_EXT_H */
90607 --- /dev/null
90608 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
90609 @@ -0,0 +1,318 @@
90610 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90611 + * All rights reserved.
90612 + *
90613 + * Redistribution and use in source and binary forms, with or without
90614 + * modification, are permitted provided that the following conditions are met:
90615 + * * Redistributions of source code must retain the above copyright
90616 + * notice, this list of conditions and the following disclaimer.
90617 + * * Redistributions in binary form must reproduce the above copyright
90618 + * notice, this list of conditions and the following disclaimer in the
90619 + * documentation and/or other materials provided with the distribution.
90620 + * * Neither the name of Freescale Semiconductor nor the
90621 + * names of its contributors may be used to endorse or promote products
90622 + * derived from this software without specific prior written permission.
90623 + *
90624 + *
90625 + * ALTERNATIVELY, this software may be distributed under the terms of the
90626 + * GNU General Public License ("GPL") as published by the Free Software
90627 + * Foundation, either version 2 of that License or (at your option) any
90628 + * later version.
90629 + *
90630 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90631 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90632 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90633 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90634 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90635 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90636 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90637 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90638 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90639 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90640 + */
90641 +
90642 +
90643 +/**************************************************************************//**
90644 +
90645 + @File mem_ext.h
90646 +
90647 + @Description External prototypes for the memory manager object
90648 +*//***************************************************************************/
90649 +
90650 +#ifndef __MEM_EXT_H
90651 +#define __MEM_EXT_H
90652 +
90653 +#include "std_ext.h"
90654 +#include "part_ext.h"
90655 +
90656 +
90657 +/**************************************************************************//**
90658 + @Group etc_id Utility Library Application Programming Interface
90659 +
90660 + @Description External routines.
90661 +
90662 + @{
90663 +*//***************************************************************************/
90664 +
90665 +/**************************************************************************//**
90666 + @Group mem_id Slab Memory Manager
90667 +
90668 + @Description Slab Memory Manager module functions, definitions and enums.
90669 +
90670 + @{
90671 +*//***************************************************************************/
90672 +
90673 +/* Each block is of the following structure:
90674 + *
90675 + *
90676 + * +-----------+----------+---------------------------+-----------+-----------+
90677 + * | Alignment | Prefix | Data | Postfix | Alignment |
90678 + * | field | field | field | field | Padding |
90679 + * | | | | | |
90680 + * +-----------+----------+---------------------------+-----------+-----------+
90681 + * and at the beginning of all bytes, an additional optional padding might reside
90682 + * to ensure that the first blocks data field is aligned as requested.
90683 + */
90684 +
90685 +
90686 +#define MEM_MAX_NAME_LENGTH 8
90687 +
90688 +/**************************************************************************//*
90689 + @Description Memory Segment structure
90690 +*//***************************************************************************/
90691 +
90692 +typedef struct
90693 +{
90694 + char name[MEM_MAX_NAME_LENGTH];
90695 + /* The segment's name */
90696 + uint8_t **p_Bases; /* Base addresses of the segments */
90697 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
90698 + t_Handle h_Spinlock;
90699 + uint16_t dataSize; /* Size of each data block */
90700 + uint16_t prefixSize; /* How many bytes to reserve before the data */
90701 + uint16_t postfixSize; /* How many bytes to reserve after the data */
90702 + uint16_t alignment; /* Requested alignment for the data field */
90703 + int allocOwner; /* Memory allocation owner */
90704 + uint32_t getFailures; /* Number of times get failed */
90705 + uint32_t num; /* Number of blocks in segment */
90706 + uint32_t current; /* Current block */
90707 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
90708 +#ifdef DEBUG_MEM_LEAKS
90709 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
90710 + uint32_t blockOffset;
90711 + uint32_t blockSize;
90712 +#endif /* DEBUG_MEM_LEAKS */
90713 +} t_MemorySegment;
90714 +
90715 +
90716 +
90717 +/**************************************************************************//**
90718 + @Function MEM_Init
90719 +
90720 + @Description Create a new memory segment.
90721 +
90722 + @Param[in] name - Name of memory partition.
90723 + @Param[in] p_Handle - Handle to new segment is returned through here.
90724 + @Param[in] num - Number of blocks in new segment.
90725 + @Param[in] dataSize - Size of blocks in segment.
90726 + @Param[in] prefixSize - How many bytes to allocate before the data.
90727 + @Param[in] postfixSize - How many bytes to allocate after the data.
90728 + @Param[in] alignment - Requested alignment for data field (in bytes).
90729 +
90730 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90731 +*//***************************************************************************/
90732 +t_Error MEM_Init(char name[],
90733 + t_Handle *p_Handle,
90734 + uint32_t num,
90735 + uint16_t dataSize,
90736 + uint16_t prefixSize,
90737 + uint16_t postfixSize,
90738 + uint16_t alignment);
90739 +
90740 +/**************************************************************************//**
90741 + @Function MEM_InitSmart
90742 +
90743 + @Description Create a new memory segment.
90744 +
90745 + @Param[in] name - Name of memory partition.
90746 + @Param[in] p_Handle - Handle to new segment is returned through here.
90747 + @Param[in] num - Number of blocks in new segment.
90748 + @Param[in] dataSize - Size of blocks in segment.
90749 + @Param[in] prefixSize - How many bytes to allocate before the data.
90750 + @Param[in] postfixSize - How many bytes to allocate after the data.
90751 + @Param[in] alignment - Requested alignment for data field (in bytes).
90752 + @Param[in] memPartitionId - Memory partition ID for allocation.
90753 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
90754 + continuously or not.
90755 +
90756 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90757 +*//***************************************************************************/
90758 +t_Error MEM_InitSmart(char name[],
90759 + t_Handle *p_Handle,
90760 + uint32_t num,
90761 + uint16_t dataSize,
90762 + uint16_t prefixSize,
90763 + uint16_t postfixSize,
90764 + uint16_t alignment,
90765 + uint8_t memPartitionId,
90766 + bool consecutiveMem);
90767 +
90768 +/**************************************************************************//**
90769 + @Function MEM_InitByAddress
90770 +
90771 + @Description Create a new memory segment with a specified base address.
90772 +
90773 + @Param[in] name - Name of memory partition.
90774 + @Param[in] p_Handle - Handle to new segment is returned through here.
90775 + @Param[in] num - Number of blocks in new segment.
90776 + @Param[in] dataSize - Size of blocks in segment.
90777 + @Param[in] prefixSize - How many bytes to allocate before the data.
90778 + @Param[in] postfixSize - How many bytes to allocate after the data.
90779 + @Param[in] alignment - Requested alignment for data field (in bytes).
90780 + @Param[in] address - The required base address.
90781 +
90782 + @Return E_OK - success, E_NO_MEMORY - out of memory.
90783 + *//***************************************************************************/
90784 +t_Error MEM_InitByAddress(char name[],
90785 + t_Handle *p_Handle,
90786 + uint32_t num,
90787 + uint16_t dataSize,
90788 + uint16_t prefixSize,
90789 + uint16_t postfixSize,
90790 + uint16_t alignment,
90791 + uint8_t *address);
90792 +
90793 +/**************************************************************************//**
90794 + @Function MEM_Free
90795 +
90796 + @Description Free a specific memory segment.
90797 +
90798 + @Param[in] h_Mem - Handle to memory segment.
90799 +
90800 + @Return None.
90801 +*//***************************************************************************/
90802 +void MEM_Free(t_Handle h_Mem);
90803 +
90804 +/**************************************************************************//**
90805 + @Function MEM_Get
90806 +
90807 + @Description Get a block of memory from a segment.
90808 +
90809 + @Param[in] h_Mem - Handle to memory segment.
90810 +
90811 + @Return Pointer to new memory block on success,0 otherwise.
90812 +*//***************************************************************************/
90813 +void * MEM_Get(t_Handle h_Mem);
90814 +
90815 +/**************************************************************************//**
90816 + @Function MEM_GetN
90817 +
90818 + @Description Get up to N blocks of memory from a segment.
90819 +
90820 + The blocks are assumed to be of a fixed size (one size per segment).
90821 +
90822 + @Param[in] h_Mem - Handle to memory segment.
90823 + @Param[in] num - Number of blocks to allocate.
90824 + @Param[out] array - Array of at least num pointers to which the addresses
90825 + of the allocated blocks are written.
90826 +
90827 + @Return The number of blocks actually allocated.
90828 +
90829 + @Cautions Interrupts are disabled for all of the allocation loop.
90830 + Although this loop is very short for each block (several machine
90831 + instructions), you should not allocate a very large number
90832 + of blocks via this routine.
90833 +*//***************************************************************************/
90834 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
90835 +
90836 +/**************************************************************************//**
90837 + @Function MEM_Put
90838 +
90839 + @Description Put a block of memory back to a segment.
90840 +
90841 + @Param[in] h_Mem - Handle to memory segment.
90842 + @Param[in] p_Block - The block to return.
90843 +
90844 + @Return Pointer to new memory block on success,0 otherwise.
90845 +*//***************************************************************************/
90846 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
90847 +
90848 +/**************************************************************************//**
90849 + @Function MEM_ComputePartitionSize
90850 +
90851 + @Description calculate a tight upper boundary of the size of a partition with
90852 + given attributes.
90853 +
90854 + The returned value is suitable if one wants to use MEM_InitByAddress().
90855 +
90856 + @Param[in] num - The number of blocks in the segment.
90857 + @Param[in] dataSize - Size of block to get.
90858 + @Param[in] prefixSize - The prefix size
90859 + @Param postfixSize - The postfix size
90860 + @Param[in] alignment - The requested alignment value (in bytes)
90861 +
90862 + @Return The memory block size a segment with the given attributes needs.
90863 +*//***************************************************************************/
90864 +uint32_t MEM_ComputePartitionSize(uint32_t num,
90865 + uint16_t dataSize,
90866 + uint16_t prefixSize,
90867 + uint16_t postfixSize,
90868 + uint16_t alignment);
90869 +
90870 +#ifdef DEBUG_MEM_LEAKS
90871 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
90872 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
90873 +#endif /* !(defined(__MWERKS__) && ... */
90874 +
90875 +/**************************************************************************//**
90876 + @Function MEM_CheckLeaks
90877 +
90878 + @Description Report MEM object leaks.
90879 +
90880 + This routine is automatically called by the MEM_Free() routine,
90881 + but it can also be invoked while the MEM object is alive.
90882 +
90883 + @Param[in] h_Mem - Handle to memory segment.
90884 +
90885 + @Return None.
90886 +*//***************************************************************************/
90887 +void MEM_CheckLeaks(t_Handle h_Mem);
90888 +
90889 +#else /* not DEBUG_MEM_LEAKS */
90890 +#define MEM_CheckLeaks(h_Mem)
90891 +#endif /* not DEBUG_MEM_LEAKS */
90892 +
90893 +/**************************************************************************//**
90894 + @Description Get base of MEM
90895 +*//***************************************************************************/
90896 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
90897 +
90898 +/**************************************************************************//**
90899 + @Description Get size of MEM block
90900 +*//***************************************************************************/
90901 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
90902 +
90903 +/**************************************************************************//**
90904 + @Description Get prefix size of MEM block
90905 +*//***************************************************************************/
90906 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
90907 +
90908 +/**************************************************************************//**
90909 + @Description Get postfix size of MEM block
90910 +*//***************************************************************************/
90911 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
90912 +
90913 +/**************************************************************************//**
90914 + @Description Get alignment of MEM block (in bytes)
90915 +*//***************************************************************************/
90916 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
90917 +
90918 +/**************************************************************************//**
90919 + @Description Get the number of blocks in the segment
90920 +*//***************************************************************************/
90921 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
90922 +
90923 +/** @} */ /* end of MEM group */
90924 +/** @} */ /* end of etc_id group */
90925 +
90926 +
90927 +#endif /* __MEM_EXT_H */
90928 --- /dev/null
90929 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
90930 @@ -0,0 +1,208 @@
90931 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90932 + * All rights reserved.
90933 + *
90934 + * Redistribution and use in source and binary forms, with or without
90935 + * modification, are permitted provided that the following conditions are met:
90936 + * * Redistributions of source code must retain the above copyright
90937 + * notice, this list of conditions and the following disclaimer.
90938 + * * Redistributions in binary form must reproduce the above copyright
90939 + * notice, this list of conditions and the following disclaimer in the
90940 + * documentation and/or other materials provided with the distribution.
90941 + * * Neither the name of Freescale Semiconductor nor the
90942 + * names of its contributors may be used to endorse or promote products
90943 + * derived from this software without specific prior written permission.
90944 + *
90945 + *
90946 + * ALTERNATIVELY, this software may be distributed under the terms of the
90947 + * GNU General Public License ("GPL") as published by the Free Software
90948 + * Foundation, either version 2 of that License or (at your option) any
90949 + * later version.
90950 + *
90951 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90952 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90953 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90954 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90955 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90956 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90957 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90958 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90959 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90960 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90961 + */
90962 +
90963 +
90964 +/**************************************************************************//**
90965 +
90966 + @File memcpy_ext.h
90967 +
90968 + @Description Efficient functions for copying and setting blocks of memory.
90969 +*//***************************************************************************/
90970 +
90971 +#ifndef __MEMCPY_EXT_H
90972 +#define __MEMCPY_EXT_H
90973 +
90974 +#include "std_ext.h"
90975 +
90976 +
90977 +/**************************************************************************//**
90978 + @Group etc_id Utility Library Application Programming Interface
90979 +
90980 + @Description External routines.
90981 +
90982 + @{
90983 +*//***************************************************************************/
90984 +
90985 +/**************************************************************************//**
90986 + @Group mem_cpy Memory Copy
90987 +
90988 + @Description Memory Copy module functions,definitions and enums.
90989 +
90990 + @{
90991 +*//***************************************************************************/
90992 +
90993 +/**************************************************************************//**
90994 + @Function MemCpy32
90995 +
90996 + @Description Copies one memory buffer into another one in 4-byte chunks!
90997 + Which should be more efficient than byte by byte.
90998 +
90999 + For large buffers (over 60 bytes) this function is about 4 times
91000 + more efficient than the trivial memory copy. For short buffers
91001 + it is reduced to the trivial copy and may be a bit worse.
91002 +
91003 + @Param[in] pDst - The address of the destination buffer.
91004 + @Param[in] pSrc - The address of the source buffer.
91005 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91006 +
91007 + @Return pDst (the address of the destination buffer).
91008 +
91009 + @Cautions There is no parameter or boundary checking! It is up to the user
91010 + to supply non-null parameters as source & destination and size
91011 + that actually fits into the destination buffer.
91012 +*//***************************************************************************/
91013 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
91014 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91015 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
91016 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91017 +
91018 +/**************************************************************************//**
91019 + @Function MemCpy64
91020 +
91021 + @Description Copies one memory buffer into another one in 8-byte chunks!
91022 + Which should be more efficient than byte by byte.
91023 +
91024 + For large buffers (over 60 bytes) this function is about 8 times
91025 + more efficient than the trivial memory copy. For short buffers
91026 + it is reduced to the trivial copy and may be a bit worse.
91027 +
91028 + Some testing suggests that MemCpy32() preforms better than
91029 + MemCpy64() over small buffers. On average they break even at
91030 + 100 byte buffers. For buffers larger than that MemCpy64 is
91031 + superior.
91032 +
91033 + @Param[in] pDst - The address of the destination buffer.
91034 + @Param[in] pSrc - The address of the source buffer.
91035 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91036 +
91037 + @Return pDst (the address of the destination buffer).
91038 +
91039 + @Cautions There is no parameter or boundary checking! It is up to the user
91040 + to supply non null parameters as source & destination and size
91041 + that actually fits into their buffer.
91042 +
91043 + Do not use under Linux.
91044 +*//***************************************************************************/
91045 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
91046 +
91047 +/**************************************************************************//**
91048 + @Function MemSet32
91049 +
91050 + @Description Sets all bytes of a memory buffer to a specific value, in
91051 + 4-byte chunks.
91052 +
91053 + @Param[in] pDst - The address of the destination buffer.
91054 + @Param[in] val - Value to set destination bytes to.
91055 + @Param[in] size - The number of bytes that will be set to val.
91056 +
91057 + @Return pDst (the address of the destination buffer).
91058 +
91059 + @Cautions There is no parameter or boundary checking! It is up to the user
91060 + to supply non null parameter as destination and size
91061 + that actually fits into the destination buffer.
91062 +*//***************************************************************************/
91063 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
91064 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
91065 +
91066 +/**************************************************************************//**
91067 + @Function MemSet64
91068 +
91069 + @Description Sets all bytes of a memory buffer to a specific value, in
91070 + 8-byte chunks.
91071 +
91072 + @Param[in] pDst - The address of the destination buffer.
91073 + @Param[in] val - Value to set destination bytes to.
91074 + @Param[in] size - The number of bytes that will be set to val.
91075 +
91076 + @Return pDst (the address of the destination buffer).
91077 +
91078 + @Cautions There is no parameter or boundary checking! It is up to the user
91079 + to supply non null parameter as destination and size
91080 + that actually fits into the destination buffer.
91081 +*//***************************************************************************/
91082 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
91083 +
91084 +/**************************************************************************//**
91085 + @Function MemDisp
91086 +
91087 + @Description Displays a block of memory in chunks of 32 bits.
91088 +
91089 + @Param[in] addr - The address of the memory to display.
91090 + @Param[in] size - The number of bytes that will be displayed.
91091 +
91092 + @Return None.
91093 +
91094 + @Cautions There is no parameter or boundary checking! It is up to the user
91095 + to supply non null parameter as destination and size
91096 + that actually fits into the destination buffer.
91097 +*//***************************************************************************/
91098 +void MemDisp(uint8_t *addr, int size);
91099 +
91100 +/**************************************************************************//**
91101 + @Function MemCpy8
91102 +
91103 + @Description Trivial copy one memory buffer into another byte by byte
91104 +
91105 + @Param[in] pDst - The address of the destination buffer.
91106 + @Param[in] pSrc - The address of the source buffer.
91107 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91108 +
91109 + @Return pDst (the address of the destination buffer).
91110 +
91111 + @Cautions There is no parameter or boundary checking! It is up to the user
91112 + to supply non-null parameters as source & destination and size
91113 + that actually fits into the destination buffer.
91114 +*//***************************************************************************/
91115 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
91116 +
91117 +/**************************************************************************//**
91118 + @Function MemSet8
91119 +
91120 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
91121 +
91122 + @Param[in] pDst - The address of the destination buffer.
91123 + @Param[in] c - Value to set destination bytes to.
91124 + @Param[in] size - The number of bytes that will be set to val.
91125 +
91126 + @Return pDst (the address of the destination buffer).
91127 +
91128 + @Cautions There is no parameter or boundary checking! It is up to the user
91129 + to supply non null parameter as destination and size
91130 + that actually fits into the destination buffer.
91131 +*//***************************************************************************/
91132 +void * MemSet8(void* pDst, int c, uint32_t size);
91133 +
91134 +/** @} */ /* end of mem_cpy group */
91135 +/** @} */ /* end of etc_id group */
91136 +
91137 +
91138 +#endif /* __MEMCPY_EXT_H */
91139 --- /dev/null
91140 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91141 @@ -0,0 +1,310 @@
91142 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91143 + * All rights reserved.
91144 + *
91145 + * Redistribution and use in source and binary forms, with or without
91146 + * modification, are permitted provided that the following conditions are met:
91147 + * * Redistributions of source code must retain the above copyright
91148 + * notice, this list of conditions and the following disclaimer.
91149 + * * Redistributions in binary form must reproduce the above copyright
91150 + * notice, this list of conditions and the following disclaimer in the
91151 + * documentation and/or other materials provided with the distribution.
91152 + * * Neither the name of Freescale Semiconductor nor the
91153 + * names of its contributors may be used to endorse or promote products
91154 + * derived from this software without specific prior written permission.
91155 + *
91156 + *
91157 + * ALTERNATIVELY, this software may be distributed under the terms of the
91158 + * GNU General Public License ("GPL") as published by the Free Software
91159 + * Foundation, either version 2 of that License or (at your option) any
91160 + * later version.
91161 + *
91162 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91163 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91164 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91165 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91166 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91167 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91168 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91169 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91170 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91171 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91172 + */
91173 +
91174 +
91175 +/**************************************************************************//**
91176 + @File mm_ext.h
91177 +
91178 + @Description Memory Manager Application Programming Interface
91179 +*//***************************************************************************/
91180 +#ifndef __MM_EXT
91181 +#define __MM_EXT
91182 +
91183 +#include "std_ext.h"
91184 +
91185 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
91186 + where maximum alignment defined as
91187 + MM_MAX_ALIGNMENT power of 2 */
91188 +
91189 +#define MM_MAX_NAME_LEN 32
91190 +
91191 +/**************************************************************************//**
91192 + @Group etc_id Utility Library Application Programming Interface
91193 +
91194 + @Description External routines.
91195 +
91196 + @{
91197 +*//***************************************************************************/
91198 +
91199 +/**************************************************************************//**
91200 + @Group mm_grp Flexible Memory Manager
91201 +
91202 + @Description Flexible Memory Manager module functions,definitions and enums.
91203 + (All of the following functions,definitions and enums can be found in mm_ext.h)
91204 +
91205 + @{
91206 +*//***************************************************************************/
91207 +
91208 +
91209 +/**************************************************************************//**
91210 + @Function MM_Init
91211 +
91212 + @Description Initializes a new MM object.
91213 +
91214 + It initializes a new memory block consisting of base address
91215 + and size of the available memory by calling to MemBlock_Init
91216 + routine. It is also initializes a new free block for each
91217 + by calling FreeBlock_Init routine, which is pointed to
91218 + the almost all memory started from the required alignment
91219 + from the base address and to the end of the memory.
91220 + The handle to the new MM object is returned via "MM"
91221 + argument (passed by reference).
91222 +
91223 + @Param[in] h_MM - Handle to the MM object.
91224 + @Param[in] base - Base address of the MM.
91225 + @Param[in] size - Size of the MM.
91226 +
91227 + @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.
91228 +*//***************************************************************************/
91229 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
91230 +
91231 +/**************************************************************************//**
91232 + @Function MM_Get
91233 +
91234 + @Description Allocates a block of memory according to the given size and the alignment.
91235 +
91236 + The Alignment argument tells from which
91237 + free list allocate a block of memory. 2^alignment indicates
91238 + the alignment that the base address of the allocated block
91239 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91240 + are available for the alignment argument.
91241 + The routine passes through the specific free list of free
91242 + blocks and seeks for a first block that have anough memory
91243 + that is required (best fit).
91244 + After the block is found and data is allocated, it calls
91245 + the internal MM_CutFree routine to update all free lists
91246 + do not include a just allocated block. Of course, each
91247 + free list contains a free blocks with the same alignment.
91248 + It is also creates a busy block that holds
91249 + information about an allocated block.
91250 +
91251 + @Param[in] h_MM - Handle to the MM object.
91252 + @Param[in] size - Size of the MM.
91253 + @Param[in] alignment - Index as a power of two defines a required
91254 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91255 + @Param[in] name - The name that specifies an allocated block.
91256 +
91257 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
91258 +*//***************************************************************************/
91259 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
91260 +
91261 +/**************************************************************************//**
91262 + @Function MM_GetBase
91263 +
91264 + @Description Gets the base address of the required MM objects.
91265 +
91266 + @Param[in] h_MM - Handle to the MM object.
91267 +
91268 + @Return base address of the block.
91269 +*//***************************************************************************/
91270 +uint64_t MM_GetBase(t_Handle h_MM);
91271 +
91272 +/**************************************************************************//**
91273 + @Function MM_GetForce
91274 +
91275 + @Description Force memory allocation.
91276 +
91277 + It means to allocate a block of memory of the given
91278 + size from the given base address.
91279 + The routine checks if the required block can be allocated
91280 + (that is it is free) and then, calls the internal MM_CutFree
91281 + routine to update all free lists do not include that block.
91282 +
91283 + @Param[in] h_MM - Handle to the MM object.
91284 + @Param[in] base - Base address of the MM.
91285 + @Param[in] size - Size of the MM.
91286 + @Param[in] name - Name that specifies an allocated block.
91287 +
91288 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
91289 +*//***************************************************************************/
91290 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
91291 +
91292 +/**************************************************************************//**
91293 + @Function MM_GetForceMin
91294 +
91295 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
91296 +
91297 + The Alignment argument tells from which
91298 + free list allocate a block of memory. 2^alignment indicates
91299 + the alignment that the base address of the allocated block
91300 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91301 + are available for the alignment argument.
91302 + The minimum baser address forces the location of the block
91303 + to be from a given address onward.
91304 + The routine passes through the specific free list of free
91305 + blocks and seeks for the first base address equal or smaller
91306 + than the required minimum address and end address larger than
91307 + than the required base + its size - i.e. that may contain
91308 + the required block.
91309 + After the block is found and data is allocated, it calls
91310 + the internal MM_CutFree routine to update all free lists
91311 + do not include a just allocated block. Of course, each
91312 + free list contains a free blocks with the same alignment.
91313 + It is also creates a busy block that holds
91314 + information about an allocated block.
91315 +
91316 + @Param[in] h_MM - Handle to the MM object.
91317 + @Param[in] size - Size of the MM.
91318 + @Param[in] alignment - Index as a power of two defines a required
91319 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91320 + @Param[in] min - The minimum base address of the block.
91321 + @Param[in] name - Name that specifies an allocated block.
91322 +
91323 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
91324 +*//***************************************************************************/
91325 +uint64_t MM_GetForceMin(t_Handle h_MM,
91326 + uint64_t size,
91327 + uint64_t alignment,
91328 + uint64_t min,
91329 + char *name);
91330 +
91331 +/**************************************************************************//**
91332 + @Function MM_Put
91333 +
91334 + @Description Puts a block of memory of the given base address back to the memory.
91335 +
91336 + It checks if there is a busy block with the
91337 + given base address. If not, it returns 0, that
91338 + means can't free a block. Otherwise, it gets parameters of
91339 + the busy block and after it updates lists of free blocks,
91340 + removes that busy block from the list by calling to MM_CutBusy
91341 + routine.
91342 + After that it calls to MM_AddFree routine to add a new free
91343 + block to the free lists.
91344 +
91345 + @Param[in] h_MM - Handle to the MM object.
91346 + @Param[in] base - Base address of the MM.
91347 +
91348 + @Return The size of bytes released, 0 if failed.
91349 +*//***************************************************************************/
91350 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
91351 +
91352 +/**************************************************************************//**
91353 + @Function MM_PutForce
91354 +
91355 + @Description Releases a block of memory of the required size from the required base address.
91356 +
91357 + First, it calls to MM_CutBusy routine
91358 + to cut a free block from the busy list. And then, calls to
91359 + MM_AddFree routine to add the free block to the free lists.
91360 +
91361 + @Param[in] h_MM - Handle to the MM object.
91362 + @Param[in] base - Base address of of a block to free.
91363 + @Param[in] size - Size of a block to free.
91364 +
91365 + @Return The number of bytes released, 0 on failure.
91366 +*//***************************************************************************/
91367 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
91368 +
91369 +/**************************************************************************//**
91370 + @Function MM_Add
91371 +
91372 + @Description Adds a new memory block for memory allocation.
91373 +
91374 + When a new memory block is initialized and added to the
91375 + memory list, it calls to MM_AddFree routine to add the
91376 + new free block to the free lists.
91377 +
91378 + @Param[in] h_MM - Handle to the MM object.
91379 + @Param[in] base - Base address of the memory block.
91380 + @Param[in] size - Size of the memory block.
91381 +
91382 + @Return E_OK on success, otherwise returns an error code.
91383 +*//***************************************************************************/
91384 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
91385 +
91386 +/**************************************************************************//**
91387 + @Function MM_Dump
91388 +
91389 + @Description Prints results of free and busy lists.
91390 +
91391 + @Param[in] h_MM - Handle to the MM object.
91392 +*//***************************************************************************/
91393 +void MM_Dump(t_Handle h_MM);
91394 +
91395 +/**************************************************************************//**
91396 + @Function MM_Free
91397 +
91398 + @Description Releases memory allocated for MM object.
91399 +
91400 + @Param[in] h_MM - Handle of the MM object.
91401 +*//***************************************************************************/
91402 +void MM_Free(t_Handle h_MM);
91403 +
91404 +/**************************************************************************//**
91405 + @Function MM_GetMemBlock
91406 +
91407 + @Description Returns base address of the memory block specified by the index.
91408 +
91409 + If index is 0, returns base address
91410 + of the first memory block, 1 - returns base address
91411 + of the second memory block, etc.
91412 + Note, those memory blocks are allocated by the
91413 + application before MM_Init or MM_Add and have to
91414 + be released by the application before or after invoking
91415 + the MM_Free routine.
91416 +
91417 + @Param[in] h_MM - Handle to the MM object.
91418 + @Param[in] index - Index of the memory block.
91419 +
91420 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
91421 +*//***************************************************************************/
91422 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
91423 +
91424 +/**************************************************************************//**
91425 + @Function MM_InRange
91426 +
91427 + @Description Checks if a specific address is in the memory range of the passed MM object.
91428 +
91429 + @Param[in] h_MM - Handle to the MM object.
91430 + @Param[in] addr - The address to be checked.
91431 +
91432 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
91433 +*//***************************************************************************/
91434 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
91435 +
91436 +/**************************************************************************//**
91437 + @Function MM_GetFreeMemSize
91438 +
91439 + @Description Returns the size (in bytes) of free memory.
91440 +
91441 + @Param[in] h_MM - Handle to the MM object.
91442 +
91443 + @Return Free memory size in bytes.
91444 +*//***************************************************************************/
91445 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
91446 +
91447 +
91448 +/** @} */ /* end of mm_grp group */
91449 +/** @} */ /* end of etc_id group */
91450 +
91451 +#endif /* __MM_EXT_H */
91452 --- /dev/null
91453 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
91454 @@ -0,0 +1,118 @@
91455 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91456 + * All rights reserved.
91457 + *
91458 + * Redistribution and use in source and binary forms, with or without
91459 + * modification, are permitted provided that the following conditions are met:
91460 + * * Redistributions of source code must retain the above copyright
91461 + * notice, this list of conditions and the following disclaimer.
91462 + * * Redistributions in binary form must reproduce the above copyright
91463 + * notice, this list of conditions and the following disclaimer in the
91464 + * documentation and/or other materials provided with the distribution.
91465 + * * Neither the name of Freescale Semiconductor nor the
91466 + * names of its contributors may be used to endorse or promote products
91467 + * derived from this software without specific prior written permission.
91468 + *
91469 + *
91470 + * ALTERNATIVELY, this software may be distributed under the terms of the
91471 + * GNU General Public License ("GPL") as published by the Free Software
91472 + * Foundation, either version 2 of that License or (at your option) any
91473 + * later version.
91474 + *
91475 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91476 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91477 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91478 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91479 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91480 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91481 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91482 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91483 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91484 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91485 + */
91486 +
91487 +
91488 +/**************************************************************************//**
91489 + @File sprint_ext.h
91490 +
91491 + @Description Debug routines (externals).
91492 +
91493 +*//***************************************************************************/
91494 +
91495 +#ifndef __SPRINT_EXT_H
91496 +#define __SPRINT_EXT_H
91497 +
91498 +
91499 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
91500 +#include <linux/kernel.h>
91501 +
91502 +#elif defined(NCSW_VXWORKS)
91503 +#include "private/stdioP.h"
91504 +
91505 +#else
91506 +#include <stdio.h>
91507 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
91508 +
91509 +#include "std_ext.h"
91510 +
91511 +
91512 +/**************************************************************************//**
91513 + @Group etc_id Utility Library Application Programming Interface
91514 +
91515 + @Description External routines.
91516 +
91517 + @{
91518 +*//***************************************************************************/
91519 +
91520 +/**************************************************************************//**
91521 + @Group sprint_id Sprint
91522 +
91523 + @Description Sprint & Sscan module functions,definitions and enums.
91524 +
91525 + @{
91526 +*//***************************************************************************/
91527 +
91528 +/**************************************************************************//**
91529 + @Function Sprint
91530 +
91531 + @Description Format a string and place it in a buffer.
91532 +
91533 + @Param[in] buff - The buffer to place the result into.
91534 + @Param[in] str - The format string to use.
91535 + @Param[in] ... - Arguments for the format string.
91536 +
91537 + @Return Number of bytes formatted.
91538 +*//***************************************************************************/
91539 +int Sprint(char *buff, const char *str, ...);
91540 +
91541 +/**************************************************************************//**
91542 + @Function Snprint
91543 +
91544 + @Description Format a string and place it in a buffer.
91545 +
91546 + @Param[in] buf - The buffer to place the result into.
91547 + @Param[in] size - The size of the buffer, including the trailing null space.
91548 + @Param[in] fmt - The format string to use.
91549 + @Param[in] ... - Arguments for the format string.
91550 +
91551 + @Return Number of bytes formatted.
91552 +*//***************************************************************************/
91553 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
91554 +
91555 +/**************************************************************************//**
91556 + @Function Sscan
91557 +
91558 + @Description Unformat a buffer into a list of arguments.
91559 +
91560 + @Param[in] buf - input buffer.
91561 + @Param[in] fmt - formatting of buffer.
91562 + @Param[out] ... - resulting arguments.
91563 +
91564 + @Return Number of bytes unformatted.
91565 +*//***************************************************************************/
91566 +int Sscan(const char * buf, const char * fmt, ...);
91567 +
91568 +/** @} */ /* end of sprint_id group */
91569 +/** @} */ /* end of etc_id group */
91570 +
91571 +
91572 +#endif /* __SPRINT_EXT_H */
91573 --- /dev/null
91574 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
91575 @@ -0,0 +1,37 @@
91576 +/*
91577 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91578 + *
91579 + * Redistribution and use in source and binary forms, with or without
91580 + * modification, are permitted provided that the following conditions are met:
91581 + * * Redistributions of source code must retain the above copyright
91582 + * notice, this list of conditions and the following disclaimer.
91583 + * * Redistributions in binary form must reproduce the above copyright
91584 + * notice, this list of conditions and the following disclaimer in the
91585 + * documentation and/or other materials provided with the distribution.
91586 + * * Neither the name of Freescale Semiconductor nor the
91587 + * names of its contributors may be used to endorse or promote products
91588 + * derived from this software without specific prior written permission.
91589 + *
91590 + *
91591 + * ALTERNATIVELY, this software may be distributed under the terms of the
91592 + * GNU General Public License ("GPL") as published by the Free Software
91593 + * Foundation, either version 2 of that License or (at your option) any
91594 + * later version.
91595 + *
91596 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91597 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91598 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91599 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91600 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91601 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91602 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91603 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91604 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91605 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91606 + */
91607 +
91608 +#ifndef FL_E500_MACROS_H
91609 +#define FL_E500_MACROS_H
91610 +
91611 +#endif /* FL_E500_MACROS_H */
91612 +
91613 --- /dev/null
91614 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
91615 @@ -0,0 +1,52 @@
91616 +/*
91617 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91618 + *
91619 + * Redistribution and use in source and binary forms, with or without
91620 + * modification, are permitted provided that the following conditions are met:
91621 + * * Redistributions of source code must retain the above copyright
91622 + * notice, this list of conditions and the following disclaimer.
91623 + * * Redistributions in binary form must reproduce the above copyright
91624 + * notice, this list of conditions and the following disclaimer in the
91625 + * documentation and/or other materials provided with the distribution.
91626 + * * Neither the name of Freescale Semiconductor nor the
91627 + * names of its contributors may be used to endorse or promote products
91628 + * derived from this software without specific prior written permission.
91629 + *
91630 + *
91631 + * ALTERNATIVELY, this software may be distributed under the terms of the
91632 + * GNU General Public License ("GPL") as published by the Free Software
91633 + * Foundation, either version 2 of that License or (at your option) any
91634 + * later version.
91635 + *
91636 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91637 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91638 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91639 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91640 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91641 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91642 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91643 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91644 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91645 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91646 + */
91647 +
91648 +#ifndef __GENERAL_H
91649 +#define __GENERAL_H
91650 +
91651 +#include "std_ext.h"
91652 +#if !defined(NCSW_LINUX)
91653 +#include "errno.h"
91654 +#endif
91655 +
91656 +
91657 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
91658 +
91659 +#ifndef CONFIG_FMAN_ARM
91660 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
91661 +#define ioread32be(addr) GET_UINT32(*addr)
91662 +#endif
91663 +
91664 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
91665 +
91666 +
91667 +#endif /* __GENERAL_H */
91668 --- /dev/null
91669 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
91670 @@ -0,0 +1,78 @@
91671 +/*
91672 + * Copyright 2008-2013 Freescale Semiconductor Inc.
91673 + *
91674 + * Redistribution and use in source and binary forms, with or without
91675 + * modification, are permitted provided that the following conditions are met:
91676 + * * Redistributions of source code must retain the above copyright
91677 + * notice, this list of conditions and the following disclaimer.
91678 + * * Redistributions in binary form must reproduce the above copyright
91679 + * notice, this list of conditions and the following disclaimer in the
91680 + * documentation and/or other materials provided with the distribution.
91681 + * * Neither the name of Freescale Semiconductor nor the
91682 + * names of its contributors may be used to endorse or promote products
91683 + * derived from this software without specific prior written permission.
91684 + *
91685 + *
91686 + * ALTERNATIVELY, this software may be distributed under the terms of the
91687 + * GNU General Public License ("GPL") as published by the Free Software
91688 + * Foundation, either version 2 of that License or (at your option) any
91689 + * later version.
91690 + *
91691 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91692 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91693 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91694 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91695 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91696 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91697 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91698 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91699 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91700 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91701 + */
91702 +
91703 +
91704 +#ifndef __FMAN_COMMON_H
91705 +#define __FMAN_COMMON_H
91706 +
91707 +/**************************************************************************//**
91708 + @Description NIA Description
91709 +*//***************************************************************************/
91710 +#define NIA_ORDER_RESTOR 0x00800000
91711 +#define NIA_ENG_FM_CTL 0x00000000
91712 +#define NIA_ENG_PRS 0x00440000
91713 +#define NIA_ENG_KG 0x00480000
91714 +#define NIA_ENG_PLCR 0x004C0000
91715 +#define NIA_ENG_BMI 0x00500000
91716 +#define NIA_ENG_QMI_ENQ 0x00540000
91717 +#define NIA_ENG_QMI_DEQ 0x00580000
91718 +#define NIA_ENG_MASK 0x007C0000
91719 +
91720 +#define NIA_FM_CTL_AC_CC 0x00000006
91721 +#define NIA_FM_CTL_AC_HC 0x0000000C
91722 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
91723 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
91724 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
91725 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
91726 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
91727 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
91728 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
91729 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
91730 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
91731 +
91732 +
91733 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
91734 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
91735 +#define NIA_BMI_AC_RELEASE 0x000000C0
91736 +#define NIA_BMI_AC_DISCARD 0x000000C1
91737 +#define NIA_BMI_AC_TX 0x00000274
91738 +#define NIA_BMI_AC_FETCH 0x00000208
91739 +#define NIA_BMI_AC_MASK 0x000003FF
91740 +
91741 +#define NIA_KG_DIRECT 0x00000100
91742 +#define NIA_KG_CC_EN 0x00000200
91743 +#define NIA_PLCR_ABSOLUTE 0x00008000
91744 +
91745 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
91746 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
91747 +
91748 +#endif /* __FMAN_COMMON_H */
91749 --- /dev/null
91750 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
91751 @@ -0,0 +1,273 @@
91752 +/*
91753 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91754 + *
91755 + * Redistribution and use in source and binary forms, with or without
91756 + * modification, are permitted provided that the following conditions are met:
91757 + * * Redistributions of source code must retain the above copyright
91758 + * notice, this list of conditions and the following disclaimer.
91759 + * * Redistributions in binary form must reproduce the above copyright
91760 + * notice, this list of conditions and the following disclaimer in the
91761 + * documentation and/or other materials provided with the distribution.
91762 + * * Neither the name of Freescale Semiconductor nor the
91763 + * names of its contributors may be used to endorse or promote products
91764 + * derived from this software without specific prior written permission.
91765 + *
91766 + *
91767 + * ALTERNATIVELY, this software may be distributed under the terms of the
91768 + * GNU General Public License ("GPL") as published by the Free Software
91769 + * Foundation, either version 2 of that License or (at your option) any
91770 + * later version.
91771 + *
91772 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91773 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91774 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91775 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91776 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91777 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91778 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91779 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91780 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91781 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91782 + */
91783 +
91784 +#ifndef __FSL_ENET_H
91785 +#define __FSL_ENET_H
91786 +
91787 +/**
91788 + @Description Ethernet MAC-PHY Interface
91789 +*/
91790 +
91791 +enum enet_interface {
91792 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
91793 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
91794 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
91795 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
91796 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
91797 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
91798 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
91799 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
91800 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
91801 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
91802 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
91803 +};
91804 +
91805 +/**
91806 + @Description Ethernet Speed (nominal data rate)
91807 +*/
91808 +enum enet_speed {
91809 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
91810 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
91811 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
91812 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
91813 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
91814 +};
91815 +
91816 +enum mac_type {
91817 + E_MAC_DTSEC,
91818 + E_MAC_TGEC,
91819 + E_MAC_MEMAC
91820 +};
91821 +
91822 +/**************************************************************************//**
91823 + @Description Enum for inter-module interrupts registration
91824 +*//***************************************************************************/
91825 +enum fman_event_modules {
91826 + E_FMAN_MOD_PRS, /**< Parser event */
91827 + E_FMAN_MOD_KG, /**< Keygen event */
91828 + E_FMAN_MOD_PLCR, /**< Policer event */
91829 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
91830 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
91831 + E_FMAN_MOD_TMR, /**< Timer event */
91832 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
91833 + E_FMAN_MOD_MACSEC,
91834 + E_FMAN_MOD_DUMMY_LAST
91835 +};
91836 +
91837 +/**************************************************************************//**
91838 + @Description Enum for interrupts types
91839 +*//***************************************************************************/
91840 +enum fman_intr_type {
91841 + E_FMAN_INTR_TYPE_ERR,
91842 + E_FMAN_INTR_TYPE_NORMAL
91843 +};
91844 +
91845 +/**************************************************************************//**
91846 + @Description enum for defining MAC types
91847 +*//***************************************************************************/
91848 +enum fman_mac_type {
91849 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
91850 + E_FMAN_MAC_1G /**< 1G MAC */
91851 +};
91852 +
91853 +enum fman_mac_exceptions {
91854 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
91855 + /**< 10GEC MDIO scan event interrupt */
91856 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
91857 + /**< 10GEC MDIO command completion interrupt */
91858 + E_FMAN_MAC_EX_10G_REM_FAULT,
91859 + /**< 10GEC, mEMAC Remote fault interrupt */
91860 + E_FMAN_MAC_EX_10G_LOC_FAULT,
91861 + /**< 10GEC, mEMAC Local fault interrupt */
91862 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
91863 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
91864 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
91865 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
91866 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
91867 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
91868 + E_FMAN_MAC_EX_10G_TX_ER,
91869 + /**< 10GEC Transmit frame error interrupt */
91870 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
91871 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
91872 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
91873 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
91874 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
91875 + /**< 10GEC Receive jabber frame interrupt */
91876 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
91877 + /**< 10GEC Receive oversized frame interrupt */
91878 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
91879 + /**< 10GEC Receive runt frame interrupt */
91880 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
91881 + /**< 10GEC Receive fragment frame interrupt */
91882 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
91883 + /**< 10GEC Receive payload length error interrupt */
91884 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
91885 + /**< 10GEC Receive CRC error interrupt */
91886 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
91887 + /**< 10GEC Receive alignment error interrupt */
91888 + E_FMAN_MAC_EX_1G_BAB_RX,
91889 + /**< dTSEC Babbling receive error */
91890 + E_FMAN_MAC_EX_1G_RX_CTL,
91891 + /**< dTSEC Receive control (pause frame) interrupt */
91892 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
91893 + /**< dTSEC Graceful transmit stop complete */
91894 + E_FMAN_MAC_EX_1G_BAB_TX,
91895 + /**< dTSEC Babbling transmit error */
91896 + E_FMAN_MAC_EX_1G_TX_CTL,
91897 + /**< dTSEC Transmit control (pause frame) interrupt */
91898 + E_FMAN_MAC_EX_1G_TX_ERR,
91899 + /**< dTSEC Transmit error */
91900 + E_FMAN_MAC_EX_1G_LATE_COL,
91901 + /**< dTSEC Late collision */
91902 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
91903 + /**< dTSEC Collision retry limit */
91904 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
91905 + /**< dTSEC Transmit FIFO underrun */
91906 + E_FMAN_MAC_EX_1G_MAG_PCKT,
91907 + /**< dTSEC Magic Packet detection */
91908 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
91909 + /**< dTSEC MII management read completion */
91910 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
91911 + /**< dTSEC MII management write completion */
91912 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
91913 + /**< dTSEC Graceful receive stop complete */
91914 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
91915 + /**< dTSEC Internal data error on transmit */
91916 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
91917 + /**< dTSEC Internal data error on receive */
91918 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
91919 + /**< dTSEC Time-Stamp Receive Error */
91920 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
91921 + /**< dTSEC MIB counter overflow */
91922 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
91923 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
91924 + not supported on T4240/B4860 rev1 chips */
91925 +};
91926 +
91927 +#define ENET_IF_SGMII_BASEX 0x80000000
91928 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
91929 + and phy or backplane;
91930 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
91931 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
91932 + 10Mbps, 100Mbps or 1000Mbps */
91933 +
91934 +enum enet_mode {
91935 + E_ENET_MODE_INVALID = 0,
91936 + /**< Invalid Ethernet mode */
91937 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
91938 + /**< 10 Mbps MII */
91939 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
91940 + /**< 100 Mbps MII */
91941 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
91942 + /**< 10 Mbps RMII */
91943 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
91944 + /**< 100 Mbps RMII */
91945 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
91946 + /**< 10 Mbps SMII */
91947 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
91948 + /**< 100 Mbps SMII */
91949 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
91950 + /**< 1000 Mbps GMII */
91951 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
91952 + /**< 10 Mbps RGMII */
91953 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
91954 + /**< 100 Mbps RGMII */
91955 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
91956 + /**< 1000 Mbps RGMII */
91957 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
91958 + /**< 1000 Mbps TBI */
91959 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
91960 + /**< 1000 Mbps RTBI */
91961 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
91962 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
91963 + SGMII phy according to Cisco SGMII specification */
91964 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
91965 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
91966 + SGMII phy according to Cisco SGMII specification */
91967 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
91968 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
91969 + SGMII phy according to Cisco SGMII specification */
91970 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
91971 + | E_ENET_SPEED_10),
91972 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
91973 + MAC and SGMII phy or backplane */
91974 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
91975 + | E_ENET_SPEED_100),
91976 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
91977 + MAC and SGMII phy or backplane */
91978 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
91979 + | E_ENET_SPEED_1000),
91980 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
91981 + MAC and SGMII phy or backplane */
91982 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
91983 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
91984 + QSGMII phy according to Cisco QSGMII specification */
91985 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
91986 + | E_ENET_SPEED_1000),
91987 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
91988 + MAC and QSGMII phy or backplane */
91989 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
91990 + /**< 10000 Mbps XGMII */
91991 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
91992 + /**< 10000 Mbps XFI */
91993 +};
91994 +
91995 +enum fmam_mac_statistics_level {
91996 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
91997 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
91998 + Optimized for performance */
91999 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
92000 + optimized for performance */
92001 +};
92002 +
92003 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
92004 + | (_speed))
92005 +
92006 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
92007 + ((mode) & 0x0FFF0000)
92008 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
92009 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
92010 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
92011 + ((uint64_t)(_enet_addr)[1] << 32) | \
92012 + ((uint64_t)(_enet_addr)[2] << 24) | \
92013 + ((uint64_t)(_enet_addr)[3] << 16) | \
92014 + ((uint64_t)(_enet_addr)[4] << 8) | \
92015 + ((uint64_t)(_enet_addr)[5]))
92016 +
92017 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
92018 + do { \
92019 + int i; \
92020 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
92021 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
92022 + } while (0)
92023 +
92024 +#endif /* __FSL_ENET_H */
92025 --- /dev/null
92026 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92027 @@ -0,0 +1,825 @@
92028 +/*
92029 + * Copyright 2013 Freescale Semiconductor Inc.
92030 + *
92031 + * Redistribution and use in source and binary forms, with or without
92032 + * modification, are permitted provided that the following conditions are met:
92033 + * * Redistributions of source code must retain the above copyright
92034 + * notice, this list of conditions and the following disclaimer.
92035 + * * Redistributions in binary form must reproduce the above copyright
92036 + * notice, this list of conditions and the following disclaimer in the
92037 + * documentation and/or other materials provided with the distribution.
92038 + * * Neither the name of Freescale Semiconductor nor the
92039 + * names of its contributors may be used to endorse or promote products
92040 + * derived from this software without specific prior written permission.
92041 + *
92042 + *
92043 + * ALTERNATIVELY, this software may be distributed under the terms of the
92044 + * GNU General Public License ("GPL") as published by the Free Software
92045 + * Foundation, either version 2 of that License or (at your option) any
92046 + * later version.
92047 + *
92048 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92049 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92050 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92051 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92052 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92053 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92054 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92055 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92056 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92057 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92058 + */
92059 +
92060 +#ifndef __FSL_FMAN_H
92061 +#define __FSL_FMAN_H
92062 +
92063 +#include "common/general.h"
92064 +
92065 +struct fman_ext_pool_params {
92066 + uint8_t id; /**< External buffer pool id */
92067 + uint16_t size; /**< External buffer pool buffer size */
92068 +};
92069 +
92070 +struct fman_ext_pools {
92071 + uint8_t num_pools_used; /**< Number of pools use by this port */
92072 + struct fman_ext_pool_params *ext_buf_pool;
92073 + /**< Parameters for each port */
92074 +};
92075 +
92076 +struct fman_backup_bm_pools {
92077 + uint8_t num_backup_pools; /**< Number of BM backup pools -
92078 + must be smaller than the total number
92079 + of pools defined for the specified
92080 + port.*/
92081 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
92082 + specifying which pools should be used
92083 + only as backup. Pool id's specified
92084 + here must be a subset of the pools
92085 + used by the specified port.*/
92086 +};
92087 +
92088 +/**************************************************************************//**
92089 + @Description A structure for defining BM pool depletion criteria
92090 +*//***************************************************************************/
92091 +struct fman_buf_pool_depletion {
92092 + bool buf_pool_depletion_enabled;
92093 + bool pools_grp_mode_enable; /**< select mode in which pause frames
92094 + will be sent after a number of pools
92095 + (all together!) are depleted */
92096 + uint8_t num_pools; /**< the number of depleted pools that
92097 + will invoke pause frames transmission.
92098 + */
92099 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
92100 + considered for depletion (Note - this
92101 + pool must be used by this port!). */
92102 + bool single_pool_mode_enable; /**< select mode in which pause frames
92103 + will be sent after a single-pool
92104 + is depleted; */
92105 + bool *pools_to_consider_for_single_mode;
92106 + /**< For each pool, TRUE if it should be
92107 + considered for depletion (Note - this
92108 + pool must be used by this port!) */
92109 + bool has_pfc_priorities;
92110 + bool *pfc_priorities_en; /**< This field is used by the MAC as
92111 + the Priority Enable Vector in the PFC
92112 + frame which is transmitted */
92113 +};
92114 +
92115 +/**************************************************************************//**
92116 + @Description Enum for defining port DMA swap mode
92117 +*//***************************************************************************/
92118 +enum fman_dma_swap_option {
92119 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
92120 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
92121 + in PowerPc Little Endian mode. */
92122 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
92123 + in Big Endian mode */
92124 +};
92125 +
92126 +/**************************************************************************//**
92127 + @Description Enum for defining port DMA cache attributes
92128 +*//***************************************************************************/
92129 +enum fman_dma_cache_option {
92130 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
92131 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
92132 +};
92133 +
92134 +typedef struct t_FmPrsResult fm_prs_result_t;
92135 +typedef enum e_EnetMode enet_mode_t;
92136 +typedef t_Handle handle_t;
92137 +
92138 +struct fman_revision_info {
92139 + uint8_t majorRev; /**< Major revision */
92140 + uint8_t minorRev; /**< Minor revision */
92141 +};
92142 +
92143 +/* sizes */
92144 +#define CAPWAP_FRAG_EXTRA_SPACE 32
92145 +#define OFFSET_UNITS 16
92146 +#define MAX_INT_OFFSET 240
92147 +#define MAX_IC_SIZE 256
92148 +#define MAX_EXT_OFFSET 496
92149 +#define MAX_EXT_BUFFER_OFFSET 511
92150 +
92151 +/**************************************************************************
92152 + @Description Memory Mapped Registers
92153 +***************************************************************************/
92154 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
92155 +
92156 +struct fman_fpm_regs {
92157 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
92158 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
92159 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
92160 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
92161 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
92162 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
92163 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
92164 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
92165 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
92166 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
92167 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
92168 + uint32_t res0050[4]; /**< res 0x50-0x5f */
92169 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
92170 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
92171 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
92172 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
92173 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
92174 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
92175 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
92176 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
92177 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
92178 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
92179 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
92180 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
92181 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
92182 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
92183 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
92184 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
92185 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
92186 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
92187 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
92188 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
92189 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
92190 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
92191 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
92192 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
92193 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
92194 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
92195 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
92196 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
92197 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
92198 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
92199 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
92200 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
92201 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
92202 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
92203 + uint32_t res0600[0x400 - 384];
92204 +};
92205 +
92206 +struct fman_bmi_regs {
92207 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
92208 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
92209 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
92210 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
92211 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
92212 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
92213 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
92214 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
92215 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
92216 + uint32_t res0060[12]; /**<0x60 - 0x8f */
92217 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
92218 + uint32_t res009c; /**< 0x9c */
92219 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
92220 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
92221 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
92222 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
92223 + uint32_t res0200; /**< 0x200 */
92224 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
92225 + uint32_t res0300; /**< 0x300 */
92226 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
92227 +};
92228 +
92229 +struct fman_qmi_regs {
92230 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
92231 + uint32_t res0004; /**< 0x04 */
92232 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
92233 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
92234 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
92235 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
92236 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
92237 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
92238 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
92239 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
92240 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
92241 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
92242 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
92243 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
92244 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
92245 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
92246 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
92247 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
92248 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
92249 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
92250 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
92251 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
92252 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
92253 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
92254 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
92255 + uint32_t res007c; /**< 0x7c */
92256 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
92257 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
92258 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
92259 + struct {
92260 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
92261 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
92262 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
92263 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
92264 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
92265 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
92266 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
92267 + uint32_t res001c; /**< 0x1c */
92268 + } dbg_traps[3]; /**< 0x90 - 0xef */
92269 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
92270 +};
92271 +
92272 +struct fman_dma_regs {
92273 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
92274 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
92275 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
92276 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
92277 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
92278 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
92279 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
92280 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
92281 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
92282 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
92283 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
92284 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
92285 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
92286 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
92287 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
92288 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
92289 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
92290 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
92291 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
92292 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
92293 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
92294 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
92295 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
92296 + uint32_t res005c; /**< 0x5c */
92297 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
92298 + uint32_t res00e0[0x400 - 56];
92299 +};
92300 +
92301 +struct fman_rg {
92302 + struct fman_fpm_regs *fpm_rg;
92303 + struct fman_dma_regs *dma_rg;
92304 + struct fman_bmi_regs *bmi_rg;
92305 + struct fman_qmi_regs *qmi_rg;
92306 +};
92307 +
92308 +enum fman_dma_cache_override {
92309 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
92310 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
92311 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
92312 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
92313 +};
92314 +
92315 +enum fman_dma_aid_mode {
92316 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
92317 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
92318 +};
92319 +
92320 +enum fman_dma_dbg_cnt_mode {
92321 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
92322 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
92323 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
92324 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
92325 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
92326 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
92327 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
92328 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
92329 +};
92330 +
92331 +enum fman_dma_emergency_level {
92332 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
92333 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
92334 +};
92335 +
92336 +enum fman_catastrophic_err {
92337 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
92338 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
92339 +};
92340 +
92341 +enum fman_dma_err {
92342 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
92343 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
92344 +};
92345 +
92346 +struct fman_cfg {
92347 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
92348 + bool en_counters;
92349 + uint8_t disp_limit_tsh;
92350 + uint8_t prs_disp_tsh;
92351 + uint8_t plcr_disp_tsh;
92352 + uint8_t kg_disp_tsh;
92353 + uint8_t bmi_disp_tsh;
92354 + uint8_t qmi_enq_disp_tsh;
92355 + uint8_t qmi_deq_disp_tsh;
92356 + uint8_t fm_ctl1_disp_tsh;
92357 + uint8_t fm_ctl2_disp_tsh;
92358 + enum fman_dma_cache_override dma_cache_override;
92359 + enum fman_dma_aid_mode dma_aid_mode;
92360 + bool dma_aid_override;
92361 + uint8_t dma_axi_dbg_num_of_beats;
92362 + uint8_t dma_cam_num_of_entries;
92363 + uint32_t dma_watchdog;
92364 + uint8_t dma_comm_qtsh_asrt_emer;
92365 + uint8_t dma_write_buf_tsh_asrt_emer;
92366 + uint8_t dma_read_buf_tsh_asrt_emer;
92367 + uint8_t dma_comm_qtsh_clr_emer;
92368 + uint8_t dma_write_buf_tsh_clr_emer;
92369 + uint8_t dma_read_buf_tsh_clr_emer;
92370 + uint32_t dma_sos_emergency;
92371 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
92372 + bool dma_stop_on_bus_error;
92373 + bool dma_en_emergency;
92374 + uint32_t dma_emergency_bus_select;
92375 + enum fman_dma_emergency_level dma_emergency_level;
92376 + bool dma_en_emergency_smoother;
92377 + uint32_t dma_emergency_switch_counter;
92378 + bool halt_on_external_activ;
92379 + bool halt_on_unrecov_ecc_err;
92380 + enum fman_catastrophic_err catastrophic_err;
92381 + enum fman_dma_err dma_err;
92382 + bool en_muram_test_mode;
92383 + bool en_iram_test_mode;
92384 + bool external_ecc_rams_enable;
92385 + uint16_t tnum_aging_period;
92386 + uint32_t exceptions;
92387 + uint16_t clk_freq;
92388 + bool pedantic_dma;
92389 + uint32_t cam_base_addr;
92390 + uint32_t fifo_base_addr;
92391 + uint32_t total_fifo_size;
92392 + uint8_t total_num_of_tasks;
92393 + bool qmi_deq_option_support;
92394 + uint32_t qmi_def_tnums_thresh;
92395 + bool fman_partition_array;
92396 + uint8_t num_of_fman_ctrl_evnt_regs;
92397 +};
92398 +
92399 +/**************************************************************************//**
92400 + @Description Exceptions
92401 +*//***************************************************************************/
92402 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
92403 +#define FMAN_EX_DMA_READ_ECC 0x40000000
92404 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
92405 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
92406 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
92407 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
92408 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
92409 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
92410 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
92411 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
92412 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
92413 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
92414 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
92415 +#define FMAN_EX_IRAM_ECC 0x00040000
92416 +#define FMAN_EX_NURAM_ECC 0x00020000
92417 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
92418 +
92419 +enum fman_exceptions {
92420 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
92421 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
92422 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
92423 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
92424 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
92425 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
92426 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
92427 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
92428 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
92429 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
92430 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
92431 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
92432 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
92433 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
92434 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
92435 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
92436 +};
92437 +
92438 +enum fman_counters {
92439 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
92440 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
92441 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
92442 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
92443 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
92444 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
92445 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
92446 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
92447 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
92448 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
92449 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
92450 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
92451 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
92452 +};
92453 +
92454 +#define FPM_PRT_FM_CTL1 0x00000001
92455 +#define FPM_PRT_FM_CTL2 0x00000002
92456 +
92457 +/**************************************************************************//**
92458 + @Description DMA definitions
92459 +*//***************************************************************************/
92460 +
92461 +/* masks */
92462 +#define DMA_MODE_AID_OR 0x20000000
92463 +#define DMA_MODE_SBER 0x10000000
92464 +#define DMA_MODE_BER 0x00200000
92465 +#define DMA_MODE_EB 0x00100000
92466 +#define DMA_MODE_ECC 0x00000020
92467 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
92468 +#define DMA_MODE_SECURE_PROT 0x00000800
92469 +#define DMA_MODE_EMER_READ 0x00080000
92470 +#define DMA_MODE_EMER_WRITE 0x00040000
92471 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
92472 +#define DMA_MODE_CEN_MASK 0x0000E000
92473 +#define DMA_MODE_DBG_MASK 0x00000380
92474 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
92475 +
92476 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
92477 +
92478 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
92479 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
92480 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
92481 +
92482 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
92483 +#define DMA_LOW_LIODN_MASK 0x00000FFF
92484 +
92485 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
92486 +#define DMA_STATUS_BUS_ERR 0x08000000
92487 +#define DMA_STATUS_READ_ECC 0x04000000
92488 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
92489 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
92490 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
92491 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
92492 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
92493 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
92494 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
92495 +
92496 +#define FM_LIODN_BASE_MASK 0x00000FFF
92497 +
92498 +/* shifts */
92499 +#define DMA_MODE_CACHE_OR_SHIFT 30
92500 +#define DMA_MODE_BUS_PRI_SHIFT 16
92501 +#define DMA_MODE_AXI_DBG_SHIFT 24
92502 +#define DMA_MODE_CEN_SHIFT 13
92503 +#define DMA_MODE_BUS_PROT_SHIFT 10
92504 +#define DMA_MODE_DBG_SHIFT 7
92505 +#define DMA_MODE_EMER_LVL_SHIFT 6
92506 +#define DMA_MODE_AID_MODE_SHIFT 4
92507 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
92508 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
92509 +
92510 +#define DMA_THRESH_COMMQ_SHIFT 24
92511 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
92512 +
92513 +#define DMA_LIODN_SHIFT 16
92514 +
92515 +#define DMA_TRANSFER_PORTID_SHIFT 24
92516 +#define DMA_TRANSFER_TNUM_SHIFT 16
92517 +
92518 +/* sizes */
92519 +#define DMA_MAX_WATCHDOG 0xffffffff
92520 +
92521 +/* others */
92522 +#define DMA_CAM_SIZEOF_ENTRY 0x40
92523 +#define DMA_CAM_ALIGN 0x1000
92524 +#define DMA_CAM_UNITS 8
92525 +
92526 +/**************************************************************************//**
92527 + @Description General defines
92528 +*//***************************************************************************/
92529 +
92530 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
92531 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
92532 +
92533 +/**************************************************************************//**
92534 + @Description FPM defines
92535 +*//***************************************************************************/
92536 +
92537 +/* masks */
92538 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
92539 +#define FPM_EV_MASK_STALL 0x40000000
92540 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
92541 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
92542 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
92543 +#define FPM_EV_MASK_STALL_EN 0x00004000
92544 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
92545 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
92546 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
92547 +
92548 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
92549 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
92550 +#define FPM_RAM_MURAM_ECC 0x00008000
92551 +#define FPM_RAM_IRAM_ECC 0x00004000
92552 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
92553 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
92554 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
92555 +
92556 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
92557 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
92558 +
92559 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
92560 +#define FPM_REV1_MINOR_MASK 0x000000FF
92561 +
92562 +#define FPM_REV2_INTEG_MASK 0x00FF0000
92563 +#define FPM_REV2_ERR_MASK 0x0000FF00
92564 +#define FPM_REV2_CFG_MASK 0x000000FF
92565 +
92566 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
92567 +#define FPM_TS_CTL_EN 0x80000000
92568 +
92569 +#define FPM_PRC_REALSE_STALLED 0x00800000
92570 +
92571 +#define FPM_PS_STALLED 0x00800000
92572 +#define FPM_PS_FM_CTL1_SEL 0x80000000
92573 +#define FPM_PS_FM_CTL2_SEL 0x40000000
92574 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
92575 +
92576 +#define FPM_RSTC_FM_RESET 0x80000000
92577 +#define FPM_RSTC_10G0_RESET 0x04000000
92578 +#define FPM_RSTC_1G0_RESET 0x40000000
92579 +#define FPM_RSTC_1G1_RESET 0x20000000
92580 +#define FPM_RSTC_1G2_RESET 0x10000000
92581 +#define FPM_RSTC_1G3_RESET 0x08000000
92582 +#define FPM_RSTC_1G4_RESET 0x02000000
92583 +
92584 +
92585 +#define FPM_DISP_LIMIT_MASK 0x1F000000
92586 +#define FPM_THR1_PRS_MASK 0xFF000000
92587 +#define FPM_THR1_KG_MASK 0x00FF0000
92588 +#define FPM_THR1_PLCR_MASK 0x0000FF00
92589 +#define FPM_THR1_BMI_MASK 0x000000FF
92590 +
92591 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
92592 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
92593 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
92594 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
92595 +
92596 +/* shifts */
92597 +#define FPM_DISP_LIMIT_SHIFT 24
92598 +
92599 +#define FPM_THR1_PRS_SHIFT 24
92600 +#define FPM_THR1_KG_SHIFT 16
92601 +#define FPM_THR1_PLCR_SHIFT 8
92602 +#define FPM_THR1_BMI_SHIFT 0
92603 +
92604 +#define FPM_THR2_QMI_ENQ_SHIFT 24
92605 +#define FPM_THR2_QMI_DEQ_SHIFT 0
92606 +#define FPM_THR2_FM_CTL1_SHIFT 16
92607 +#define FPM_THR2_FM_CTL2_SHIFT 8
92608 +
92609 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
92610 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
92611 +
92612 +#define FPM_REV1_MAJOR_SHIFT 8
92613 +#define FPM_REV1_MINOR_SHIFT 0
92614 +
92615 +#define FPM_REV2_INTEG_SHIFT 16
92616 +#define FPM_REV2_ERR_SHIFT 8
92617 +#define FPM_REV2_CFG_SHIFT 0
92618 +
92619 +#define FPM_TS_INT_SHIFT 16
92620 +
92621 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
92622 +
92623 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
92624 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
92625 +
92626 +#define FPM_DISP_LIMIT_SHIFT 24
92627 +
92628 +/* Interrupts defines */
92629 +#define FPM_EVENT_FM_CTL_0 0x00008000
92630 +#define FPM_EVENT_FM_CTL 0x0000FF00
92631 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
92632 +
92633 +/* others */
92634 +#define FPM_MAX_DISP_LIMIT 31
92635 +#define FPM_RSTC_FM_RESET 0x80000000
92636 +#define FPM_RSTC_1G0_RESET 0x40000000
92637 +#define FPM_RSTC_1G1_RESET 0x20000000
92638 +#define FPM_RSTC_1G2_RESET 0x10000000
92639 +#define FPM_RSTC_1G3_RESET 0x08000000
92640 +#define FPM_RSTC_10G0_RESET 0x04000000
92641 +#define FPM_RSTC_1G4_RESET 0x02000000
92642 +#define FPM_RSTC_1G5_RESET 0x01000000
92643 +#define FPM_RSTC_1G6_RESET 0x00800000
92644 +#define FPM_RSTC_1G7_RESET 0x00400000
92645 +#define FPM_RSTC_10G1_RESET 0x00200000
92646 +/**************************************************************************//**
92647 + @Description BMI defines
92648 +*//***************************************************************************/
92649 +/* masks */
92650 +#define BMI_INIT_START 0x80000000
92651 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
92652 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
92653 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
92654 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
92655 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
92656 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
92657 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
92658 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
92659 +#define BMI_FIFO_SIZE_MASK 0x000003FF
92660 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
92661 +#define BMI_CFG2_DMAS_MASK 0x0000003F
92662 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
92663 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
92664 +
92665 +/* shifts */
92666 +#define BMI_CFG2_TASKS_SHIFT 16
92667 +#define BMI_CFG2_DMAS_SHIFT 0
92668 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
92669 +#define BMI_FIFO_SIZE_SHIFT 0
92670 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
92671 +#define BMI_NUM_OF_TASKS_SHIFT 24
92672 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
92673 +#define BMI_NUM_OF_DMAS_SHIFT 8
92674 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
92675 +
92676 +/* others */
92677 +#define BMI_FIFO_ALIGN 0x100
92678 +#define FMAN_BMI_FIFO_UNITS 0x100
92679 +
92680 +
92681 +/**************************************************************************//**
92682 + @Description QMI defines
92683 +*//***************************************************************************/
92684 +/* masks */
92685 +#define QMI_CFG_ENQ_EN 0x80000000
92686 +#define QMI_CFG_DEQ_EN 0x40000000
92687 +#define QMI_CFG_EN_COUNTERS 0x10000000
92688 +#define QMI_CFG_SOFT_RESET 0x01000000
92689 +#define QMI_CFG_DEQ_MASK 0x0000003F
92690 +#define QMI_CFG_ENQ_MASK 0x00003F00
92691 +
92692 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
92693 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
92694 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
92695 +
92696 +/* shifts */
92697 +#define QMI_CFG_ENQ_SHIFT 8
92698 +#define QMI_TAPC_TAP 22
92699 +
92700 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
92701 +
92702 +/**************************************************************************//**
92703 + @Description IRAM defines
92704 +*//***************************************************************************/
92705 +/* masks */
92706 +#define IRAM_IADD_AIE 0x80000000
92707 +#define IRAM_READY 0x80000000
92708 +
92709 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
92710 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
92711 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
92712 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
92713 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
92714 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
92715 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
92716 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
92717 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
92718 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
92719 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
92720 + uint8_t event_reg_id);
92721 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
92722 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
92723 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92724 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
92725 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
92726 + uint8_t port_id);
92727 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92728 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
92729 + uint8_t port_id);
92730 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
92731 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
92732 + uint8_t port_id);
92733 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
92734 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
92735 + uint8_t reg_id);
92736 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
92737 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
92738 + uint8_t *minor);
92739 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
92740 + enum fman_counters reg_name);
92741 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
92742 +
92743 +
92744 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
92745 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
92746 + uint32_t enable_events);
92747 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
92748 + uint8_t port_id,
92749 + uint8_t num_fman_ctrls,
92750 + uint32_t or_fman_ctrl);
92751 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
92752 + uint8_t port_id,
92753 + bool independent_mode,
92754 + bool is_rx_port);
92755 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
92756 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
92757 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
92758 + uint8_t port_id,
92759 + uint16_t liodn_base,
92760 + uint16_t liodn_offset);
92761 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
92762 + uint8_t port_id,
92763 + uint32_t size_of_fifo,
92764 + uint32_t extra_size_of_fifo);
92765 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
92766 + uint8_t port_id,
92767 + uint8_t num_of_tasks,
92768 + uint8_t num_of_extra_tasks);
92769 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
92770 + uint8_t port_id,
92771 + uint8_t num_of_open_dmas,
92772 + uint8_t num_of_extra_open_dmas,
92773 + uint8_t total_num_of_dmas);
92774 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
92775 +int fman_set_exception(struct fman_rg *fman_rg,
92776 + enum fman_exceptions exception,
92777 + bool enable);
92778 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
92779 + bool enable);
92780 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
92781 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
92782 + uint32_t congestion_group_id,
92783 + uint8_t piority_bit_map,
92784 + uint32_t reg_num);
92785 +
92786 +
92787 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
92788 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
92789 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
92790 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
92791 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
92792 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
92793 +void fman_free_resources(struct fman_rg *fman_rg);
92794 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
92795 +void fman_reset(struct fman_fpm_regs *fpm_rg);
92796 +void fman_resume(struct fman_fpm_regs *fpm_rg);
92797 +
92798 +
92799 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
92800 + uint8_t count1ubit,
92801 + uint16_t fm_clk_freq);
92802 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
92803 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
92804 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
92805 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
92806 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
92807 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
92808 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
92809 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
92810 +int fman_modify_counter(struct fman_rg *fman_rg,
92811 + enum fman_counters reg_name,
92812 + uint32_t val);
92813 +void fman_force_intr(struct fman_rg *fman_rg,
92814 + enum fman_exceptions exception);
92815 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
92816 + uint8_t port_id,
92817 + uint8_t base_storage_profile,
92818 + uint8_t log2_num_of_profiles);
92819 +
92820 +/**************************************************************************//**
92821 + @Description default values
92822 +*//***************************************************************************/
92823 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
92824 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
92825 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
92826 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
92827 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
92828 +#define DEFAULT_AID_OVERRIDE FALSE
92829 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
92830 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
92831 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
92832 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
92833 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
92834 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
92835 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
92836 +#define DEFAULT_DMA_SOS_EMERGENCY 0
92837 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
92838 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
92839 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
92840 +#define DEFAULT_DISP_LIMIT 0
92841 +#define DEFAULT_PRS_DISP_TH 16
92842 +#define DEFAULT_PLCR_DISP_TH 16
92843 +#define DEFAULT_KG_DISP_TH 16
92844 +#define DEFAULT_BMI_DISP_TH 16
92845 +#define DEFAULT_QMI_ENQ_DISP_TH 16
92846 +#define DEFAULT_QMI_DEQ_DISP_TH 16
92847 +#define DEFAULT_FM_CTL1_DISP_TH 16
92848 +#define DEFAULT_FM_CTL2_DISP_TH 16
92849 +#define DEFAULT_TNUM_AGING_PERIOD 4
92850 +
92851 +
92852 +#endif /* __FSL_FMAN_H */
92853 --- /dev/null
92854 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
92855 @@ -0,0 +1,1096 @@
92856 +/*
92857 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92858 + *
92859 + * Redistribution and use in source and binary forms, with or without
92860 + * modification, are permitted provided that the following conditions are met:
92861 + * * Redistributions of source code must retain the above copyright
92862 + * notice, this list of conditions and the following disclaimer.
92863 + * * Redistributions in binary form must reproduce the above copyright
92864 + * notice, this list of conditions and the following disclaimer in the
92865 + * documentation and/or other materials provided with the distribution.
92866 + * * Neither the name of Freescale Semiconductor nor the
92867 + * names of its contributors may be used to endorse or promote products
92868 + * derived from this software without specific prior written permission.
92869 + *
92870 + *
92871 + * ALTERNATIVELY, this software may be distributed under the terms of the
92872 + * GNU General Public License ("GPL") as published by the Free Software
92873 + * Foundation, either version 2 of that License or (at your option) any
92874 + * later version.
92875 + *
92876 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92877 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92878 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92879 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92880 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92881 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92882 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92883 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92884 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92885 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92886 + */
92887 +
92888 +#ifndef __FSL_FMAN_DTSEC_H
92889 +#define __FSL_FMAN_DTSEC_H
92890 +
92891 +#include "common/general.h"
92892 +#include "fsl_enet.h"
92893 +
92894 +/**
92895 + * DOC: dTSEC Init sequence
92896 + *
92897 + * To prepare dTSEC block for transfer use the following call sequence:
92898 + *
92899 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
92900 + * use is to obtain the default dTSEC configuration parameters.
92901 + *
92902 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
92903 + * to customize the dTSEC behavior.
92904 + *
92905 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
92906 + * dTSEC is initialized while both Tx and Rx are disabled.
92907 + *
92908 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
92909 + * This is used by dTSEC to match against received packets.
92910 + *
92911 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
92912 + * after the PHY establishes the link.
92913 + *
92914 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
92915 + * reception.
92916 + */
92917 +
92918 +/**
92919 + * DOC: dTSEC Graceful stop
92920 + *
92921 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
92922 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
92923 + * but return before this stop is complete. To query for graceful stop
92924 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
92925 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
92926 + * enable graceful stop interrupts.
92927 + *
92928 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
92929 + * fman_dtsec_start_rx().
92930 + */
92931 +
92932 +/**
92933 + * DOC: dTSEC interrupt handling
92934 + *
92935 + * This code does not provide an interrupt handler for dTSEC. Instead this
92936 + * handler should be implemented and registered to the operating system by the
92937 + * caller. Some primitives for accessing the event status and mask registers
92938 + * are provided.
92939 + *
92940 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
92941 + */
92942 +
92943 +/**
92944 + * DOC: dTSEC Events
92945 + *
92946 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
92947 + * event register at any time to check for pending interrupts. If an event
92948 + * occurs and its corresponding enable bit is set in the interrupt mask
92949 + * register, the event also causes a hardware interrupt at the PIC.
92950 + *
92951 + * To poll for event status use the fman_dtsec_get_event() function.
92952 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
92953 + * fman_dtsec_disable_interrupt() functions.
92954 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
92955 + * serviced event bit.
92956 + *
92957 + * The following events may be signaled by dTSEC hardware:
92958 + *
92959 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
92960 + * a frame was received with length in excess of the MAC's maximum frame length
92961 + * register.
92962 + *
92963 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
92964 + * control frame was received while Rx pause frame handling is enabled.
92965 + * Also see fman_dtsec_handle_rx_pause().
92966 + *
92967 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
92968 + * counters has exceeded the size of its register.
92969 + *
92970 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
92971 + * complete. The transmitter is in a stopped state, in which only pause frames
92972 + * can be transmitted.
92973 + * Also see fman_dtsec_stop_tx().
92974 + *
92975 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
92976 + * has exceeded the value in the MAC's Maximum Frame Length register.
92977 + *
92978 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
92979 + * indicates that a control frame was transmitted.
92980 + *
92981 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
92982 + * occurred on the transmitted channel. This bit is set whenever any transmit
92983 + * error occurs which causes the dTSEC to discard all or part of a frame
92984 + * (LC, CRL, XFUN).
92985 + *
92986 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
92987 + * occurred beyond the collision window (slot time) in half-duplex mode.
92988 + * The frame is truncated with a bad CRC and the remainder of the frame
92989 + * is discarded.
92990 + *
92991 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
92992 + * of successive transmission collisions has exceeded the MAC's half-duplex
92993 + * register's retransmission maximum count. The frame is discarded without
92994 + * being transmitted and transmission of the next frame commences. This only
92995 + * occurs while in half-duplex mode.
92996 + * The number of retransmit attempts can be set in
92997 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
92998 + *
92999 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
93000 + * transmit FIFO became empty before the complete frame was transmitted.
93001 + * The frame is truncated with a bad CRC and the remainder of the frame is
93002 + * discarded.
93003 + *
93004 + * %DTSEC_IEVENT_MAG - TBD
93005 + *
93006 + * %DTSEC_IEVENT_MMRD - MII management read completion.
93007 + *
93008 + * %DTSEC_IEVENT_MMWR - MII management write completion.
93009 + *
93010 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
93011 + * know if the system has completed the stop and it is safe to write to receive
93012 + * registers (status, control or configuration registers) that are used by the
93013 + * system during normal operation.
93014 + *
93015 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
93016 + * that the dTSEC has detected a parity error on its stored transmit data, which
93017 + * is likely to compromise the validity of recently transferred frames.
93018 + *
93019 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
93020 + * the dTSEC has detected a parity error on its stored receive data, which is
93021 + * likely to compromise the validity of recently transferred frames.
93022 + */
93023 +/* Interrupt Mask Register (IMASK) */
93024 +#define DTSEC_IMASK_BREN 0x80000000
93025 +#define DTSEC_IMASK_RXCEN 0x40000000
93026 +#define DTSEC_IMASK_MSROEN 0x04000000
93027 +#define DTSEC_IMASK_GTSCEN 0x02000000
93028 +#define DTSEC_IMASK_BTEN 0x01000000
93029 +#define DTSEC_IMASK_TXCEN 0x00800000
93030 +#define DTSEC_IMASK_TXEEN 0x00400000
93031 +#define DTSEC_IMASK_LCEN 0x00040000
93032 +#define DTSEC_IMASK_CRLEN 0x00020000
93033 +#define DTSEC_IMASK_XFUNEN 0x00010000
93034 +#define DTSEC_IMASK_ABRTEN 0x00008000
93035 +#define DTSEC_IMASK_IFERREN 0x00004000
93036 +#define DTSEC_IMASK_MAGEN 0x00000800
93037 +#define DTSEC_IMASK_MMRDEN 0x00000400
93038 +#define DTSEC_IMASK_MMWREN 0x00000200
93039 +#define DTSEC_IMASK_GRSCEN 0x00000100
93040 +#define DTSEC_IMASK_TDPEEN 0x00000002
93041 +#define DTSEC_IMASK_RDPEEN 0x00000001
93042 +
93043 +#define DTSEC_EVENTS_MASK \
93044 + ((uint32_t)(DTSEC_IMASK_BREN | \
93045 + DTSEC_IMASK_RXCEN | \
93046 + DTSEC_IMASK_BTEN | \
93047 + DTSEC_IMASK_TXCEN | \
93048 + DTSEC_IMASK_TXEEN | \
93049 + DTSEC_IMASK_ABRTEN | \
93050 + DTSEC_IMASK_LCEN | \
93051 + DTSEC_IMASK_CRLEN | \
93052 + DTSEC_IMASK_XFUNEN | \
93053 + DTSEC_IMASK_IFERREN | \
93054 + DTSEC_IMASK_MAGEN | \
93055 + DTSEC_IMASK_TDPEEN | \
93056 + DTSEC_IMASK_RDPEEN))
93057 +
93058 +/* dtsec timestamp event bits */
93059 +#define TMR_PEMASK_TSREEN 0x00010000
93060 +#define TMR_PEVENT_TSRE 0x00010000
93061 +
93062 +/* Group address bit indication */
93063 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
93064 +/* size in bytes of L2 address */
93065 +#define MAC_ADDRLEN 6
93066 +
93067 +#define DEFAULT_HALFDUP_ON FALSE
93068 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
93069 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
93070 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
93071 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
93072 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
93073 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
93074 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
93075 +#define DEFAULT_RX_DROP_BCAST FALSE
93076 +#define DEFAULT_RX_SHORT_FRM TRUE
93077 +#define DEFAULT_RX_LEN_CHECK FALSE
93078 +#define DEFAULT_TX_PAD_CRC TRUE
93079 +#define DEFAULT_TX_CRC FALSE
93080 +#define DEFAULT_RX_CTRL_ACC FALSE
93081 +#define DEFAULT_TX_PAUSE_TIME 0xf000
93082 +#define DEFAULT_TBIPA 5
93083 +#define DEFAULT_RX_PREPEND 0
93084 +#define DEFAULT_PTP_TSU_EN TRUE
93085 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
93086 +#define DEFAULT_PREAMBLE_LEN 7
93087 +#define DEFAULT_RX_PREAMBLE FALSE
93088 +#define DEFAULT_TX_PREAMBLE FALSE
93089 +#define DEFAULT_LOOPBACK FALSE
93090 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
93091 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
93092 +#define DEFAULT_RX_FLOW TRUE
93093 +#define DEFAULT_TX_FLOW TRUE
93094 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
93095 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
93096 +#define DEFAULT_RX_PROMISC FALSE
93097 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
93098 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
93099 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
93100 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
93101 +#define DEFAULT_MAXIMUM_FRAME 0x600
93102 +#define DEFAULT_TBI_PHY_ADDR 5
93103 +#define DEFAULT_WAKE_ON_LAN FALSE
93104 +
93105 +/* register related defines (bits, field offsets..) */
93106 +#define DTSEC_ID1_ID 0xffff0000
93107 +#define DTSEC_ID1_REV_MJ 0x0000FF00
93108 +#define DTSEC_ID1_REV_MN 0x000000ff
93109 +
93110 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
93111 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
93112 +
93113 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
93114 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
93115 +#define DTSEC_ECNTRL_STEN 0x00001000
93116 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
93117 +#define DTSEC_ECNTRL_GMIIM 0x00000040
93118 +#define DTSEC_ECNTRL_TBIM 0x00000020
93119 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
93120 +#define DTSEC_ECNTRL_RPM 0x00000010
93121 +#define DTSEC_ECNTRL_R100M 0x00000008
93122 +#define DTSEC_ECNTRL_RMM 0x00000004
93123 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
93124 +
93125 +#define DTSEC_TCTRL_THDF 0x00000800
93126 +#define DTSEC_TCTRL_TTSE 0x00000040
93127 +#define DTSEC_TCTRL_GTS 0x00000020
93128 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
93129 +
93130 +/* PTV offsets */
93131 +#define PTV_PTE_OFST 16
93132 +
93133 +#define RCTRL_CFA 0x00008000
93134 +#define RCTRL_GHTX 0x00000400
93135 +#define RCTRL_RTSE 0x00000040
93136 +#define RCTRL_GRS 0x00000020
93137 +#define RCTRL_BC_REJ 0x00000010
93138 +#define RCTRL_MPROM 0x00000008
93139 +#define RCTRL_RSF 0x00000004
93140 +#define RCTRL_UPROM 0x00000001
93141 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
93142 +
93143 +#define TMR_CTL_ESFDP 0x00000800
93144 +#define TMR_CTL_ESFDE 0x00000400
93145 +
93146 +#define MACCFG1_SOFT_RESET 0x80000000
93147 +#define MACCFG1_LOOPBACK 0x00000100
93148 +#define MACCFG1_RX_FLOW 0x00000020
93149 +#define MACCFG1_TX_FLOW 0x00000010
93150 +#define MACCFG1_TX_EN 0x00000001
93151 +#define MACCFG1_RX_EN 0x00000004
93152 +#define MACCFG1_RESET_RxMC 0x00080000
93153 +#define MACCFG1_RESET_TxMC 0x00040000
93154 +#define MACCFG1_RESET_RxFUN 0x00020000
93155 +#define MACCFG1_RESET_TxFUN 0x00010000
93156 +
93157 +#define MACCFG2_NIBBLE_MODE 0x00000100
93158 +#define MACCFG2_BYTE_MODE 0x00000200
93159 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
93160 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
93161 +#define MACCFG2_LENGTH_CHECK 0x00000010
93162 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
93163 +#define MACCFG2_PAD_CRC_EN 0x00000004
93164 +#define MACCFG2_CRC_EN 0x00000002
93165 +#define MACCFG2_FULL_DUPLEX 0x00000001
93166 +
93167 +#define PREAMBLE_LENGTH_SHIFT 12
93168 +
93169 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
93170 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
93171 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
93172 +
93173 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
93174 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
93175 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
93176 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
93177 +
93178 +#define HAFDUP_ALT_BEB 0x00080000
93179 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
93180 +#define HAFDUP_NO_BACKOFF 0x00020000
93181 +#define HAFDUP_EXCESS_DEFER 0x00010000
93182 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
93183 +
93184 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
93185 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
93186 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
93187 +
93188 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
93189 +
93190 +/* CAR1/2 bits */
93191 +#define DTSEC_CAR1_TR64 0x80000000
93192 +#define DTSEC_CAR1_TR127 0x40000000
93193 +#define DTSEC_CAR1_TR255 0x20000000
93194 +#define DTSEC_CAR1_TR511 0x10000000
93195 +#define DTSEC_CAR1_TRK1 0x08000000
93196 +#define DTSEC_CAR1_TRMAX 0x04000000
93197 +#define DTSEC_CAR1_TRMGV 0x02000000
93198 +
93199 +#define DTSEC_CAR1_RBYT 0x00010000
93200 +#define DTSEC_CAR1_RPKT 0x00008000
93201 +#define DTSEC_CAR1_RFCS 0x00004000
93202 +#define DTSEC_CAR1_RMCA 0x00002000
93203 +#define DTSEC_CAR1_RBCA 0x00001000
93204 +#define DTSEC_CAR1_RXCF 0x00000800
93205 +#define DTSEC_CAR1_RXPF 0x00000400
93206 +#define DTSEC_CAR1_RXUO 0x00000200
93207 +#define DTSEC_CAR1_RALN 0x00000100
93208 +#define DTSEC_CAR1_RFLR 0x00000080
93209 +#define DTSEC_CAR1_RCDE 0x00000040
93210 +#define DTSEC_CAR1_RCSE 0x00000020
93211 +#define DTSEC_CAR1_RUND 0x00000010
93212 +#define DTSEC_CAR1_ROVR 0x00000008
93213 +#define DTSEC_CAR1_RFRG 0x00000004
93214 +#define DTSEC_CAR1_RJBR 0x00000002
93215 +#define DTSEC_CAR1_RDRP 0x00000001
93216 +
93217 +#define DTSEC_CAR2_TJBR 0x00080000
93218 +#define DTSEC_CAR2_TFCS 0x00040000
93219 +#define DTSEC_CAR2_TXCF 0x00020000
93220 +#define DTSEC_CAR2_TOVR 0x00010000
93221 +#define DTSEC_CAR2_TUND 0x00008000
93222 +#define DTSEC_CAR2_TFRG 0x00004000
93223 +#define DTSEC_CAR2_TBYT 0x00002000
93224 +#define DTSEC_CAR2_TPKT 0x00001000
93225 +#define DTSEC_CAR2_TMCA 0x00000800
93226 +#define DTSEC_CAR2_TBCA 0x00000400
93227 +#define DTSEC_CAR2_TXPF 0x00000200
93228 +#define DTSEC_CAR2_TDFR 0x00000100
93229 +#define DTSEC_CAR2_TEDF 0x00000080
93230 +#define DTSEC_CAR2_TSCL 0x00000040
93231 +#define DTSEC_CAR2_TMCL 0x00000020
93232 +#define DTSEC_CAR2_TLCL 0x00000010
93233 +#define DTSEC_CAR2_TXCL 0x00000008
93234 +#define DTSEC_CAR2_TNCL 0x00000004
93235 +#define DTSEC_CAR2_TDRP 0x00000001
93236 +
93237 +#define CAM1_ERRORS_ONLY \
93238 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
93239 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
93240 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93241 + | DTSEC_CAR1_RDRP)
93242 +
93243 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
93244 +
93245 +/*
93246 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
93247 + * (or Ethernet) statistics.
93248 + */
93249 +#define CAM1_MIB_GRP_1 \
93250 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
93251 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
93252 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93253 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
93254 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
93255 +
93256 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
93257 +
93258 +/* memory map */
93259 +
93260 +struct dtsec_regs {
93261 + /* dTSEC General Control and Status Registers */
93262 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
93263 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
93264 + uint32_t ievent; /* 0x008 Interrupt event register */
93265 + uint32_t imask; /* 0x00C Interrupt mask register */
93266 + uint32_t reserved0010[1];
93267 + uint32_t ecntrl; /* 0x014 E control register */
93268 + uint32_t ptv; /* 0x018 Pause time value register */
93269 + uint32_t tbipa; /* 0x01C TBI PHY address register */
93270 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
93271 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
93272 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
93273 + uint32_t reserved002c[5];
93274 + uint32_t tctrl; /* 0x040 Transmit control register */
93275 + uint32_t reserved0044[3];
93276 + uint32_t rctrl; /* 0x050 Receive control register */
93277 + uint32_t reserved0054[11];
93278 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
93279 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
93280 + uint32_t reserved00c0[16];
93281 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
93282 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
93283 + uint32_t ipgifg; /* 0x108 IPG/IFG */
93284 + uint32_t hafdup; /* 0x10C Half-duplex */
93285 + uint32_t maxfrm; /* 0x110 Maximum frame */
93286 + uint32_t reserved0114[10];
93287 + uint32_t ifstat; /* 0x13C Interface status */
93288 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
93289 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
93290 + struct {
93291 + uint32_t exact_match1; /* octets 1-4 */
93292 + uint32_t exact_match2; /* octets 5-6 */
93293 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
93294 + uint32_t reserved01c0[16];
93295 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
93296 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
93297 + * counter */
93298 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
93299 + * counter */
93300 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
93301 + * counter */
93302 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
93303 + * counter */
93304 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
93305 + * counter */
93306 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
93307 + * VLAN frame count */
93308 + uint32_t rbyt; /* 0x21C receive byte counter */
93309 + uint32_t rpkt; /* 0x220 receive packet counter */
93310 + uint32_t rfcs; /* 0x224 receive FCS error counter */
93311 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
93312 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
93313 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
93314 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
93315 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
93316 + uint32_t raln; /* 0x23C receive alignment error counter */
93317 + uint32_t rflr; /* 0x240 receive frame length error counter */
93318 + uint32_t rcde; /* 0x244 receive code error counter */
93319 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
93320 + uint32_t rund; /* 0x24C receive undersize packet counter */
93321 + uint32_t rovr; /* 0x250 receive oversize packet counter */
93322 + uint32_t rfrg; /* 0x254 receive fragments counter */
93323 + uint32_t rjbr; /* 0x258 receive jabber counter */
93324 + uint32_t rdrp; /* 0x25C receive drop */
93325 + uint32_t tbyt; /* 0x260 transmit byte counter */
93326 + uint32_t tpkt; /* 0x264 transmit packet counter */
93327 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
93328 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
93329 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
93330 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
93331 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
93332 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
93333 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
93334 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
93335 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
93336 + uint32_t tncl; /* 0x28C transmit total collision counter */
93337 + uint32_t reserved0290[1];
93338 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
93339 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
93340 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
93341 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
93342 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
93343 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
93344 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
93345 + uint32_t car1; /* 0x2B0 carry register one register* */
93346 + uint32_t car2; /* 0x2B4 carry register two register* */
93347 + uint32_t cam1; /* 0x2B8 carry register one mask register */
93348 + uint32_t cam2; /* 0x2BC carry register two mask register */
93349 + uint32_t reserved02c0[848];
93350 +};
93351 +
93352 +/**
93353 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
93354 + *
93355 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
93356 + * good or bad frame, of any type, transmitted or received, which
93357 + * is 64 bytes in length.
93358 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
93359 + * each good or bad frame of any type, transmitted or received,
93360 + * which is 65-127 bytes in length.
93361 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
93362 + * for each good or bad frame, of any type, transmitted or
93363 + * received, which is 128-255 bytes in length.
93364 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
93365 + * for each good or bad frame, of any type, transmitted or
93366 + * received, which is 256-511 bytes in length.
93367 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
93368 + * for each good or bad frame, of any type, transmitted or
93369 + * received, which is 512-1023 bytes in length.
93370 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
93371 + * for each good or bad frame, of any type, transmitted or
93372 + * received, which is 1024-1518 bytes in length.
93373 + * @rfrg: Receive fragments count. Increments for each received frame
93374 + * which is less than 64 bytes in length and contains an invalid
93375 + * FCS. This includes integral and non-integral lengths.
93376 + * @rjbr: Receive jabber count. Increments for received frames which
93377 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
93378 + * invalid FCS. This includes alignment errors.
93379 + * @rdrp: Receive dropped packets count. Increments for received frames
93380 + * which are streamed to system but are later dropped due to lack
93381 + * of system resources. Does not increment for frames rejected due
93382 + * to address filtering.
93383 + * @raln: Receive alignment error count. Increments for each received
93384 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
93385 + * an invalid FCS and is not an integral number of bytes.
93386 + * @rund: Receive undersize packet count. Increments each time a frame is
93387 + * received which is less than 64 bytes in length and contains a
93388 + * valid FCS and is otherwise well formed. This count does not
93389 + * include range length errors.
93390 + * @rovr: Receive oversize packet count. Increments each time a frame is
93391 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
93392 + * contains a valid FCS and is otherwise well formed.
93393 + * @rbyt: Receive byte count. Increments by the byte count of frames
93394 + * received, including those in bad packets, excluding preamble and
93395 + * SFD but including FCS bytes.
93396 + * @rpkt: Receive packet count. Increments for each received frame
93397 + * (including bad packets, all unicast, broadcast, and multicast
93398 + * packets).
93399 + * @rmca: Receive multicast packet count. Increments for each multicast
93400 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93401 + * 1522 (VLAN), excluding broadcast frames. This count does not
93402 + * include range/length errors.
93403 + * @rbca: Receive broadcast packet count. Increments for each broadcast
93404 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93405 + * 1522 (VLAN), excluding multicast frames. Does not include
93406 + * range/length errors.
93407 + * @tdrp: Transmit drop frame count. Increments each time a memory error
93408 + * or an underrun has occurred.
93409 + * @tncl: Transmit total collision counter. Increments by the number of
93410 + * collisions experienced during the transmission of a frame. Does
93411 + * not increment for aborted frames.
93412 + *
93413 + * The structure contains a group of dTSEC HW specific counters relating to the
93414 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
93415 + * is counting only the carry events of the corresponding HW counters.
93416 + *
93417 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
93418 + * and SFD but including FCS bytes.
93419 + */
93420 +struct dtsec_mib_grp_1_counters {
93421 + uint64_t rdrp;
93422 + uint64_t tdrp;
93423 + uint64_t rbyt;
93424 + uint64_t rpkt;
93425 + uint64_t rbca;
93426 + uint64_t rmca;
93427 + uint64_t raln;
93428 + uint64_t rund;
93429 + uint64_t rovr;
93430 + uint64_t rfrg;
93431 + uint64_t rjbr;
93432 + uint64_t tncl;
93433 + uint64_t tr64;
93434 + uint64_t tr127;
93435 + uint64_t tr255;
93436 + uint64_t tr511;
93437 + uint64_t tr1k;
93438 + uint64_t trmax;
93439 +};
93440 +
93441 +enum dtsec_stat_counters {
93442 + E_DTSEC_STAT_TR64,
93443 + E_DTSEC_STAT_TR127,
93444 + E_DTSEC_STAT_TR255,
93445 + E_DTSEC_STAT_TR511,
93446 + E_DTSEC_STAT_TR1K,
93447 + E_DTSEC_STAT_TRMAX,
93448 + E_DTSEC_STAT_TRMGV,
93449 + E_DTSEC_STAT_RBYT,
93450 + E_DTSEC_STAT_RPKT,
93451 + E_DTSEC_STAT_RMCA,
93452 + E_DTSEC_STAT_RBCA,
93453 + E_DTSEC_STAT_RXPF,
93454 + E_DTSEC_STAT_RALN,
93455 + E_DTSEC_STAT_RFLR,
93456 + E_DTSEC_STAT_RCDE,
93457 + E_DTSEC_STAT_RCSE,
93458 + E_DTSEC_STAT_RUND,
93459 + E_DTSEC_STAT_ROVR,
93460 + E_DTSEC_STAT_RFRG,
93461 + E_DTSEC_STAT_RJBR,
93462 + E_DTSEC_STAT_RDRP,
93463 + E_DTSEC_STAT_TFCS,
93464 + E_DTSEC_STAT_TBYT,
93465 + E_DTSEC_STAT_TPKT,
93466 + E_DTSEC_STAT_TMCA,
93467 + E_DTSEC_STAT_TBCA,
93468 + E_DTSEC_STAT_TXPF,
93469 + E_DTSEC_STAT_TNCL,
93470 + E_DTSEC_STAT_TDRP
93471 +};
93472 +
93473 +enum dtsec_stat_level {
93474 + /* No statistics */
93475 + E_MAC_STAT_NONE = 0,
93476 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
93477 + E_MAC_STAT_MIB_GRP1,
93478 + /* Only error counters are available. Optimized for performance */
93479 + E_MAC_STAT_PARTIAL,
93480 + /* All counters available. Not optimized for performance */
93481 + E_MAC_STAT_FULL
93482 +};
93483 +
93484 +
93485 +/**
93486 + * struct dtsec_cfg - dTSEC configuration
93487 + *
93488 + * @halfdup_on: Transmit half-duplex flow control, under software
93489 + * control for 10/100-Mbps half-duplex media. If set,
93490 + * back pressure is applied to media by raising carrier.
93491 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
93492 + * If this is exceeded dTSEC aborts transmission due to
93493 + * excessive collisions. The standard specifies the
93494 + * attempt limit to be 15.
93495 + * @halfdup_coll_window:The number of bytes of the frame during which
93496 + * collisions may occur. The default value of 55
93497 + * corresponds to the frame byte at the end of the
93498 + * standard 512-bit slot time window. If collisions are
93499 + * detected after this byte, the late collision event is
93500 + * asserted and transmission of current frame is aborted.
93501 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
93502 + * will be discarded by dTSEC.
93503 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
93504 + * of length 14..63 bytes.
93505 + * @rx_len_check: Length check for received frames. If set, the MAC
93506 + * checks the frame's length field on receive to ensure it
93507 + * matches the actual data field length. This only works
93508 + * for received frames with length field less than 1500.
93509 + * No check is performed for larger frames.
93510 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
93511 + * transmitted short frames and appends a CRC to every
93512 + * frame regardless of padding requirement.
93513 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
93514 + * to all frames. If frames presented to the MAC have a
93515 + * valid length and contain a valid CRC, @tx_crc should be
93516 + * reset.
93517 + * This field is ignored if @tx_pad_crc is set.
93518 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
93519 + * standard control frame behavior, and all Ethernet frames
93520 + * that have an ethertype of 0x8808 are treated as normal
93521 + * Ethernet frames and passed up to the packet interface on
93522 + * a DA match. Received pause control frames are passed to
93523 + * the packet interface only if Rx flow control is also
93524 + * disabled. See fman_dtsec_handle_rx_pause() function.
93525 + * @tx_pause_time: Transmit pause time value. This pause value is used as
93526 + * part of the pause frame to be sent when a transmit pause
93527 + * frame is initiated. If set to 0 this disables
93528 + * transmission of pause frames.
93529 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
93530 + * received Ethernet 7-byte preamble and passes it to the
93531 + * packet interface at the start of each received frame.
93532 + * This field should be reset for internal MAC loop-back
93533 + * mode.
93534 + * @tx_preamble: User defined preamble enable for transmitted frames.
93535 + * If set, a user-defined preamble must passed to the MAC
93536 + * and it is transmitted instead of the standard preamble.
93537 + * @preamble_len: Length, in bytes, of the preamble field preceding each
93538 + * Ethernet start-of-frame delimiter byte. The default
93539 + * value of 0x7 should be used in order to guarantee
93540 + * reliable operation with IEEE 802.3 compliant hardware.
93541 + * @rx_prepend: Packet alignment padding length. The specified number
93542 + * of bytes (1-31) of zero padding are inserted before the
93543 + * start of each received frame. For Ethernet, where
93544 + * optional preamble extraction is enabled, the padding
93545 + * appears before the preamble, otherwise the padding
93546 + * precedes the layer 2 header.
93547 + *
93548 + * This structure contains basic dTSEC configuration and must be passed to
93549 + * fman_dtsec_init() function. A default set of configuration values can be
93550 + * obtained by calling fman_dtsec_defconfig().
93551 + */
93552 +struct dtsec_cfg {
93553 + bool halfdup_on;
93554 + bool halfdup_alt_backoff_en;
93555 + bool halfdup_excess_defer;
93556 + bool halfdup_no_backoff;
93557 + bool halfdup_bp_no_backoff;
93558 + uint8_t halfdup_alt_backoff_val;
93559 + uint16_t halfdup_retransmit;
93560 + uint16_t halfdup_coll_window;
93561 + bool rx_drop_bcast;
93562 + bool rx_short_frm;
93563 + bool rx_len_check;
93564 + bool tx_pad_crc;
93565 + bool tx_crc;
93566 + bool rx_ctrl_acc;
93567 + unsigned short tx_pause_time;
93568 + unsigned short tbipa;
93569 + bool ptp_tsu_en;
93570 + bool ptp_exception_en;
93571 + bool rx_preamble;
93572 + bool tx_preamble;
93573 + unsigned char preamble_len;
93574 + unsigned char rx_prepend;
93575 + bool loopback;
93576 + bool rx_time_stamp_en;
93577 + bool tx_time_stamp_en;
93578 + bool rx_flow;
93579 + bool tx_flow;
93580 + bool rx_group_hash_exd;
93581 + bool rx_promisc;
93582 + uint8_t tbi_phy_addr;
93583 + uint16_t tx_pause_time_extd;
93584 + uint16_t maximum_frame;
93585 + uint32_t non_back_to_back_ipg1;
93586 + uint32_t non_back_to_back_ipg2;
93587 + uint32_t min_ifg_enforcement;
93588 + uint32_t back_to_back_ipg;
93589 + bool wake_on_lan;
93590 +};
93591 +
93592 +
93593 +/**
93594 + * fman_dtsec_defconfig() - Get default dTSEC configuration
93595 + * @cfg: pointer to configuration structure.
93596 + *
93597 + * Call this function to obtain a default set of configuration values for
93598 + * initializing dTSEC. The user can overwrite any of the values before calling
93599 + * fman_dtsec_init(), if specific configuration needs to be applied.
93600 + */
93601 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
93602 +
93603 +/**
93604 + * fman_dtsec_init() - Init dTSEC hardware block
93605 + * @regs: Pointer to dTSEC register block
93606 + * @cfg: dTSEC configuration data
93607 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
93608 + * @iface_speed: 1G or 10G
93609 + * @macaddr: MAC station address to be assigned to the device
93610 + * @fm_rev_maj: major rev number
93611 + * @fm_rev_min: minor rev number
93612 + * @exceptions_mask: initial exceptions mask
93613 + *
93614 + * This function initializes dTSEC and applies basic configuration.
93615 + *
93616 + * dTSEC initialization sequence:
93617 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
93618 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
93619 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
93620 + *
93621 + * Returns: 0 if successful, an error code otherwise.
93622 + */
93623 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
93624 + enum enet_interface iface_mode,
93625 + enum enet_speed iface_speed,
93626 + uint8_t *macaddr, uint8_t fm_rev_maj,
93627 + uint8_t fm_rev_min,
93628 + uint32_t exception_mask);
93629 +
93630 +/**
93631 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
93632 + * @regs: Pointer to dTSEC register block
93633 + * @apply_rx: enable rx side
93634 + * @apply_tx: enable tx side
93635 + *
93636 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
93637 + */
93638 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
93639 +
93640 +/**
93641 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
93642 + * @regs: Pointer to dTSEC register block
93643 + * @apply_rx: disable rx side
93644 + * @apply_tx: disable tx side
93645 + *
93646 + * This function disables Tx and Rx in dTSEC.
93647 + */
93648 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
93649 +
93650 +/**
93651 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
93652 + * @regs: Pointer to dTSEC register block
93653 + *
93654 + * Returns dtsec_id content
93655 + *
93656 + * Call this function to obtain the dTSEC hardware version.
93657 + */
93658 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
93659 +
93660 +/**
93661 + * fman_dtsec_set_mac_address() - Set MAC station address
93662 + * @regs: Pointer to dTSEC register block
93663 + * @macaddr: MAC address array
93664 + *
93665 + * This function sets MAC station address. To enable unicast reception call
93666 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
93667 + * match the destination address of received unicast frames against this
93668 + * address.
93669 + */
93670 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
93671 +
93672 +/**
93673 + * fman_dtsec_get_mac_address() - Query MAC station address
93674 + * @regs: Pointer to dTSEC register block
93675 + * @macaddr: MAC address array
93676 + */
93677 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
93678 +
93679 +/**
93680 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
93681 + * @regs: Pointer to dTSEC register block
93682 + * @enable: Enable unicast promiscuous mode
93683 + *
93684 + * Use this function to enable/disable dTSEC L2 address filtering. If the
93685 + * address filtering is disabled all unicast packets are accepted.
93686 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
93687 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
93688 + * multicast addresses.
93689 + */
93690 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
93691 +
93692 +/**
93693 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
93694 + * (magic packet support)
93695 + * @regs: Pointer to dTSEC register block
93696 + * @en: Enable Wake On Lan support in dTSEC
93697 + *
93698 + */
93699 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
93700 +
93701 +/**
93702 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
93703 + * @regs: Pointer to dTSEC register block
93704 + * @iface_mode: dTSEC interface mode
93705 + * @speed: Link speed
93706 + * @full_dx: True for full-duplex, false for half-duplex.
93707 + *
93708 + * This function configures the MAC to function and the desired rates. Use it
93709 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
93710 + * changes (for instance following PHY auto-negociation).
93711 + *
93712 + * Returns: 0 if successful, an error code otherwise.
93713 + */
93714 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
93715 + enum enet_interface iface_mode,
93716 + enum enet_speed speed, bool full_dx);
93717 +
93718 +/**
93719 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
93720 + * @regs: Pointer to dTSEC register block
93721 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
93722 + *
93723 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
93724 + * so that the associated TBI PHY (i.e. the link) may be initialized.
93725 + *
93726 + * Returns: 0 if successful, an error code otherwise.
93727 + */
93728 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
93729 + uint8_t addr);
93730 +
93731 +/**
93732 + * fman_dtsec_set_max_frame_len() - Set max frame length
93733 + * @regs: Pointer to dTSEC register block
93734 + * @length: Max frame length.
93735 + *
93736 + * Sets maximum frame length for received and transmitted frames. Frames that
93737 + * exceeds this length are truncated.
93738 + */
93739 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
93740 +
93741 +/**
93742 + * fman_dtsec_get_max_frame_len() - Query max frame length
93743 + * @regs: Pointer to dTSEC register block
93744 + *
93745 + * Returns: the current value of the maximum frame length.
93746 + */
93747 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
93748 +
93749 +/**
93750 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
93751 + * @regs: Pointer to dTSEC register block
93752 + * @en: Enable pause frame handling in dTSEC
93753 + *
93754 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
93755 + * if dTSEC is set in half-duplex mode.
93756 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
93757 + * frames will be transferred to the packet interface just like regular Ethernet
93758 + * frames.
93759 + */
93760 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
93761 +
93762 +/**
93763 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
93764 + * @regs: Pointer to dTSEC register block
93765 + * @time: Time value included in pause frames
93766 + *
93767 + * Call this function to set the time value used in transmitted pause frames.
93768 + * If time is 0, transmission of pause frames is disabled
93769 + */
93770 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
93771 +
93772 +/**
93773 + * fman_dtsec_ack_event() - Acknowledge handled events
93774 + * @regs: Pointer to dTSEC register block
93775 + * @ev_mask: Events to acknowledge
93776 + *
93777 + * After handling events signaled by dTSEC in either polling or interrupt mode,
93778 + * call this function to reset the associated status bits in dTSEC event
93779 + * register.
93780 + */
93781 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
93782 +
93783 +/**
93784 + * fman_dtsec_get_event() - Returns currently asserted events
93785 + * @regs: Pointer to dTSEC register block
93786 + * @ev_mask: Mask of relevant events
93787 + *
93788 + * Call this function to obtain a bit-mask of events that are currently asserted
93789 + * in dTSEC, taken from IEVENT register.
93790 + *
93791 + * Returns: a bit-mask of events asserted in dTSEC.
93792 + */
93793 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
93794 +
93795 +/**
93796 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
93797 + * @regs: Pointer to dTSEC register block
93798 + *
93799 + * Call this function to obtain a bit-mask of enabled interrupts
93800 + * in dTSEC, taken from IMASK register.
93801 + *
93802 + * Returns: a bit-mask of enabled interrupts in dTSEC.
93803 + */
93804 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
93805 +
93806 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
93807 + uint8_t paddr_num);
93808 +
93809 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
93810 + uint64_t addr,
93811 + uint8_t paddr_num);
93812 +
93813 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
93814 +
93815 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
93816 +
93817 +/**
93818 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
93819 + * @regs: Pointer to dTSEC register block
93820 + * @ev_mask: Mask of relevant events
93821 + *
93822 + * Call this function to disable interrupts in dTSEC for the specified events.
93823 + * To enable interrupts use fman_dtsec_enable_interrupt().
93824 + */
93825 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
93826 +
93827 +/**
93828 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
93829 + * @regs: Pointer to dTSEC register block
93830 + * @ev_mask: Mask of relevant events
93831 + *
93832 + * Call this function to enable interrupts in dTSEC for the specified events.
93833 + * To disable interrupts use fman_dtsec_disable_interrupt().
93834 + */
93835 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
93836 +
93837 +/**
93838 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
93839 + * @regs: Pointer to dTSEC register block
93840 + * @en: true to enable timestamps, false to disable them
93841 + *
93842 + * Call this function to enable/disable dTSEC timestamps. This affects both
93843 + * Tx and Rx.
93844 + */
93845 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
93846 +
93847 +/**
93848 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
93849 + * @regs: Pointer to dTSEC register block
93850 + * @bucket: Bucket index
93851 + * @enable: true/false to enable/disable this bucket
93852 + *
93853 + * This function enables or disables the specified bucket. Enabling a bucket
93854 + * associated with an address configures dTSEC to accept received packets
93855 + * with that destination address.
93856 + * Multiple addresses may be associated with the same bucket. Disabling a
93857 + * bucket will affect all addresses associated with that bucket. A bucket that
93858 + * is enabled requires further filtering and verification in the upper layers
93859 + *
93860 + */
93861 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
93862 +
93863 +/**
93864 + * dtsec_set_hash_table() - insert a crc code into thr filter table
93865 + * @regs: Pointer to dTSEC register block
93866 + * @crc: crc to insert
93867 + * @mcast: true is this is a multicast address
93868 + * @ghtx: true if we are in ghtx mode
93869 + *
93870 + * This function inserts a crc code into the filter table.
93871 + */
93872 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
93873 + bool mcast, bool ghtx);
93874 +
93875 +/**
93876 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
93877 + * @regs: Pointer to dTSEC register block
93878 + * @mcast: Reset multicast entries
93879 + * @ucast: Reset unicast entries
93880 + *
93881 + * Resets all entries in L2 address filter table. After calling this function
93882 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
93883 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
93884 + * @ucast argument is ignored.
93885 + * This does not affect the primary nor the 15 additional addresses configured
93886 + * using dtsec_set_address() or dtsec_set_match_address().
93887 + */
93888 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
93889 + bool ucast);
93890 +
93891 +/**
93892 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
93893 + * @regs: Pointer to dTSEC register block
93894 + * @enable: Enable multicast promiscuous mode
93895 + *
93896 + * Call this to enable/disable L2 address filtering for multicast packets.
93897 + */
93898 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
93899 +
93900 +/* statistics APIs */
93901 +
93902 +/**
93903 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
93904 + * @regs: Pointer to dTSEC register block
93905 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
93906 + * to specify all the existing counters.
93907 + * If set to _none_, it disables all the counters.
93908 + *
93909 + * Enables the MIB statistics hw counters and sets up the carry interrupt
93910 + * masks for the counters corresponding to the @level input parameter.
93911 + *
93912 + * Returns: error if invalid @level value given.
93913 + */
93914 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
93915 + enum dtsec_stat_level level);
93916 +
93917 +/**
93918 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
93919 + * @regs: Pointer to dTSEC register block
93920 + */
93921 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
93922 +
93923 +/**
93924 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
93925 + * @regs: Pointer to dTSEC register block
93926 + * @car1: car1 register value
93927 + * @car2: car2 register value
93928 + *
93929 + * When set, the carry bits signal that an overflow occurred on the
93930 + * corresponding counters.
93931 + * Note that the carry bits (CAR1-2 registers) will assert the
93932 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
93933 + *
93934 + * Returns: true if overflow occurred, otherwise - false
93935 + */
93936 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
93937 + uint32_t *car1, uint32_t *car2);
93938 +
93939 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
93940 +
93941 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
93942 + enum dtsec_stat_counters reg_name);
93943 +
93944 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
93945 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
93946 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
93947 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
93948 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
93949 +
93950 +
93951 +#endif /* __FSL_FMAN_DTSEC_H */
93952 --- /dev/null
93953 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
93954 @@ -0,0 +1,107 @@
93955 +/*
93956 + * Copyright 2008-2013 Freescale Semiconductor Inc.
93957 + *
93958 + * Redistribution and use in source and binary forms, with or without
93959 + * modification, are permitted provided that the following conditions are met:
93960 + * * Redistributions of source code must retain the above copyright
93961 + * notice, this list of conditions and the following disclaimer.
93962 + * * Redistributions in binary form must reproduce the above copyright
93963 + * notice, this list of conditions and the following disclaimer in the
93964 + * documentation and/or other materials provided with the distribution.
93965 + * * Neither the name of Freescale Semiconductor nor the
93966 + * names of its contributors may be used to endorse or promote products
93967 + * derived from this software without specific prior written permission.
93968 + *
93969 + *
93970 + * ALTERNATIVELY, this software may be distributed under the terms of the
93971 + * GNU General Public License ("GPL") as published by the Free Software
93972 + * Foundation, either version 2 of that License or (at your option) any
93973 + * later version.
93974 + *
93975 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93976 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93977 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93978 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93979 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93980 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93981 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93982 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93983 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93984 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93985 + */
93986 +
93987 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
93988 +#define __FSL_FMAN_DTSEC_MII_ACC_H
93989 +
93990 +#include "common/general.h"
93991 +
93992 +
93993 +/* MII Management Configuration Register */
93994 +#define MIIMCFG_RESET_MGMT 0x80000000
93995 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
93996 +#define MIIMCFG_MGNTCLK_SHIFT 0
93997 +
93998 +/* MII Management Command Register */
93999 +#define MIIMCOM_SCAN_CYCLE 0x00000002
94000 +#define MIIMCOM_READ_CYCLE 0x00000001
94001 +
94002 +/* MII Management Address Register */
94003 +#define MIIMADD_PHY_ADDR_SHIFT 8
94004 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
94005 +
94006 +#define MIIMADD_REG_ADDR_SHIFT 0
94007 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
94008 +
94009 +/* MII Management Indicator Register */
94010 +#define MIIMIND_BUSY 0x00000001
94011 +
94012 +
94013 +/* PHY Control Register */
94014 +#define PHY_CR_PHY_RESET 0x8000
94015 +#define PHY_CR_LOOPBACK 0x4000
94016 +#define PHY_CR_SPEED0 0x2000
94017 +#define PHY_CR_ANE 0x1000
94018 +#define PHY_CR_RESET_AN 0x0200
94019 +#define PHY_CR_FULLDUPLEX 0x0100
94020 +#define PHY_CR_SPEED1 0x0040
94021 +
94022 +#define PHY_TBICON_SRESET 0x8000
94023 +#define PHY_TBICON_SPEED2 0x0020
94024 +#define PHY_TBICON_CLK_SEL 0x0020
94025 +#define PHY_TBIANA_SGMII 0x4001
94026 +#define PHY_TBIANA_1000X 0x01a0
94027 +/* register map */
94028 +
94029 +/* MII Configuration Control Memory Map Registers */
94030 +struct dtsec_mii_reg {
94031 + uint32_t reserved1[72];
94032 + uint32_t miimcfg; /* MII Mgmt:configuration */
94033 + uint32_t miimcom; /* MII Mgmt:command */
94034 + uint32_t miimadd; /* MII Mgmt:address */
94035 + uint32_t miimcon; /* MII Mgmt:control 3 */
94036 + uint32_t miimstat; /* MII Mgmt:status */
94037 + uint32_t miimind; /* MII Mgmt:indicators */
94038 +};
94039 +
94040 +/* dTSEC MII API */
94041 +
94042 +/* functions to access the mii registers for phy configuration.
94043 + * this functionality may not be available for all dtsecs in the system.
94044 + * consult the reference manual for details */
94045 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
94046 +/* frequency is in MHz.
94047 + * note that dtsec clock is 1/2 of fman clock */
94048 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
94049 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
94050 + uint8_t addr,
94051 + uint8_t reg,
94052 + uint16_t data,
94053 + uint16_t dtsec_freq);
94054 +
94055 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
94056 + uint8_t addr,
94057 + uint8_t reg,
94058 + uint16_t *data,
94059 + uint16_t dtsec_freq);
94060 +
94061 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
94062 --- /dev/null
94063 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94064 @@ -0,0 +1,514 @@
94065 +/*
94066 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94067 + *
94068 + * Redistribution and use in source and binary forms, with or without
94069 + * modification, are permitted provided that the following conditions are met:
94070 + * * Redistributions of source code must retain the above copyright
94071 + * notice, this list of conditions and the following disclaimer.
94072 + * * Redistributions in binary form must reproduce the above copyright
94073 + * notice, this list of conditions and the following disclaimer in the
94074 + * documentation and/or other materials provided with the distribution.
94075 + * * Neither the name of Freescale Semiconductor nor the
94076 + * names of its contributors may be used to endorse or promote products
94077 + * derived from this software without specific prior written permission.
94078 + *
94079 + *
94080 + * ALTERNATIVELY, this software may be distributed under the terms of the
94081 + * GNU General Public License ("GPL") as published by the Free Software
94082 + * Foundation, either version 2 of that License or (at your option) any
94083 + * later version.
94084 + *
94085 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94086 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94087 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94088 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94089 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94090 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94091 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94092 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94093 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94094 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94095 + */
94096 +
94097 +#ifndef __FSL_FMAN_KG_H
94098 +#define __FSL_FMAN_KG_H
94099 +
94100 +#include "common/general.h"
94101 +
94102 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
94103 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
94104 +/**< Total num of masks allowed on KG extractions */
94105 +#define FM_KG_EXTRACT_MASKS_NUM 4
94106 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
94107 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
94108 +
94109 +struct fman_kg_regs {
94110 + uint32_t fmkg_gcr;
94111 + uint32_t res004;
94112 + uint32_t res008;
94113 + uint32_t fmkg_eer;
94114 + uint32_t fmkg_eeer;
94115 + uint32_t res014;
94116 + uint32_t res018;
94117 + uint32_t fmkg_seer;
94118 + uint32_t fmkg_seeer;
94119 + uint32_t fmkg_gsr;
94120 + uint32_t fmkg_tpc;
94121 + uint32_t fmkg_serc;
94122 + uint32_t res030[4];
94123 + uint32_t fmkg_fdor;
94124 + uint32_t fmkg_gdv0r;
94125 + uint32_t fmkg_gdv1r;
94126 + uint32_t res04c[6];
94127 + uint32_t fmkg_feer;
94128 + uint32_t res068[38];
94129 + uint32_t fmkg_indirect[63];
94130 + uint32_t fmkg_ar;
94131 +};
94132 +
94133 +struct fman_kg_scheme_regs {
94134 + uint32_t kgse_mode; /**< MODE */
94135 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
94136 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
94137 + uint32_t kgse_bmch; /**< Bit Mask Command High */
94138 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
94139 + uint32_t kgse_fqb; /**< Frame Queue Base */
94140 + uint32_t kgse_hc; /**< Hash Command */
94141 + uint32_t kgse_ppc; /**< Policer Profile Command */
94142 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
94143 + /**< Generic Extract Command */
94144 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
94145 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
94146 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
94147 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
94148 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
94149 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
94150 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
94151 +};
94152 +
94153 +struct fman_kg_pe_regs{
94154 + uint32_t fmkg_pe_sp;
94155 + uint32_t fmkg_pe_cpp;
94156 +};
94157 +
94158 +struct fman_kg_cp_regs {
94159 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
94160 +};
94161 +
94162 +
94163 +#define FM_KG_KGAR_GO 0x80000000
94164 +#define FM_KG_KGAR_READ 0x40000000
94165 +#define FM_KG_KGAR_WRITE 0x00000000
94166 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
94167 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
94168 +
94169 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
94170 +#define KG_SCH_PP_NO_GEN 0x10000000
94171 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
94172 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
94173 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94174 +#define KG_SCH_BITMASK_MASK 0x000000FF
94175 +#define KG_SCH_GEN_VALID 0x80000000
94176 +#define KG_SCH_GEN_MASK 0x00FF0000
94177 +#define FM_PCD_KG_KGAR_ERR 0x20000000
94178 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
94179 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
94180 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
94181 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
94182 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
94183 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
94184 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
94185 +
94186 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
94187 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
94188 +
94189 +/* ECC capture register */
94190 +#define KG_FMKG_SERC_CAP 0x80000000
94191 +#define KG_FMKG_SERC_CET 0x40000000
94192 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
94193 +#define KG_FMKG_SERC_CNT_SHIFT 16
94194 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
94195 +
94196 +/* Masks */
94197 +#define FM_KG_KGGCR_EN 0x80000000
94198 +#define KG_SCH_GEN_VALID 0x80000000
94199 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94200 +#define KG_ERR_TYPE_DOUBLE 0x40000000
94201 +#define KG_ERR_ADDR_MASK 0x00000FFF
94202 +#define KG_SCH_MODE_EN 0x80000000
94203 +
94204 +/* shifts */
94205 +#define FM_KG_KGAR_NUM_SHIFT 16
94206 +#define FM_KG_PE_CPP_MASK_SHIFT 16
94207 +#define FM_KG_KGAR_WSEL_SHIFT 8
94208 +
94209 +#define FM_KG_SCH_GEN_HT_INVALID 0
94210 +
94211 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
94212 +
94213 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
94214 +switch (i) \
94215 +{ \
94216 + case 0: (shift) = 26; break; \
94217 + case 1: (shift) = 20; break; \
94218 + case 2: (shift) = 10; break; \
94219 + case 3: (shift) = 4; break; \
94220 + default: (shift) = 0; \
94221 +}
94222 +
94223 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
94224 +switch (i) \
94225 +{ \
94226 + case 0: (shift) = 16; break; \
94227 + case 1: (shift) = 0; break; \
94228 + case 2: (shift) = 28; break; \
94229 + case 3: (shift) = 24; break; \
94230 + default: (shift) = 0; \
94231 +}
94232 +
94233 +#define KG_GET_MASK_SHIFT(shift, i) \
94234 +switch (i) \
94235 +{ \
94236 + case 0: shift = 24; break; \
94237 + case 1: shift = 16; break; \
94238 + case 2: shift = 8; break; \
94239 + case 3: shift = 0; break; \
94240 + default: shift = 0; \
94241 +}
94242 +
94243 +/* Port entry CPP register */
94244 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
94245 +
94246 +/* Scheme registers */
94247 +#define FMAN_KG_SCH_MODE_EN 0x80000000
94248 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
94249 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
94250 +
94251 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
94252 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
94253 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
94254 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
94255 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
94256 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
94257 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
94258 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
94259 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
94260 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
94261 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
94262 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
94263 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
94264 +
94265 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
94266 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
94267 +#define FMAN_KG_SCH_GEN_OR 0x00008000
94268 +
94269 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
94270 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
94271 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
94272 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
94273 +
94274 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
94275 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
94276 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
94277 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
94278 +
94279 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
94280 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
94281 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
94282 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
94283 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
94284 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
94285 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
94286 +
94287 +enum fman_kg_gen_extract_src {
94288 + E_FMAN_KG_GEN_EXTRACT_ETH,
94289 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
94290 + E_FMAN_KG_GEN_EXTRACT_SNAP,
94291 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
94292 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
94293 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
94294 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
94295 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
94296 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
94297 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
94298 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
94299 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
94300 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
94301 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
94302 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
94303 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
94304 + E_FMAN_KG_GEN_EXTRACT_GRE,
94305 + E_FMAN_KG_GEN_EXTRACT_TCP,
94306 + E_FMAN_KG_GEN_EXTRACT_UDP,
94307 + E_FMAN_KG_GEN_EXTRACT_SCTP,
94308 + E_FMAN_KG_GEN_EXTRACT_DCCP,
94309 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
94310 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
94311 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
94312 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
94313 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
94314 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
94315 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
94316 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
94317 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
94318 +};
94319 +
94320 +struct fman_kg_ex_ecc_attr
94321 +{
94322 + bool valid;
94323 + bool double_ecc;
94324 + uint16_t addr;
94325 + uint8_t single_ecc_count;
94326 +};
94327 +
94328 +enum fman_kg_def_select
94329 +{
94330 + E_FMAN_KG_DEF_GLOBAL_0,
94331 + E_FMAN_KG_DEF_GLOBAL_1,
94332 + E_FMAN_KG_DEF_SCHEME_0,
94333 + E_FMAN_KG_DEF_SCHEME_1
94334 +};
94335 +
94336 +struct fman_kg_extract_def
94337 +{
94338 + enum fman_kg_def_select mac_addr;
94339 + enum fman_kg_def_select vlan_tci;
94340 + enum fman_kg_def_select etype;
94341 + enum fman_kg_def_select ppp_sid;
94342 + enum fman_kg_def_select ppp_pid;
94343 + enum fman_kg_def_select mpls;
94344 + enum fman_kg_def_select ip_addr;
94345 + enum fman_kg_def_select ptype;
94346 + enum fman_kg_def_select ip_tos_tc;
94347 + enum fman_kg_def_select ipv6_fl;
94348 + enum fman_kg_def_select ipsec_spi;
94349 + enum fman_kg_def_select l4_port;
94350 + enum fman_kg_def_select tcp_flg;
94351 +};
94352 +
94353 +enum fman_kg_gen_extract_type
94354 +{
94355 + E_FMAN_KG_HASH_EXTRACT,
94356 + E_FMAN_KG_OR_EXTRACT
94357 +};
94358 +
94359 +struct fman_kg_gen_extract_params
94360 +{
94361 + /* Hash or Or-ed extract */
94362 + enum fman_kg_gen_extract_type type;
94363 + enum fman_kg_gen_extract_src src;
94364 + bool no_validation;
94365 + /* Extraction offset from the header location specified above */
94366 + uint8_t offset;
94367 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
94368 + * hash result shift for FMAN_KG_OR_EXTRACT */
94369 + uint8_t extract;
94370 + uint8_t mask;
94371 + /* Default value to use when header specified
94372 + * by fman_kg_gen_extract_src doesn't present */
94373 + enum fman_kg_def_select def_val;
94374 +};
94375 +
94376 +struct fman_kg_extract_mask
94377 +{
94378 + /**< Indication if mask is on known field extraction or
94379 + * on general extraction; TRUE for known field */
94380 + bool is_known;
94381 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
94382 + * generic register index for generic extracts mask */
94383 + uint32_t field_or_gen_idx;
94384 + /**< Byte offset from start of the extracted data specified
94385 + * by field_or_gen_idx */
94386 + uint8_t offset;
94387 + /**< Byte mask (selected bits will be used) */
94388 + uint8_t mask;
94389 +};
94390 +
94391 +struct fman_kg_extract_params
94392 +{
94393 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
94394 + uint32_t known_fields;
94395 + struct fman_kg_extract_def known_fields_def;
94396 + /* Number of entries in gen_extract */
94397 + uint8_t gen_extract_num;
94398 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
94399 + /* Number of entries in masks */
94400 + uint8_t masks_num;
94401 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
94402 + uint32_t def_scheme_0;
94403 + uint32_t def_scheme_1;
94404 +};
94405 +
94406 +struct fman_kg_hash_params
94407 +{
94408 + bool use_hash;
94409 + uint8_t shift_r;
94410 + uint32_t mask; /**< 24-bit mask */
94411 + bool sym; /**< Symmetric hash for src and dest pairs */
94412 +};
94413 +
94414 +struct fman_kg_pp_params
94415 +{
94416 + uint8_t base;
94417 + uint8_t shift;
94418 + uint8_t mask;
94419 + bool bypass_pp_gen;
94420 +};
94421 +
94422 +struct fman_kg_cc_params
94423 +{
94424 + uint8_t base_offset;
94425 + uint32_t qlcv_bits_sel;
94426 +};
94427 +
94428 +enum fman_pcd_engine
94429 +{
94430 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
94431 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
94432 + E_FMAN_PCD_KG, /**< Keygen indicated */
94433 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
94434 + E_FMAN_PCD_PLCR, /**< Policer indicated */
94435 + E_FMAN_PCD_PRS /**< Parser indicated */
94436 +};
94437 +
94438 +struct fman_kg_cls_plan_params
94439 +{
94440 + uint8_t entries_mask;
94441 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
94442 +};
94443 +
94444 +struct fman_kg_scheme_params
94445 +{
94446 + uint32_t match_vector;
94447 + struct fman_kg_extract_params extract_params;
94448 + struct fman_kg_hash_params hash_params;
94449 + uint32_t base_fqid;
94450 + /* What we do w/features supported per FM version ?? */
94451 + bool bypass_fqid_gen;
94452 + struct fman_kg_pp_params policer_params;
94453 + struct fman_kg_cc_params cc_params;
94454 + bool update_counter;
94455 + /**< counter_value: Set scheme counter to the specified value;
94456 + * relevant only when update_counter = TRUE. */
94457 + uint32_t counter_value;
94458 + enum fman_pcd_engine next_engine;
94459 + /**< Next engine action code */
94460 + uint32_t next_engine_action;
94461 +};
94462 +
94463 +
94464 +
94465 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
94466 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
94467 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
94468 +void fman_kg_get_event(struct fman_kg_regs *regs,
94469 + uint32_t *event,
94470 + uint32_t *scheme_idx);
94471 +void fman_kg_init(struct fman_kg_regs *regs,
94472 + uint32_t exceptions,
94473 + uint32_t dflt_nia);
94474 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
94475 +void fman_kg_enable(struct fman_kg_regs *regs);
94476 +void fman_kg_disable(struct fman_kg_regs *regs);
94477 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
94478 + uint8_t hwport_id,
94479 + uint32_t bind_cls_plans);
94480 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
94481 + uint8_t grp_mask,
94482 + uint32_t *bind_cls_plans);
94483 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
94484 + uint8_t hwport_id,
94485 + uint32_t schemes);
94486 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
94487 + uint8_t grp_id,
94488 + uint8_t entries_mask,
94489 + uint8_t hwport_id,
94490 + struct fman_kg_cp_regs *cls_plan_regs);
94491 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
94492 + struct fman_kg_cp_regs *cls_plan_regs);
94493 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
94494 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
94495 + uint8_t scheme_id,
94496 + uint8_t hwport_id,
94497 + uint32_t counter);
94498 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
94499 + uint8_t scheme_id,
94500 + uint8_t hwport_id,
94501 + uint32_t *counter);
94502 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
94503 + uint8_t scheme_id,
94504 + uint8_t hwport_id);
94505 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
94506 + uint8_t scheme_id,
94507 + uint8_t hwport_id,
94508 + struct fman_kg_scheme_regs *scheme_regs,
94509 + bool update_counter);
94510 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
94511 + struct fman_kg_scheme_regs *scheme_regs);
94512 +void fman_kg_get_capture(struct fman_kg_regs *regs,
94513 + struct fman_kg_ex_ecc_attr *ecc_attr,
94514 + bool clear);
94515 +void fman_kg_get_exception(struct fman_kg_regs *regs,
94516 + uint32_t *events,
94517 + uint32_t *scheme_ids,
94518 + bool clear);
94519 +void fman_kg_set_exception(struct fman_kg_regs *regs,
94520 + uint32_t exception,
94521 + bool enable);
94522 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
94523 + uint8_t def_id,
94524 + uint32_t val);
94525 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
94526 +
94527 +
94528 +
94529 +/**************************************************************************//**
94530 + @Description NIA Description
94531 +*//***************************************************************************/
94532 +#define KG_NIA_ORDER_RESTOR 0x00800000
94533 +#define KG_NIA_ENG_FM_CTL 0x00000000
94534 +#define KG_NIA_ENG_PRS 0x00440000
94535 +#define KG_NIA_ENG_KG 0x00480000
94536 +#define KG_NIA_ENG_PLCR 0x004C0000
94537 +#define KG_NIA_ENG_BMI 0x00500000
94538 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
94539 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
94540 +#define KG_NIA_ENG_MASK 0x007C0000
94541 +
94542 +#define KG_NIA_AC_MASK 0x0003FFFF
94543 +
94544 +#define KG_NIA_INVALID 0xFFFFFFFF
94545 +
94546 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
94547 + uint32_t next_engine_action)
94548 +{
94549 + uint32_t nia;
94550 +
94551 + if (next_engine_action & ~KG_NIA_AC_MASK)
94552 + return KG_NIA_INVALID;
94553 +
94554 + switch (next_engine) {
94555 + case E_FMAN_PCD_DONE:
94556 + nia = KG_NIA_ENG_BMI | next_engine_action;
94557 + break;
94558 +
94559 + case E_FMAN_PCD_KG:
94560 + nia = KG_NIA_ENG_KG | next_engine_action;
94561 + break;
94562 +
94563 + case E_FMAN_PCD_CC:
94564 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
94565 + break;
94566 +
94567 + case E_FMAN_PCD_PLCR:
94568 + nia = KG_NIA_ENG_PLCR | next_engine_action;
94569 + break;
94570 +
94571 + default:
94572 + nia = KG_NIA_INVALID;
94573 + }
94574 +
94575 + return nia;
94576 +}
94577 +
94578 +#endif /* __FSL_FMAN_KG_H */
94579 --- /dev/null
94580 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
94581 @@ -0,0 +1,427 @@
94582 +/*
94583 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94584 + *
94585 + * Redistribution and use in source and binary forms, with or without
94586 + * modification, are permitted provided that the following conditions are met:
94587 + * * Redistributions of source code must retain the above copyright
94588 + * notice, this list of conditions and the following disclaimer.
94589 + * * Redistributions in binary form must reproduce the above copyright
94590 + * notice, this list of conditions and the following disclaimer in the
94591 + * documentation and/or other materials provided with the distribution.
94592 + * * Neither the name of Freescale Semiconductor nor the
94593 + * names of its contributors may be used to endorse or promote products
94594 + * derived from this software without specific prior written permission.
94595 + *
94596 + *
94597 + * ALTERNATIVELY, this software may be distributed under the terms of the
94598 + * GNU General Public License ("GPL") as published by the Free Software
94599 + * Foundation, either version 2 of that License or (at your option) any
94600 + * later version.
94601 + *
94602 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94603 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94604 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94605 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94606 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94607 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94608 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94609 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94610 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94611 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94612 + */
94613 +
94614 +
94615 +#ifndef __FSL_FMAN_MEMAC_H
94616 +#define __FSL_FMAN_MEMAC_H
94617 +
94618 +#include "common/general.h"
94619 +#include "fsl_enet.h"
94620 +
94621 +
94622 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
94623 +
94624 +/* Control and Configuration Register (COMMAND_CONFIG) */
94625 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
94626 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
94627 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
94628 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
94629 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
94630 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
94631 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
94632 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
94633 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
94634 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
94635 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
94636 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
94637 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
94638 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
94639 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
94640 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
94641 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
94642 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
94643 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
94644 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
94645 +
94646 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
94647 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
94648 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
94649 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
94650 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
94651 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
94652 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
94653 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
94654 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
94655 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
94656 +
94657 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
94658 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
94659 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
94660 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
94661 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
94662 +
94663 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
94664 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
94665 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
94666 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
94667 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
94668 +
94669 +/* Interface Mode Register (IF_MODE) */
94670 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
94671 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
94672 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
94673 +#define IF_MODE_RGMII 0x00000004
94674 +#define IF_MODE_RGMII_AUTO 0x00008000
94675 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
94676 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
94677 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
94678 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
94679 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
94680 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
94681 +
94682 +/* Hash table Control Register (HASHTABLE_CTRL) */
94683 +#define HASH_CTRL_MCAST_SHIFT 26
94684 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
94685 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
94686 +
94687 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
94688 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
94689 +
94690 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
94691 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
94692 +
94693 +/* Statistics Configuration Register (STATN_CONFIG) */
94694 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
94695 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
94696 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
94697 +
94698 +/* Interrupt Mask Register (IMASK) */
94699 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
94700 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
94701 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
94702 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
94703 +
94704 +#define MEMAC_ALL_ERRS_IMASK \
94705 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
94706 + MEMAC_IMASK_TECC_ER | \
94707 + MEMAC_IMASK_RECC_ER | \
94708 + MEMAC_IMASK_MGI))
94709 +
94710 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
94711 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
94712 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
94713 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
94714 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
94715 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
94716 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
94717 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
94718 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
94719 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
94720 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
94721 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
94722 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
94723 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
94724 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
94725 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
94726 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
94727 +
94728 +enum memac_counters {
94729 + E_MEMAC_COUNTER_R64,
94730 + E_MEMAC_COUNTER_R127,
94731 + E_MEMAC_COUNTER_R255,
94732 + E_MEMAC_COUNTER_R511,
94733 + E_MEMAC_COUNTER_R1023,
94734 + E_MEMAC_COUNTER_R1518,
94735 + E_MEMAC_COUNTER_R1519X,
94736 + E_MEMAC_COUNTER_RFRG,
94737 + E_MEMAC_COUNTER_RJBR,
94738 + E_MEMAC_COUNTER_RDRP,
94739 + E_MEMAC_COUNTER_RALN,
94740 + E_MEMAC_COUNTER_TUND,
94741 + E_MEMAC_COUNTER_ROVR,
94742 + E_MEMAC_COUNTER_RXPF,
94743 + E_MEMAC_COUNTER_TXPF,
94744 + E_MEMAC_COUNTER_ROCT,
94745 + E_MEMAC_COUNTER_RMCA,
94746 + E_MEMAC_COUNTER_RBCA,
94747 + E_MEMAC_COUNTER_RPKT,
94748 + E_MEMAC_COUNTER_RUCA,
94749 + E_MEMAC_COUNTER_RERR,
94750 + E_MEMAC_COUNTER_TOCT,
94751 + E_MEMAC_COUNTER_TMCA,
94752 + E_MEMAC_COUNTER_TBCA,
94753 + E_MEMAC_COUNTER_TUCA,
94754 + E_MEMAC_COUNTER_TERR
94755 +};
94756 +
94757 +#define DEFAULT_PAUSE_QUANTA 0xf000
94758 +#define DEFAULT_FRAME_LENGTH 0x600
94759 +#define DEFAULT_TX_IPG_LENGTH 12
94760 +
94761 +/*
94762 + * memory map
94763 + */
94764 +
94765 +struct mac_addr {
94766 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
94767 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
94768 +};
94769 +
94770 +struct memac_regs {
94771 + /* General Control and Status */
94772 + uint32_t res0000[2];
94773 + uint32_t command_config; /* 0x008 Ctrl and cfg */
94774 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
94775 + uint32_t maxfrm; /* 0x014 Max frame length */
94776 + uint32_t res0018[1];
94777 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
94778 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
94779 + uint32_t res0024[2];
94780 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
94781 + uint32_t res0030[4];
94782 + uint32_t ievent; /* 0x040 Interrupt event */
94783 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
94784 + uint32_t res0048;
94785 + uint32_t imask; /* 0x04C Interrupt mask */
94786 + uint32_t res0050;
94787 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
94788 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
94789 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
94790 + uint32_t res0078[2];
94791 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
94792 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
94793 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
94794 + uint32_t res00c0[8];
94795 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
94796 + uint32_t res00e4[7];
94797 + /* Rx Statistics Counter */
94798 + uint32_t reoct_l;
94799 + uint32_t reoct_u;
94800 + uint32_t roct_l;
94801 + uint32_t roct_u;
94802 + uint32_t raln_l;
94803 + uint32_t raln_u;
94804 + uint32_t rxpf_l;
94805 + uint32_t rxpf_u;
94806 + uint32_t rfrm_l;
94807 + uint32_t rfrm_u;
94808 + uint32_t rfcs_l;
94809 + uint32_t rfcs_u;
94810 + uint32_t rvlan_l;
94811 + uint32_t rvlan_u;
94812 + uint32_t rerr_l;
94813 + uint32_t rerr_u;
94814 + uint32_t ruca_l;
94815 + uint32_t ruca_u;
94816 + uint32_t rmca_l;
94817 + uint32_t rmca_u;
94818 + uint32_t rbca_l;
94819 + uint32_t rbca_u;
94820 + uint32_t rdrp_l;
94821 + uint32_t rdrp_u;
94822 + uint32_t rpkt_l;
94823 + uint32_t rpkt_u;
94824 + uint32_t rund_l;
94825 + uint32_t rund_u;
94826 + uint32_t r64_l;
94827 + uint32_t r64_u;
94828 + uint32_t r127_l;
94829 + uint32_t r127_u;
94830 + uint32_t r255_l;
94831 + uint32_t r255_u;
94832 + uint32_t r511_l;
94833 + uint32_t r511_u;
94834 + uint32_t r1023_l;
94835 + uint32_t r1023_u;
94836 + uint32_t r1518_l;
94837 + uint32_t r1518_u;
94838 + uint32_t r1519x_l;
94839 + uint32_t r1519x_u;
94840 + uint32_t rovr_l;
94841 + uint32_t rovr_u;
94842 + uint32_t rjbr_l;
94843 + uint32_t rjbr_u;
94844 + uint32_t rfrg_l;
94845 + uint32_t rfrg_u;
94846 + uint32_t rcnp_l;
94847 + uint32_t rcnp_u;
94848 + uint32_t rdrntp_l;
94849 + uint32_t rdrntp_u;
94850 + uint32_t res01d0[12];
94851 + /* Tx Statistics Counter */
94852 + uint32_t teoct_l;
94853 + uint32_t teoct_u;
94854 + uint32_t toct_l;
94855 + uint32_t toct_u;
94856 + uint32_t res0210[2];
94857 + uint32_t txpf_l;
94858 + uint32_t txpf_u;
94859 + uint32_t tfrm_l;
94860 + uint32_t tfrm_u;
94861 + uint32_t tfcs_l;
94862 + uint32_t tfcs_u;
94863 + uint32_t tvlan_l;
94864 + uint32_t tvlan_u;
94865 + uint32_t terr_l;
94866 + uint32_t terr_u;
94867 + uint32_t tuca_l;
94868 + uint32_t tuca_u;
94869 + uint32_t tmca_l;
94870 + uint32_t tmca_u;
94871 + uint32_t tbca_l;
94872 + uint32_t tbca_u;
94873 + uint32_t res0258[2];
94874 + uint32_t tpkt_l;
94875 + uint32_t tpkt_u;
94876 + uint32_t tund_l;
94877 + uint32_t tund_u;
94878 + uint32_t t64_l;
94879 + uint32_t t64_u;
94880 + uint32_t t127_l;
94881 + uint32_t t127_u;
94882 + uint32_t t255_l;
94883 + uint32_t t255_u;
94884 + uint32_t t511_l;
94885 + uint32_t t511_u;
94886 + uint32_t t1023_l;
94887 + uint32_t t1023_u;
94888 + uint32_t t1518_l;
94889 + uint32_t t1518_u;
94890 + uint32_t t1519x_l;
94891 + uint32_t t1519x_u;
94892 + uint32_t res02a8[6];
94893 + uint32_t tcnp_l;
94894 + uint32_t tcnp_u;
94895 + uint32_t res02c8[14];
94896 + /* Line Interface Control */
94897 + uint32_t if_mode; /* 0x300 Interface Mode Control */
94898 + uint32_t if_status; /* 0x304 Interface Status */
94899 + uint32_t res0308[14];
94900 + /* HiGig/2 */
94901 + uint32_t hg_config; /* 0x340 Control and cfg */
94902 + uint32_t res0344[3];
94903 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
94904 + uint32_t res0354[3];
94905 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
94906 + uint32_t res0364[3];
94907 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
94908 + uint32_t hg_fifos_status; /* 0x374 fifos status */
94909 + uint32_t rhm; /* 0x378 rx messages counter */
94910 + uint32_t thm; /* 0x37C tx messages counter */
94911 +};
94912 +
94913 +struct memac_cfg {
94914 + bool reset_on_init;
94915 + bool rx_error_discard;
94916 + bool pause_ignore;
94917 + bool pause_forward_enable;
94918 + bool no_length_check_enable;
94919 + bool cmd_frame_enable;
94920 + bool send_idle_enable;
94921 + bool wan_mode_enable;
94922 + bool promiscuous_mode_enable;
94923 + bool tx_addr_ins_enable;
94924 + bool loopback_enable;
94925 + bool lgth_check_nostdr;
94926 + bool time_stamp_enable;
94927 + bool pad_enable;
94928 + bool phy_tx_ena_on;
94929 + bool rx_sfd_any;
94930 + bool rx_pbl_fwd;
94931 + bool tx_pbl_fwd;
94932 + bool debug_mode;
94933 + bool wake_on_lan;
94934 + uint16_t max_frame_length;
94935 + uint16_t pause_quanta;
94936 + uint32_t tx_ipg_length;
94937 +};
94938 +
94939 +
94940 +/**
94941 + * fman_memac_defconfig() - Get default MEMAC configuration
94942 + * @cfg: pointer to configuration structure.
94943 + *
94944 + * Call this function to obtain a default set of configuration values for
94945 + * initializing MEMAC. The user can overwrite any of the values before calling
94946 + * fman_memac_init(), if specific configuration needs to be applied.
94947 + */
94948 +void fman_memac_defconfig(struct memac_cfg *cfg);
94949 +
94950 +int fman_memac_init(struct memac_regs *regs,
94951 + struct memac_cfg *cfg,
94952 + enum enet_interface enet_interface,
94953 + enum enet_speed enet_speed,
94954 + bool slow_10g_if,
94955 + uint32_t exceptions);
94956 +
94957 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
94958 +
94959 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
94960 +
94961 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
94962 +
94963 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
94964 + uint8_t *adr,
94965 + uint8_t paddr_num);
94966 +
94967 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
94968 + uint8_t paddr_num);
94969 +
94970 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
94971 + enum memac_counters reg_name);
94972 +
94973 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
94974 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
94975 +
94976 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
94977 +
94978 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
94979 + bool enable);
94980 +
94981 +void fman_memac_reset_stat(struct memac_regs *regs);
94982 +
94983 +void fman_memac_reset(struct memac_regs *regs);
94984 +
94985 +void fman_memac_reset_filter_table(struct memac_regs *regs);
94986 +
94987 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
94988 +
94989 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
94990 +
94991 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
94992 + bool enable);
94993 +
94994 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
94995 +
94996 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
94997 +
94998 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
94999 +
95000 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
95001 +
95002 +void fman_memac_adjust_link(struct memac_regs *regs,
95003 + enum enet_interface iface_mode,
95004 + enum enet_speed speed, bool full_dx);
95005 +
95006 +
95007 +
95008 +#endif /*__FSL_FMAN_MEMAC_H*/
95009 --- /dev/null
95010 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95011 @@ -0,0 +1,78 @@
95012 +/*
95013 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95014 + *
95015 + * Redistribution and use in source and binary forms, with or without
95016 + * modification, are permitted provided that the following conditions are met:
95017 + * * Redistributions of source code must retain the above copyright
95018 + * notice, this list of conditions and the following disclaimer.
95019 + * * Redistributions in binary form must reproduce the above copyright
95020 + * notice, this list of conditions and the following disclaimer in the
95021 + * documentation and/or other materials provided with the distribution.
95022 + * * Neither the name of Freescale Semiconductor nor the
95023 + * names of its contributors may be used to endorse or promote products
95024 + * derived from this software without specific prior written permission.
95025 + *
95026 + *
95027 + * ALTERNATIVELY, this software may be distributed under the terms of the
95028 + * GNU General Public License ("GPL") as published by the Free Software
95029 + * Foundation, either version 2 of that License or (at your option) any
95030 + * later version.
95031 + *
95032 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95033 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95034 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95035 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95036 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95037 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95038 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95039 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95040 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95041 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95042 + */
95043 +
95044 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
95045 +#define __FSL_FMAN_MEMAC_MII_ACC_H
95046 +
95047 +#include "common/general.h"
95048 +#include "fsl_enet.h"
95049 +/* MII Management Registers */
95050 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
95051 +#define MDIO_CFG_CLK_DIV_SHIFT 7
95052 +#define MDIO_CFG_HOLD_MASK 0x0000001c
95053 +#define MDIO_CFG_ENC45 0x00000040
95054 +#define MDIO_CFG_READ_ERR 0x00000002
95055 +#define MDIO_CFG_BSY 0x00000001
95056 +
95057 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
95058 +#define MDIO_CTL_READ 0x00008000
95059 +
95060 +#define MDIO_DATA_BSY 0x80000000
95061 +
95062 +/*MEMAC Internal PHY Registers - SGMII */
95063 +#define PHY_SGMII_CR_PHY_RESET 0x8000
95064 +#define PHY_SGMII_CR_RESET_AN 0x0200
95065 +#define PHY_SGMII_CR_DEF_VAL 0x1140
95066 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
95067 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
95068 +#define PHY_SGMII_IF_MODE_AN 0x0002
95069 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
95070 +#define PHY_SGMII_IF_MODE_1000X 0x0000
95071 +
95072 +/*----------------------------------------------------*/
95073 +/* MII Configuration Control Memory Map Registers */
95074 +/*----------------------------------------------------*/
95075 +struct memac_mii_access_mem_map {
95076 + uint32_t mdio_cfg; /* 0x030 */
95077 + uint32_t mdio_ctrl; /* 0x034 */
95078 + uint32_t mdio_data; /* 0x038 */
95079 + uint32_t mdio_addr; /* 0x03c */
95080 +};
95081 +
95082 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95083 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
95084 + enum enet_speed enet_speed);
95085 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95086 + uint8_t phy_addr, uint8_t reg, uint16_t data,
95087 + enum enet_speed enet_speed);
95088 +
95089 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
95090 --- /dev/null
95091 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95092 @@ -0,0 +1,593 @@
95093 +/*
95094 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95095 + *
95096 + * Redistribution and use in source and binary forms, with or without
95097 + * modification, are permitted provided that the following conditions are met:
95098 + * * Redistributions of source code must retain the above copyright
95099 + * notice, this list of conditions and the following disclaimer.
95100 + * * Redistributions in binary form must reproduce the above copyright
95101 + * notice, this list of conditions and the following disclaimer in the
95102 + * documentation and/or other materials provided with the distribution.
95103 + * * Neither the name of Freescale Semiconductor nor the
95104 + * names of its contributors may be used to endorse or promote products
95105 + * derived from this software without specific prior written permission.
95106 + *
95107 + *
95108 + * ALTERNATIVELY, this software may be distributed under the terms of the
95109 + * GNU General Public License ("GPL") as published by the Free Software
95110 + * Foundation, either version 2 of that License or (at your option) any
95111 + * later version.
95112 + *
95113 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95114 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95115 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95116 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95117 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95118 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95119 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95120 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95121 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95122 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95123 + */
95124 +
95125 +#ifndef __FSL_FMAN_PORT_H
95126 +#define __FSL_FMAN_PORT_H
95127 +
95128 +#include "fsl_fman_sp.h"
95129 +
95130 +/** @Collection Registers bit fields */
95131 +
95132 +/** @Description BMI defines */
95133 +#define BMI_EBD_EN 0x80000000
95134 +
95135 +#define BMI_PORT_CFG_EN 0x80000000
95136 +#define BMI_PORT_CFG_FDOVR 0x02000000
95137 +#define BMI_PORT_CFG_IM 0x01000000
95138 +
95139 +#define BMI_PORT_STATUS_BSY 0x80000000
95140 +
95141 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
95142 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
95143 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
95144 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
95145 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
95146 +
95147 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
95148 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
95149 +
95150 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
95151 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
95152 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
95153 +
95154 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
95155 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
95156 +
95157 +#define BMI_INT_BUF_MARG_SHIFT 28
95158 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
95159 +
95160 +#define BMI_CMD_MR_LEAC 0x00200000
95161 +#define BMI_CMD_MR_SLEAC 0x00100000
95162 +#define BMI_CMD_MR_MA 0x00080000
95163 +#define BMI_CMD_MR_DEAS 0x00040000
95164 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
95165 + BMI_CMD_MR_SLEAC | \
95166 + BMI_CMD_MR_MA | \
95167 + BMI_CMD_MR_DEAS)
95168 +#define BMI_CMD_TX_MR_DEF 0
95169 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
95170 + BMI_CMD_MR_MA)
95171 +
95172 +#define BMI_CMD_ATTR_ORDER 0x80000000
95173 +#define BMI_CMD_ATTR_SYNC 0x02000000
95174 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
95175 +
95176 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
95177 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
95178 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
95179 +
95180 +#define BMI_COUNTERS_EN 0x80000000
95181 +
95182 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
95183 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
95184 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
95185 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
95186 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
95187 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
95188 +
95189 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
95190 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
95191 +
95192 +#define MAX_PERFORMANCE_TASK_COMP 64
95193 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
95194 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
95195 +#define MAX_PERFORMANCE_DMA_COMP 16
95196 +#define MAX_PERFORMANCE_FIFO_COMP 1024
95197 +
95198 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
95199 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
95200 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
95201 +
95202 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
95203 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
95204 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
95205 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
95206 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
95207 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
95208 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
95209 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
95210 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
95211 +
95212 +/** @Description QMI defines */
95213 +#define QMI_PORT_CFG_EN 0x80000000
95214 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
95215 +
95216 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
95217 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
95218 +
95219 +#define QMI_DEQ_CFG_PRI 0x80000000
95220 +#define QMI_DEQ_CFG_TYPE1 0x10000000
95221 +#define QMI_DEQ_CFG_TYPE2 0x20000000
95222 +#define QMI_DEQ_CFG_TYPE3 0x30000000
95223 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
95224 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
95225 +#define QMI_DEQ_CFG_SP_MASK 0xf
95226 +#define QMI_DEQ_CFG_SP_SHIFT 20
95227 +
95228 +
95229 +/** @Description General port defines */
95230 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
95231 + (((fm_rev_maj) == 4) ? 4 : 8)
95232 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
95233 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
95234 +#define FMAN_PORT_CG_MAP_NUM 8
95235 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
95236 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
95237 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
95238 +
95239 +
95240 +/** @Collection FM Port Register Map */
95241 +
95242 +/** @Description BMI Rx port register map */
95243 +struct fman_port_rx_bmi_regs {
95244 + uint32_t fmbm_rcfg; /**< Rx Configuration */
95245 + uint32_t fmbm_rst; /**< Rx Status */
95246 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
95247 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
95248 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
95249 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
95250 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
95251 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
95252 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
95253 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
95254 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
95255 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
95256 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
95257 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
95258 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
95259 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
95260 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95261 + /**< Rx Parse Results Array Init*/
95262 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
95263 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
95264 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
95265 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
95266 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
95267 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
95268 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
95269 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
95270 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
95271 + /**< Buffer Manager pool Information-*/
95272 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
95273 + /**< Allocate Counter-*/
95274 + uint32_t reserved0130[8];
95275 + /**< 0x130/0x140 - 0x15F reserved -*/
95276 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
95277 + /**< Congestion Group Map*/
95278 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
95279 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
95280 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
95281 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
95282 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
95283 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
95284 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
95285 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
95286 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
95287 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
95288 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
95289 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
95290 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
95291 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
95292 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
95293 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
95294 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
95295 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
95296 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
95297 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
95298 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
95299 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
95300 +};
95301 +
95302 +/** @Description BMI Tx port register map */
95303 +struct fman_port_tx_bmi_regs {
95304 + uint32_t fmbm_tcfg; /**< Tx Configuration */
95305 + uint32_t fmbm_tst; /**< Tx Status */
95306 + uint32_t fmbm_tda; /**< Tx DMA attributes */
95307 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
95308 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
95309 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
95310 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
95311 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
95312 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
95313 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
95314 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
95315 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
95316 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
95317 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
95318 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
95319 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
95320 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
95321 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
95322 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
95323 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
95324 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
95325 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
95326 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
95327 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
95328 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
95329 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
95330 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
95331 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
95332 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
95333 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
95334 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
95335 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
95336 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
95337 +};
95338 +
95339 +/** @Description BMI O/H port register map */
95340 +struct fman_port_oh_bmi_regs {
95341 + uint32_t fmbm_ocfg; /**< O/H Configuration */
95342 + uint32_t fmbm_ost; /**< O/H Status */
95343 + uint32_t fmbm_oda; /**< O/H DMA attributes */
95344 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
95345 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
95346 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
95347 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
95348 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
95349 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
95350 + uint32_t fmbm_opp; /**< O/H Policer Profile */
95351 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
95352 + uint32_t fmbm_oim; /**< O/H Internal margins*/
95353 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
95354 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
95355 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
95356 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95357 + /**< O/H Parse Results Array Initialization */
95358 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
95359 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
95360 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
95361 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
95362 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
95363 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
95364 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
95365 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
95366 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
95367 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
95368 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
95369 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
95370 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
95371 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
95372 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
95373 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
95374 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
95375 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
95376 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
95377 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
95378 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
95379 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
95380 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
95381 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
95382 + uint32_t fmbm_opc; /**< O/H Performance Counters */
95383 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
95384 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
95385 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
95386 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
95387 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
95388 +};
95389 +
95390 +/** @Description BMI port register map */
95391 +union fman_port_bmi_regs {
95392 + struct fman_port_rx_bmi_regs rx;
95393 + struct fman_port_tx_bmi_regs tx;
95394 + struct fman_port_oh_bmi_regs oh;
95395 +};
95396 +
95397 +/** @Description QMI port register map */
95398 +struct fman_port_qmi_regs {
95399 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
95400 + uint32_t fmqm_pns; /**< PortID n Status Register */
95401 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
95402 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
95403 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
95404 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
95405 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
95406 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
95407 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
95408 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
95409 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
95410 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
95411 +};
95412 +
95413 +
95414 +enum fman_port_dma_swap {
95415 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
95416 + E_FMAN_PORT_DMA_SWAP_LE,
95417 + /**< The transferred data should be swapped in PPC Little Endian mode */
95418 + E_FMAN_PORT_DMA_SWAP_BE
95419 + /**< The transferred data should be swapped in Big Endian mode */
95420 +};
95421 +
95422 +/* Default port color */
95423 +enum fman_port_color {
95424 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
95425 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
95426 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
95427 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
95428 +};
95429 +
95430 +/* QMI dequeue from the SP channel - types */
95431 +enum fman_port_deq_type {
95432 + E_FMAN_PORT_DEQ_BY_PRI,
95433 + /**< Priority precedence and Intra-Class scheduling */
95434 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
95435 + /**< Active FQ precedence and Intra-Class scheduling */
95436 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
95437 + /**< Active FQ precedence and override Intra-Class scheduling */
95438 +};
95439 +
95440 +/* QMI dequeue prefetch modes */
95441 +enum fman_port_deq_prefetch {
95442 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
95443 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
95444 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
95445 +};
95446 +
95447 +/* Parameters for defining performance counters behavior */
95448 +struct fman_port_perf_cnt_params {
95449 + uint8_t task_val; /**< Task compare value */
95450 + uint8_t queue_val;
95451 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
95452 + uint8_t dma_val; /**< Dma compare value */
95453 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
95454 +};
95455 +
95456 +/** @Description FM Port configuration structure, used at init */
95457 +struct fman_port_cfg {
95458 + struct fman_port_perf_cnt_params perf_cnt_params;
95459 + /* BMI parameters */
95460 + enum fman_port_dma_swap dma_swap_data;
95461 + bool dma_ic_stash_on;
95462 + bool dma_header_stash_on;
95463 + bool dma_sg_stash_on;
95464 + bool dma_write_optimize;
95465 + uint16_t ic_ext_offset;
95466 + uint8_t ic_int_offset;
95467 + uint16_t ic_size;
95468 + enum fman_port_color color;
95469 + bool sync_req;
95470 + bool discard_override;
95471 + uint8_t checksum_bytes_ignore;
95472 + uint8_t rx_cut_end_bytes;
95473 + uint32_t rx_pri_elevation;
95474 + uint32_t rx_fifo_thr;
95475 + uint8_t rx_fd_bits;
95476 + uint8_t int_buf_start_margin;
95477 + uint16_t ext_buf_start_margin;
95478 + uint16_t ext_buf_end_margin;
95479 + uint32_t tx_fifo_min_level;
95480 + uint32_t tx_fifo_low_comf_level;
95481 + uint8_t tx_fifo_deq_pipeline_depth;
95482 + bool stats_counters_enable;
95483 + bool perf_counters_enable;
95484 + /* QMI parameters */
95485 + bool deq_high_pri;
95486 + enum fman_port_deq_type deq_type;
95487 + enum fman_port_deq_prefetch deq_prefetch_opt;
95488 + uint16_t deq_byte_cnt;
95489 + bool queue_counters_enable;
95490 + bool no_scatter_gather;
95491 + int errata_A006675;
95492 + int errata_A006320;
95493 + int excessive_threshold_register;
95494 + int fmbm_rebm_has_sgd;
95495 + int fmbm_tfne_has_features;
95496 + int qmi_deq_options_support;
95497 +};
95498 +
95499 +enum fman_port_type {
95500 + E_FMAN_PORT_TYPE_OP = 0,
95501 + /**< Offline parsing port, shares id-s with
95502 + * host command, so must have exclusive id-s */
95503 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
95504 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
95505 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
95506 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
95507 + E_FMAN_PORT_TYPE_DUMMY,
95508 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
95509 + /**< Host command port, shares id-s with
95510 + * offline parsing ports, so must have exclusive id-s */
95511 +};
95512 +
95513 +struct fman_port_params {
95514 + uint32_t discard_mask;
95515 + uint32_t err_mask;
95516 + uint32_t dflt_fqid;
95517 + uint32_t err_fqid;
95518 + uint8_t deq_sp;
95519 + bool dont_release_buf;
95520 +};
95521 +
95522 +/* Port context - used by most API functions */
95523 +struct fman_port {
95524 + enum fman_port_type type;
95525 + uint8_t fm_rev_maj;
95526 + uint8_t fm_rev_min;
95527 + union fman_port_bmi_regs *bmi_regs;
95528 + struct fman_port_qmi_regs *qmi_regs;
95529 + bool im_en;
95530 + uint8_t ext_pools_num;
95531 +};
95532 +
95533 +/** @Description External buffer pools configuration */
95534 +struct fman_port_bpools {
95535 + uint8_t count; /**< Num of pools to set up */
95536 + bool counters_enable; /**< Enable allocate counters */
95537 + uint8_t grp_bp_depleted_num;
95538 + /**< Number of depleted pools - if reached the BMI indicates
95539 + * the MAC to send a pause frame */
95540 + struct {
95541 + uint8_t bpid; /**< BM pool ID */
95542 + uint16_t size;
95543 + /**< Pool's size - must be in ascending order */
95544 + bool is_backup;
95545 + /**< If this is a backup pool */
95546 + bool grp_bp_depleted;
95547 + /**< Consider this buffer in multiple pools depletion criteria*/
95548 + bool single_bp_depleted;
95549 + /**< Consider this buffer in single pool depletion criteria */
95550 + bool pfc_priorities_en;
95551 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
95552 +};
95553 +
95554 +enum fman_port_rate_limiter_scale_down {
95555 + E_FMAN_PORT_RATE_DOWN_NONE,
95556 + E_FMAN_PORT_RATE_DOWN_BY_2,
95557 + E_FMAN_PORT_RATE_DOWN_BY_4,
95558 + E_FMAN_PORT_RATE_DOWN_BY_8
95559 +};
95560 +
95561 +/* Rate limiter configuration */
95562 +struct fman_port_rate_limiter {
95563 + uint8_t count_1micro_bit;
95564 + bool high_burst_size_gran;
95565 + /**< Defines burst_size granularity for OP ports; when TRUE,
95566 + * burst_size below counts in frames, otherwise in 10^3 frames */
95567 + uint16_t burst_size;
95568 + /**< Max burst size, in KBytes for Tx port, according to
95569 + * high_burst_size_gran definition for OP port */
95570 + uint32_t rate;
95571 + /**< In Kbps for Tx port, in frames/sec for OP port */
95572 + enum fman_port_rate_limiter_scale_down rate_factor;
95573 +};
95574 +
95575 +/* BMI statistics counters */
95576 +enum fman_port_stats_counters {
95577 + E_FMAN_PORT_STATS_CNT_FRAME,
95578 + /**< Number of processed frames; valid for all ports */
95579 + E_FMAN_PORT_STATS_CNT_DISCARD,
95580 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
95581 + * frames discarded due to DMA error; valid for all ports */
95582 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
95583 + /**< Number of buffer deallocate operations; valid for all ports */
95584 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
95585 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
95586 + * valid for Rx ports only */
95587 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
95588 + /**< Number of Rx oversized frames, that is frames exceeding max frame
95589 + * size configured for the corresponding ETH controller;
95590 + * valid for Rx ports only */
95591 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
95592 + /**< Frames discarded due to lack of external buffers; valid for
95593 + * Rx ports only */
95594 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
95595 + /**< Frames discarded due to frame length error; valid for Tx and
95596 + * O/H ports only */
95597 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
95598 + /**< Frames discarded due to unsupported FD format; valid for Tx
95599 + * and O/H ports only */
95600 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
95601 + /**< Number of frames filtered out by PCD module; valid for
95602 + * Rx and OP ports only */
95603 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
95604 + /**< Frames rejected by QMAN that were not able to release their
95605 + * buffers due to DMA error; valid for Rx and O/H ports only */
95606 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
95607 + /**< Frames going through O/H port that were not able to to enter the
95608 + * return queue due to WRED algorithm; valid for O/H ports only */
95609 +};
95610 +
95611 +/* BMI performance counters */
95612 +enum fman_port_perf_counters {
95613 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
95614 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
95615 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
95616 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
95617 + * utilization; not valid for O/H ports */
95618 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
95619 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
95620 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
95621 + /**< Number of cycles in which Rx pause activation control is on;
95622 + * valid for Rx ports only */
95623 +};
95624 +
95625 +/* QMI counters */
95626 +enum fman_port_qmi_counters {
95627 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
95628 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
95629 + E_FMAN_PORT_DEQ_FROM_DFLT,
95630 + /**< Dequeue from default FQID counter not valid for Rx ports */
95631 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
95632 +};
95633 +
95634 +
95635 +/** @Collection FM Port API */
95636 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
95637 +int fman_port_init(struct fman_port *port,
95638 + struct fman_port_cfg *cfg,
95639 + struct fman_port_params *params);
95640 +int fman_port_enable(struct fman_port *port);
95641 +int fman_port_disable(const struct fman_port *port);
95642 +int fman_port_set_bpools(const struct fman_port *port,
95643 + const struct fman_port_bpools *bp);
95644 +int fman_port_set_rate_limiter(struct fman_port *port,
95645 + struct fman_port_rate_limiter *rate_limiter);
95646 +int fman_port_delete_rate_limiter(struct fman_port *port);
95647 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
95648 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
95649 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
95650 + uint8_t rx_fd_bits,
95651 + bool add);
95652 +int fman_port_set_perf_cnt_params(struct fman_port *port,
95653 + struct fman_port_perf_cnt_params *params);
95654 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
95655 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
95656 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
95657 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
95658 + uint8_t bpid,
95659 + bool enable);
95660 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
95661 + enum fman_port_stats_counters counter);
95662 +void fman_port_set_stats_counter(struct fman_port *port,
95663 + enum fman_port_stats_counters counter,
95664 + uint32_t value);
95665 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
95666 + enum fman_port_perf_counters counter);
95667 +void fman_port_set_perf_counter(struct fman_port *port,
95668 + enum fman_port_perf_counters counter,
95669 + uint32_t value);
95670 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
95671 + enum fman_port_qmi_counters counter);
95672 +void fman_port_set_qmi_counter(struct fman_port *port,
95673 + enum fman_port_qmi_counters counter,
95674 + uint32_t value);
95675 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
95676 +void fman_port_set_bpool_counter(struct fman_port *port,
95677 + uint8_t bpid,
95678 + uint32_t value);
95679 +int fman_port_add_congestion_grps(struct fman_port *port,
95680 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
95681 +int fman_port_remove_congestion_grps(struct fman_port *port,
95682 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
95683 +
95684 +
95685 +#endif /* __FSL_FMAN_PORT_H */
95686 --- /dev/null
95687 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
95688 @@ -0,0 +1,102 @@
95689 +/*
95690 + * Copyright 2008-2012 Freescale Semiconductor Inc.
95691 + *
95692 + * Redistribution and use in source and binary forms, with or without
95693 + * modification, are permitted provided that the following conditions are met:
95694 + * * Redistributions of source code must retain the above copyright
95695 + * notice, this list of conditions and the following disclaimer.
95696 + * * Redistributions in binary form must reproduce the above copyright
95697 + * notice, this list of conditions and the following disclaimer in the
95698 + * documentation and/or other materials provided with the distribution.
95699 + * * Neither the name of Freescale Semiconductor nor the
95700 + * names of its contributors may be used to endorse or promote products
95701 + * derived from this software without specific prior written permission.
95702 + *
95703 + *
95704 + * ALTERNATIVELY, this software may be distributed under the terms of the
95705 + * GNU General Public License ("GPL") as published by the Free Software
95706 + * Foundation, either version 2 of that License or (at your option) any
95707 + * later version.
95708 + *
95709 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95710 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95711 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95712 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95713 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95714 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95715 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95716 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95717 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95718 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95719 + */
95720 +
95721 +#ifndef __FSL_FMAN_PRS_H
95722 +#define __FSL_FMAN_PRS_H
95723 +
95724 +#include "common/general.h"
95725 +
95726 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
95727 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
95728 +
95729 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
95730 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
95731 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
95732 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
95733 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
95734 +#define PRS_MAX_CYCLE_LIMIT 8191
95735 +
95736 +#define DEFAULT_MAX_PRS_CYC_LIM 0
95737 +
95738 +struct fman_prs_regs {
95739 + uint32_t fmpr_rpclim;
95740 + uint32_t fmpr_rpimac;
95741 + uint32_t pmeec;
95742 + uint32_t res00c[5];
95743 + uint32_t fmpr_pevr;
95744 + uint32_t fmpr_pever;
95745 + uint32_t res028;
95746 + uint32_t fmpr_perr;
95747 + uint32_t fmpr_perer;
95748 + uint32_t res034;
95749 + uint32_t res038[10];
95750 + uint32_t fmpr_ppsc;
95751 + uint32_t res064;
95752 + uint32_t fmpr_pds;
95753 + uint32_t fmpr_l2rrs;
95754 + uint32_t fmpr_l3rrs;
95755 + uint32_t fmpr_l4rrs;
95756 + uint32_t fmpr_srrs;
95757 + uint32_t fmpr_l2rres;
95758 + uint32_t fmpr_l3rres;
95759 + uint32_t fmpr_l4rres;
95760 + uint32_t fmpr_srres;
95761 + uint32_t fmpr_spcs;
95762 + uint32_t fmpr_spscs;
95763 + uint32_t fmpr_hxscs;
95764 + uint32_t fmpr_mrcs;
95765 + uint32_t fmpr_mwcs;
95766 + uint32_t fmpr_mrscs;
95767 + uint32_t fmpr_mwscs;
95768 + uint32_t fmpr_fcscs;
95769 +};
95770 +
95771 +struct fman_prs_cfg {
95772 + uint32_t port_id_stat;
95773 + uint16_t max_prs_cyc_lim;
95774 + uint32_t prs_exceptions;
95775 +};
95776 +
95777 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
95778 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
95779 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
95780 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
95781 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
95782 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
95783 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
95784 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
95785 +void fman_prs_enable(struct fman_prs_regs *regs);
95786 +void fman_prs_disable(struct fman_prs_regs *regs);
95787 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
95788 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
95789 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
95790 +#endif /* __FSL_FMAN_PRS_H */
95791 --- /dev/null
95792 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
95793 @@ -0,0 +1,449 @@
95794 +/*
95795 + * Copyright 2013 Freescale Semiconductor Inc.
95796 + *
95797 + * Redistribution and use in source and binary forms, with or without
95798 + * modification, are permitted provided that the following conditions are met:
95799 + * * Redistributions of source code must retain the above copyright
95800 + * notice, this list of conditions and the following disclaimer.
95801 + * * Redistributions in binary form must reproduce the above copyright
95802 + * notice, this list of conditions and the following disclaimer in the
95803 + * documentation and/or other materials provided with the distribution.
95804 + * * Neither the name of Freescale Semiconductor nor the
95805 + * names of its contributors may be used to endorse or promote products
95806 + * derived from this software without specific prior written permission.
95807 + *
95808 + *
95809 + * ALTERNATIVELY, this software may be distributed under the terms of the
95810 + * GNU General Public License ("GPL") as published by the Free Software
95811 + * Foundation, either version 2 of that License or (at your option) any
95812 + * later version.
95813 + *
95814 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95815 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95816 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95817 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95818 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95819 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95820 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95821 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95822 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95823 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95824 + */
95825 +
95826 +#ifndef __FSL_FMAN_RTC_H
95827 +#define __FSL_FMAN_RTC_H
95828 +
95829 +#include "common/general.h"
95830 +
95831 +/* FM RTC Registers definitions */
95832 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
95833 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
95834 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
95835 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
95836 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
95837 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
95838 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
95839 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
95840 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
95841 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
95842 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
95843 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
95844 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
95845 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
95846 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
95847 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
95848 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
95849 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
95850 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
95851 +
95852 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
95853 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
95854 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
95855 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
95856 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
95857 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
95858 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
95859 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
95860 + FMAN_RTC_TMR_TEVENT_ETS1 |\
95861 + FMAN_RTC_TMR_TEVENT_ALM2 |\
95862 + FMAN_RTC_TMR_TEVENT_ALM1 |\
95863 + FMAN_RTC_TMR_TEVENT_PP1 |\
95864 + FMAN_RTC_TMR_TEVENT_PP2 |\
95865 + FMAN_RTC_TMR_TEVENT_PP3)
95866 +
95867 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
95868 +
95869 +/**************************************************************************//**
95870 + @Description FM RTC Alarm Polarity Options.
95871 +*//***************************************************************************/
95872 +enum fman_rtc_alarm_polarity {
95873 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
95874 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
95875 +};
95876 +
95877 +/**************************************************************************//**
95878 + @Description FM RTC Trigger Polarity Options.
95879 +*//***************************************************************************/
95880 +enum fman_rtc_trigger_polarity {
95881 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
95882 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
95883 +};
95884 +
95885 +/**************************************************************************//**
95886 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
95887 +*//***************************************************************************/
95888 +enum fman_src_clock {
95889 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
95890 + reference clock */
95891 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
95892 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
95893 +};
95894 +
95895 +/* RTC default values */
95896 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
95897 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
95898 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
95899 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
95900 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
95901 +#define DEFAULT_PULSE_REALIGN FALSE
95902 +
95903 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
95904 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
95905 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
95906 +
95907 +/**************************************************************************//**
95908 + @Description FM RTC timer alarm
95909 +*//***************************************************************************/
95910 +struct t_tmr_alarm{
95911 + uint32_t tmr_alarm_h; /**< */
95912 + uint32_t tmr_alarm_l; /**< */
95913 +};
95914 +
95915 +/**************************************************************************//**
95916 + @Description FM RTC timer Ex trigger
95917 +*//***************************************************************************/
95918 +struct t_tmr_ext_trigger{
95919 + uint32_t tmr_etts_h; /**< */
95920 + uint32_t tmr_etts_l; /**< */
95921 +};
95922 +
95923 +struct rtc_regs {
95924 + uint32_t tmr_id; /* 0x000 Module ID register */
95925 + uint32_t tmr_id2; /* 0x004 Controller ID register */
95926 + uint32_t reserved0008[30];
95927 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
95928 + uint32_t tmr_tevent; /* 0x0084 timer event register */
95929 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
95930 + uint32_t reserved008c[3];
95931 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
95932 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
95933 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
95934 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
95935 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
95936 + uint32_t reserved00ac;
95937 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
95938 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
95939 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
95940 + alarm */
95941 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
95942 + fixed period interval */
95943 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
95944 + /* 0x00e0 time stamp general purpose external */
95945 + uint32_t reserved00f0[4];
95946 +};
95947 +
95948 +struct rtc_cfg {
95949 + enum fman_src_clock src_clk;
95950 + uint32_t ext_src_clk_freq;
95951 + uint32_t rtc_freq_hz;
95952 + bool timer_slave_mode;
95953 + bool invert_input_clk_phase;
95954 + bool invert_output_clk_phase;
95955 + uint32_t events_mask;
95956 + bool bypass; /**< Indicates if frequency compensation
95957 + is bypassed */
95958 + bool pulse_realign;
95959 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
95960 + enum fman_rtc_trigger_polarity trigger_polarity
95961 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
95962 +};
95963 +
95964 +/**
95965 + * fman_rtc_defconfig() - Get default RTC configuration
95966 + * @cfg: pointer to configuration structure.
95967 + *
95968 + * Call this function to obtain a default set of configuration values for
95969 + * initializing RTC. The user can overwrite any of the values before calling
95970 + * fman_rtc_init(), if specific configuration needs to be applied.
95971 + */
95972 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
95973 +
95974 +/**
95975 + * fman_rtc_get_events() - Get the events
95976 + * @regs: Pointer to RTC register block
95977 + *
95978 + * Returns: The events
95979 + */
95980 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
95981 +
95982 +/**
95983 + * fman_rtc_get_interrupt_mask() - Get the events mask
95984 + * @regs: Pointer to RTC register block
95985 + *
95986 + * Returns: The events mask
95987 + */
95988 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
95989 +
95990 +
95991 +/**
95992 + * fman_rtc_set_interrupt_mask() - Set the events mask
95993 + * @regs: Pointer to RTC register block
95994 + * @mask: The mask to set
95995 + */
95996 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
95997 +
95998 +/**
95999 + * fman_rtc_get_event() - Check if specific events occurred
96000 + * @regs: Pointer to RTC register block
96001 + * @ev_mask: a mask of the events to check
96002 + *
96003 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
96004 + */
96005 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
96006 +
96007 +/**
96008 + * fman_rtc_check_and_clear_event() - Clear events which are on
96009 + * @regs: Pointer to RTC register block
96010 + *
96011 + * Returns: A mask of the events which were cleared
96012 + */
96013 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
96014 +
96015 +/**
96016 + * fman_rtc_ack_event() - Clear events
96017 + * @regs: Pointer to RTC register block
96018 + * @events: The events to disable
96019 + */
96020 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
96021 +
96022 +/**
96023 + * fman_rtc_enable_interupt() - Enable events interrupts
96024 + * @regs: Pointer to RTC register block
96025 + * @mask: The events to disable
96026 + */
96027 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
96028 +
96029 +/**
96030 + * fman_rtc_disable_interupt() - Disable events interrupts
96031 + * @regs: Pointer to RTC register block
96032 + * @mask: The events to disable
96033 + */
96034 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
96035 +
96036 +/**
96037 + * fman_rtc_get_timer_ctrl() - Get the control register
96038 + * @regs: Pointer to RTC register block
96039 + *
96040 + * Returns: The control register value
96041 + */
96042 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
96043 +
96044 +/**
96045 + * fman_rtc_set_timer_ctrl() - Set timer control register
96046 + * @regs: Pointer to RTC register block
96047 + * @val: The value to set
96048 + */
96049 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
96050 +
96051 +/**
96052 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
96053 + * @regs: Pointer to RTC register block
96054 + *
96055 + * Returns: The timer counter
96056 + */
96057 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
96058 +
96059 +/**
96060 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
96061 + * @regs: Pointer to RTC register block
96062 + * @val: The value to set
96063 + */
96064 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
96065 +
96066 +/**
96067 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
96068 + * @regs: Pointer to RTC register block
96069 + * @id: The id of the trigger stamp
96070 + *
96071 + * Returns: The time stamp
96072 + */
96073 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
96074 +
96075 +/**
96076 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
96077 + * @regs: Pointer to RTC register block
96078 + * @index: The index of alarm to set
96079 + * @val: The value to set
96080 + */
96081 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
96082 + uint32_t val);
96083 +
96084 +/**
96085 + * fman_rtc_set_timer_alarm() - Set timer alarm
96086 + * @regs: Pointer to RTC register block
96087 + * @index: The index of alarm to set
96088 + * @val: The value to set
96089 + */
96090 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
96091 +
96092 +/**
96093 + * fman_rtc_set_timer_fiper() - Set timer fiper
96094 + * @regs: Pointer to RTC register block
96095 + * @index: The index of fiper to set
96096 + * @val: The value to set
96097 + */
96098 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
96099 +
96100 +/**
96101 + * fman_rtc_set_timer_offset() - Set timer offset
96102 + * @regs: Pointer to RTC register block
96103 + * @val: The value to set
96104 + */
96105 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
96106 +
96107 +/**
96108 + * fman_rtc_get_timer() - Get the timer counter
96109 + * @regs: Pointer to RTC register block
96110 + *
96111 + * Returns: The timer counter
96112 + */
96113 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
96114 +{
96115 + uint64_t time;
96116 + /* TMR_CNT_L must be read first to get an accurate value */
96117 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
96118 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
96119 +
96120 + return time;
96121 +}
96122 +
96123 +/**
96124 + * fman_rtc_set_timer() - Set timer counter
96125 + * @regs: Pointer to RTC register block
96126 + * @val: The value to set
96127 + */
96128 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
96129 +{
96130 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
96131 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
96132 +}
96133 +
96134 +/**
96135 + * fman_rtc_timers_soft_reset() - Soft reset
96136 + * @regs: Pointer to RTC register block
96137 + *
96138 + * Resets all the timer registers and state machines for the 1588 IP and
96139 + * the attached client 1588
96140 + */
96141 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
96142 +
96143 +/**
96144 + * fman_rtc_clear_external_trigger() - Clear an external trigger
96145 + * @regs: Pointer to RTC register block
96146 + * @id: The id of the trigger to clear
96147 + */
96148 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
96149 +
96150 +/**
96151 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
96152 + * @regs: Pointer to RTC register block
96153 + * @id: The id of the fiper to clear
96154 + */
96155 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
96156 +
96157 +/**
96158 + * fman_rtc_enable() - Enable RTC hardware block
96159 + * @regs: Pointer to RTC register block
96160 + */
96161 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
96162 +
96163 +/**
96164 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
96165 + * @regs: Pointer to RTC register block
96166 + *
96167 + * Return: TRUE if enabled
96168 + */
96169 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
96170 +
96171 +/**
96172 + * fman_rtc_disable() - Disable RTC hardware block
96173 + * @regs: Pointer to RTC register block
96174 + */
96175 +void fman_rtc_disable(struct rtc_regs *regs);
96176 +
96177 +/**
96178 + * fman_rtc_init() - Init RTC hardware block
96179 + * @cfg: RTC configuration data
96180 + * @regs: Pointer to RTC register block
96181 + * @num_alarms: Number of alarms in RTC
96182 + * @num_fipers: Number of fipers in RTC
96183 + * @num_ext_triggers: Number of external triggers in RTC
96184 + * @freq_compensation: Frequency compensation
96185 + * @output_clock_divisor: Output clock divisor
96186 + *
96187 + * This function initializes RTC and applies basic configuration.
96188 + */
96189 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
96190 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
96191 + uint32_t freq_compensation, uint32_t output_clock_divisor);
96192 +
96193 +/**
96194 + * fman_rtc_set_alarm() - Set an alarm
96195 + * @regs: Pointer to RTC register block
96196 + * @id: id of alarm
96197 + * @val: value to write
96198 + * @enable: should interrupt be enabled
96199 + */
96200 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
96201 +
96202 +/**
96203 + * fman_rtc_set_periodic_pulse() - Set an alarm
96204 + * @regs: Pointer to RTC register block
96205 + * @id: id of fiper
96206 + * @val: value to write
96207 + * @enable: should interrupt be enabled
96208 + */
96209 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
96210 + bool enable);
96211 +
96212 +/**
96213 + * fman_rtc_set_ext_trigger() - Set an external trigger
96214 + * @regs: Pointer to RTC register block
96215 + * @id: id of trigger
96216 + * @enable: should interrupt be enabled
96217 + * @use_pulse_as_input: use the pulse as input
96218 + */
96219 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
96220 + bool use_pulse_as_input);
96221 +
96222 +struct fm_rtc_alarm_params {
96223 + uint8_t alarm_id; /**< 0 or 1 */
96224 + uint64_t alarm_time; /**< In nanoseconds, the time when the
96225 + alarm should go off - must be a
96226 + multiple of the RTC period */
96227 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
96228 + be called when RTC reaches alarmTime */
96229 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
96230 + expired.*/
96231 +};
96232 +
96233 +struct fm_rtc_periodic_pulse_params {
96234 + uint8_t periodic_pulse_id; /**< 0 or 1 */
96235 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
96236 + of the RTC period */
96237 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
96238 + routine will be called every
96239 + periodicPulsePeriod. */
96240 +};
96241 +
96242 +#endif /* __FSL_FMAN_RTC_H */
96243 --- /dev/null
96244 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96245 @@ -0,0 +1,138 @@
96246 +/*
96247 + * Copyright 2013 Freescale Semiconductor Inc.
96248 + *
96249 + * Redistribution and use in source and binary forms, with or without
96250 + * modification, are permitted provided that the following conditions are met:
96251 + * * Redistributions of source code must retain the above copyright
96252 + * notice, this list of conditions and the following disclaimer.
96253 + * * Redistributions in binary form must reproduce the above copyright
96254 + * notice, this list of conditions and the following disclaimer in the
96255 + * documentation and/or other materials provided with the distribution.
96256 + * * Neither the name of Freescale Semiconductor nor the
96257 + * names of its contributors may be used to endorse or promote products
96258 + * derived from this software without specific prior written permission.
96259 + *
96260 + *
96261 + * ALTERNATIVELY, this software may be distributed under the terms of the
96262 + * GNU General Public License ("GPL") as published by the Free Software
96263 + * Foundation, either version 2 of that License or (at your option) any
96264 + * later version.
96265 + *
96266 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96267 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96268 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96269 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96270 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96271 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96272 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96273 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96274 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96275 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96276 + */
96277 +
96278 +#ifndef __FSL_FMAN_SP_H
96279 +#define __FSL_FMAN_SP_H
96280 +
96281 +#include "common/general.h"
96282 +#include "fsl_fman.h"
96283 +
96284 +
96285 +struct fm_pcd_storage_profile_regs{
96286 + uint32_t fm_sp_ebmpi[8];
96287 + /*offset 0 - 0xc*/
96288 + /**< Buffer Manager pool Information */
96289 +
96290 + uint32_t fm_sp_acnt; /*offset 0x20*/
96291 + uint32_t fm_sp_ebm; /*offset 0x24*/
96292 + uint32_t fm_sp_da; /*offset 0x28*/
96293 + uint32_t fm_sp_icp; /*offset 0x2c*/
96294 + uint32_t fm_sp_mpd; /*offset 0x30*/
96295 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
96296 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
96297 +};
96298 +
96299 +/**************************************************************************//**
96300 + @Description structure for defining internal context copying
96301 +*//***************************************************************************/
96302 +struct fman_sp_int_context_data_copy{
96303 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
96304 + internal context is copied to (Rx)
96305 + or taken from (Tx, Op). */
96306 + uint8_t int_context_offset; /**< Offset within internal context to copy
96307 + from (Rx) or to copy to (Tx, Op).*/
96308 + uint16_t size; /**< Internal offset size to be copied */
96309 +};
96310 +
96311 +/**************************************************************************//**
96312 + @Description struct for defining external buffer margins
96313 +*//***************************************************************************/
96314 +struct fman_sp_buf_margins{
96315 + uint16_t start_margins; /**< Number of bytes to be left at the
96316 + beginning of the external buffer (must be
96317 + divisible by 16) */
96318 + uint16_t end_margins; /**< number of bytes to be left at the end of
96319 + the external buffer(must be divisible by 16)*/
96320 +};
96321 +
96322 +struct fm_storage_profile_params {
96323 + struct fman_ext_pools fm_ext_pools;
96324 + struct fman_backup_bm_pools backup_pools;
96325 + struct fman_sp_int_context_data_copy *int_context;
96326 + struct fman_sp_buf_margins *buf_margins;
96327 + enum fman_dma_swap_option dma_swap_data;
96328 + enum fman_dma_cache_option int_context_cache_attr;
96329 + enum fman_dma_cache_option header_cache_attr;
96330 + enum fman_dma_cache_option scatter_gather_cache_attr;
96331 + bool dma_write_optimize;
96332 + uint16_t liodn_offset;
96333 + bool no_scather_gather;
96334 + struct fman_buf_pool_depletion buf_pool_depletion;
96335 +};
96336 +
96337 +/**************************************************************************//**
96338 + @Description Registers bit fields
96339 +*//***************************************************************************/
96340 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
96341 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
96342 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
96343 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
96344 +#define FMAN_SP_SG_DISABLE 0x80000000
96345 +
96346 +/* shifts */
96347 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
96348 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96349 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
96350 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
96351 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
96352 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
96353 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
96354 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
96355 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
96356 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
96357 +#define FMAN_SP_IC_SIZE_SHIFT 0
96358 +
96359 +/**************************************************************************//**
96360 + @Description defaults
96361 +*//***************************************************************************/
96362 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
96363 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
96364 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
96365 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
96366 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
96367 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
96368 +
96369 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
96370 +
96371 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
96372 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
96373 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
96374 + int max_num_of_pfc_priorities);
96375 +
96376 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
96377 + uint16_t index);
96378 +
96379 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
96380 + uint16_t index, uint32_t value);
96381 +
96382 +
96383 +#endif /* __FSL_FMAN_SP_H */
96384 --- /dev/null
96385 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96386 @@ -0,0 +1,479 @@
96387 +/*
96388 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96389 + *
96390 + * Redistribution and use in source and binary forms, with or without
96391 + * modification, are permitted provided that the following conditions are met:
96392 + * * Redistributions of source code must retain the above copyright
96393 + * notice, this list of conditions and the following disclaimer.
96394 + * * Redistributions in binary form must reproduce the above copyright
96395 + * notice, this list of conditions and the following disclaimer in the
96396 + * documentation and/or other materials provided with the distribution.
96397 + * * Neither the name of Freescale Semiconductor nor the
96398 + * names of its contributors may be used to endorse or promote products
96399 + * derived from this software without specific prior written permission.
96400 + *
96401 + *
96402 + * ALTERNATIVELY, this software may be distributed under the terms of the
96403 + * GNU General Public License ("GPL") as published by the Free Software
96404 + * Foundation, either version 2 of that License or (at your option) any
96405 + * later version.
96406 + *
96407 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96408 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96409 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96410 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96411 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96412 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96413 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96414 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96415 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96416 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96417 + */
96418 +
96419 +#ifndef __FSL_FMAN_TGEC_H
96420 +#define __FSL_FMAN_TGEC_H
96421 +
96422 +#include "common/general.h"
96423 +#include "fsl_enet.h"
96424 +
96425 +
96426 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96427 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
96428 +
96429 +enum tgec_counters {
96430 + E_TGEC_COUNTER_R64,
96431 + E_TGEC_COUNTER_R127,
96432 + E_TGEC_COUNTER_R255,
96433 + E_TGEC_COUNTER_R511,
96434 + E_TGEC_COUNTER_R1023,
96435 + E_TGEC_COUNTER_R1518,
96436 + E_TGEC_COUNTER_R1519X,
96437 + E_TGEC_COUNTER_TRFRG,
96438 + E_TGEC_COUNTER_TRJBR,
96439 + E_TGEC_COUNTER_RDRP,
96440 + E_TGEC_COUNTER_RALN,
96441 + E_TGEC_COUNTER_TRUND,
96442 + E_TGEC_COUNTER_TROVR,
96443 + E_TGEC_COUNTER_RXPF,
96444 + E_TGEC_COUNTER_TXPF,
96445 + E_TGEC_COUNTER_ROCT,
96446 + E_TGEC_COUNTER_RMCA,
96447 + E_TGEC_COUNTER_RBCA,
96448 + E_TGEC_COUNTER_RPKT,
96449 + E_TGEC_COUNTER_RUCA,
96450 + E_TGEC_COUNTER_RERR,
96451 + E_TGEC_COUNTER_TOCT,
96452 + E_TGEC_COUNTER_TMCA,
96453 + E_TGEC_COUNTER_TBCA,
96454 + E_TGEC_COUNTER_TUCA,
96455 + E_TGEC_COUNTER_TERR
96456 +};
96457 +
96458 +/* Command and Configuration Register (COMMAND_CONFIG) */
96459 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
96460 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
96461 +#define CMD_CFG_NO_LEN_CHK 0x00020000
96462 +#define CMD_CFG_SEND_IDLE 0x00010000
96463 +#define CMD_CFG_RX_ER_DISC 0x00004000
96464 +#define CMD_CFG_CMD_FRM_EN 0x00002000
96465 +#define CMD_CFG_STAT_CLR 0x00001000
96466 +#define CMD_CFG_LOOPBACK_EN 0x00000400
96467 +#define CMD_CFG_TX_ADDR_INS 0x00000200
96468 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
96469 +#define CMD_CFG_PAUSE_FWD 0x00000080
96470 +#define CMD_CFG_PROMIS_EN 0x00000010
96471 +#define CMD_CFG_WAN_MODE 0x00000008
96472 +#define CMD_CFG_RX_EN 0x00000002
96473 +#define CMD_CFG_TX_EN 0x00000001
96474 +
96475 +/* Interrupt Mask Register (IMASK) */
96476 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
96477 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
96478 +#define TGEC_IMASK_REM_FAULT 0x00004000
96479 +#define TGEC_IMASK_LOC_FAULT 0x00002000
96480 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
96481 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
96482 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
96483 +#define TGEC_IMASK_TX_ER 0x00000200
96484 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
96485 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
96486 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
96487 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
96488 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
96489 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
96490 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
96491 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
96492 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
96493 +
96494 +#define TGEC_EVENTS_MASK \
96495 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
96496 + TGEC_IMASK_MDIO_CMD_CMPL | \
96497 + TGEC_IMASK_REM_FAULT | \
96498 + TGEC_IMASK_LOC_FAULT | \
96499 + TGEC_IMASK_TX_ECC_ER | \
96500 + TGEC_IMASK_TX_FIFO_UNFL | \
96501 + TGEC_IMASK_TX_FIFO_OVFL | \
96502 + TGEC_IMASK_TX_ER | \
96503 + TGEC_IMASK_RX_FIFO_OVFL | \
96504 + TGEC_IMASK_RX_ECC_ER | \
96505 + TGEC_IMASK_RX_JAB_FRM | \
96506 + TGEC_IMASK_RX_OVRSZ_FRM | \
96507 + TGEC_IMASK_RX_RUNT_FRM | \
96508 + TGEC_IMASK_RX_FRAG_FRM | \
96509 + TGEC_IMASK_RX_LEN_ER | \
96510 + TGEC_IMASK_RX_CRC_ER | \
96511 + TGEC_IMASK_RX_ALIGN_ER))
96512 +
96513 +/* Hashtable Control Register (HASHTABLE_CTRL) */
96514 +#define TGEC_HASH_MCAST_SHIFT 23
96515 +#define TGEC_HASH_MCAST_EN 0x00000200
96516 +#define TGEC_HASH_ADR_MSK 0x000001ff
96517 +
96518 +#define DEFAULT_WAN_MODE_ENABLE FALSE
96519 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
96520 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
96521 +#define DEFAULT_PAUSE_IGNORE FALSE
96522 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
96523 +#define DEFAULT_LOOPBACK_ENABLE FALSE
96524 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
96525 +#define DEFAULT_RX_ERROR_DISCARD FALSE
96526 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
96527 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
96528 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
96529 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
96530 +#define DEFAULT_TX_IPG_LENGTH 12
96531 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
96532 +#define DEFAULT_PAUSE_QUANT 0xf000
96533 +
96534 +/*
96535 + * 10G memory map
96536 + */
96537 +struct tgec_regs {
96538 + uint32_t tgec_id; /* 0x000 Controller ID */
96539 + uint32_t reserved001[1]; /* 0x004 */
96540 + uint32_t command_config; /* 0x008 Control and configuration */
96541 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
96542 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
96543 + uint32_t maxfrm; /* 0x014 Maximum frame length */
96544 + uint32_t pause_quant; /* 0x018 Pause quanta */
96545 + uint32_t rx_fifo_sections; /* 0x01c */
96546 + uint32_t tx_fifo_sections; /* 0x020 */
96547 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
96548 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
96549 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
96550 + uint32_t mdio_cfg_status; /* 0x030 */
96551 + uint32_t mdio_command; /* 0x034 */
96552 + uint32_t mdio_data; /* 0x038 */
96553 + uint32_t mdio_regaddr; /* 0x03c */
96554 + uint32_t status; /* 0x040 */
96555 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
96556 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
96557 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
96558 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
96559 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
96560 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
96561 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
96562 + uint32_t imask; /* 0x060 Interrupt mask */
96563 + uint32_t ievent; /* 0x064 Interrupt event */
96564 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
96565 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
96566 + uint32_t reserved070[4]; /* 0x070 */
96567 + /*10Ge Statistics Counter */
96568 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
96569 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
96570 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
96571 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
96572 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
96573 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
96574 + uint32_t raln_u; /* 98 aAlignmentErrors */
96575 + uint32_t raln_l; /* 9c aAlignmentErrors */
96576 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
96577 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
96578 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
96579 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
96580 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
96581 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
96582 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
96583 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
96584 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
96585 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
96586 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
96587 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
96588 + uint32_t toct_u; /* D0 ifOutOctets */
96589 + uint32_t toct_l; /* D4 ifOutOctets */
96590 + uint32_t roct_u; /* D8 ifInOctets */
96591 + uint32_t roct_l; /* Dc ifInOctets */
96592 + uint32_t ruca_u; /* E0 ifInUcastPkts */
96593 + uint32_t ruca_l; /* E4 ifInUcastPkts */
96594 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
96595 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
96596 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
96597 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
96598 + uint32_t terr_u; /* F8 ifOutErrors */
96599 + uint32_t terr_l; /* Fc ifOutErrors */
96600 + uint32_t reserved100[2]; /* 100-108*/
96601 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
96602 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
96603 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
96604 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
96605 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
96606 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
96607 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
96608 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
96609 + uint32_t reoct_u; /* 128 etherStatsOctets */
96610 + uint32_t reoct_l; /* 12c etherStatsOctets */
96611 + uint32_t rpkt_u; /* 130 etherStatsPkts */
96612 + uint32_t rpkt_l; /* 134 etherStatsPkts */
96613 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
96614 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
96615 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
96616 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
96617 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
96618 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
96619 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
96620 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
96621 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
96622 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
96623 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
96624 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
96625 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
96626 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
96627 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
96628 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
96629 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
96630 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
96631 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
96632 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
96633 + uint32_t trfrg_u; /* 188 etherStatsFragments */
96634 + uint32_t trfrg_l; /* 18C etherStatsFragments */
96635 + uint32_t rerr_u; /* 190 ifInErrors */
96636 + uint32_t rerr_l; /* 194 ifInErrors */
96637 +};
96638 +
96639 +/**
96640 + * struct tgec_cfg - TGEC configuration
96641 + *
96642 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
96643 + * any frame received with an error is discarded in the
96644 + * Core and not forwarded to the Client interface.
96645 + * When set to 0 (Reset value), erroneous Frames are
96646 + * forwarded to the Client interface with ff_rx_err
96647 + * asserted.
96648 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
96649 + * frames are ignored by the MAC. When set to 0
96650 + * (Reset value) the transmit process is stopped for the
96651 + * amount of time specified in the pause quanta received
96652 + * within a pause frame.
96653 + * @pause_forward_enable:
96654 + * Terminate / Forward Pause Frames. If set to 1 pause
96655 + * frames are forwarded to the user application. When set
96656 + * to 0 (Reset value) pause frames are terminated and
96657 + * discarded within the MAC.
96658 + * @no_length_check_enable:
96659 + * Payload Length Check Disable. When set to 0
96660 + * (Reset value), the Core checks the frame's payload
96661 + * length with the Frame Length/Type field, when set to 1
96662 + * the payload length check is disabled.
96663 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
96664 + * all Command Frames are accepted, when set to 0
96665 + * (Reset Value) only Pause Frames are accepted and all
96666 + * other Command Frames are rejected.
96667 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
96668 + * permanently sends XGMII Idle sequences even when faults
96669 + * are received.
96670 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
96671 + * (0, default) of operation.
96672 + * @promiscuous_mode_enable:
96673 + * Enables MAC promiscuous operation. When set to 1, all
96674 + * frames are received without any MAC address filtering,
96675 + * when set to 0 (Reset value) Unicast Frames with a
96676 + * destination address not matching the Core MAC Address
96677 + * (MAC Address programmed in Registers MAC_ADDR_0 and
96678 + * MAC_ADDR_1 or the MAC address programmed in Registers
96679 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
96680 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
96681 + * MAC overwrites the source MAC address received from the
96682 + * Client Interface with one of the MAC addresses. If set
96683 + * to 0 (Reset value), the source MAC address from the
96684 + * Client Interface is transmitted unmodified to the line.
96685 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
96686 + * loop_ena is set to '1', when set to 0 (Reset value)
96687 + * the signal loop_ena is set to 0.
96688 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
96689 + * depending on the value of this Bit
96690 + * @time_stamp_enable: This bit selects between enabling and disabling the
96691 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
96692 + * 0: IEEE 1588 is disabled
96693 + * @max_frame_length: Maximum supported received frame length.
96694 + * The 10GEC MAC supports reception of any frame size up
96695 + * to 16,352 bytes (0x3FE0). Typical settings are
96696 + * 0x05EE (1,518 bytes) for standard frames.
96697 + * Default setting is 0x0600 (1,536 bytes).
96698 + * Received frames that exceed this stated maximum
96699 + * are truncated.
96700 + * @pause_quant: Pause quanta value used with transmitted pause frames.
96701 + * Each quanta represents a 512 bit-times.
96702 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
96703 + * Depending on LAN or WAN mode of operation the value has
96704 + * the following meaning: - LAN Mode: Number of octets in
96705 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
96706 + * fully supported (see 10.6.1 page 49) for any setting. A
96707 + * default of 12 (reset value) must be set to conform to
96708 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
96709 + * be able to perform clock rate compensation. - WAN Mode:
96710 + * Stretch factor. Valid values are 4..15. The stretch
96711 + * factor is calculated as (value+1)*8. A default of 12
96712 + * (reset value) must be set to conform to IEEE 802.3ae
96713 + * (i.e. 13*8=104). A larger value shrinks the IPG
96714 + * (increasing bandwidth).
96715 + *
96716 + * This structure contains basic TGEC configuration and must be passed to
96717 + * fman_tgec_init() function. A default set of configuration values can be
96718 + * obtained by calling fman_tgec_defconfig().
96719 + */
96720 +struct tgec_cfg {
96721 + bool rx_error_discard;
96722 + bool pause_ignore;
96723 + bool pause_forward_enable;
96724 + bool no_length_check_enable;
96725 + bool cmd_frame_enable;
96726 + bool send_idle_enable;
96727 + bool wan_mode_enable;
96728 + bool promiscuous_mode_enable;
96729 + bool tx_addr_ins_enable;
96730 + bool loopback_enable;
96731 + bool lgth_check_nostdr;
96732 + bool time_stamp_enable;
96733 + uint16_t max_frame_length;
96734 + uint16_t pause_quant;
96735 + uint32_t tx_ipg_length;
96736 + bool skip_fman11_workaround;
96737 +};
96738 +
96739 +
96740 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
96741 +
96742 +/**
96743 + * fman_tgec_init() - Init tgec hardware block
96744 + * @regs: Pointer to tgec register block
96745 + * @cfg: tgec configuration data
96746 + * @exceptions_mask: initial exceptions mask
96747 + *
96748 + * This function initializes the tgec controller and applies its
96749 + * basic configuration.
96750 + *
96751 + * Returns: 0 if successful, an error code otherwise.
96752 + */
96753 +
96754 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
96755 + uint32_t exception_mask);
96756 +
96757 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
96758 +
96759 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
96760 +
96761 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
96762 +
96763 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
96764 +
96765 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
96766 +
96767 +/**
96768 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
96769 + * @regs: Pointer to TGEC register block
96770 + */
96771 +void fman_tgec_reset_stat(struct tgec_regs *regs);
96772 +
96773 +/**
96774 + * fman_tgec_get_counter() - Reads TGEC HW counters
96775 + * @regs: Pointer to TGEC register block
96776 + * @reg_name: Counter name according to the appropriate enum
96777 + *
96778 + * Returns: Required counter value
96779 + */
96780 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
96781 + enum tgec_counters reg_name);
96782 +
96783 +/**
96784 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
96785 + * @regs: Pointer to TGEC register block
96786 + * @value: Value to be written in Hashtable Control Register
96787 + */
96788 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
96789 +
96790 +/**
96791 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
96792 + * @regs: Pointer to TGEC register block
96793 + * @pause_time: Pause quanta value used with transmitted pause frames.
96794 + * Each quanta represents a 512 bit-times
96795 + */
96796 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
96797 +
96798 +/**
96799 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
96800 + * @regs: Pointer to TGEC register block
96801 + * @en: Ignore/Respond to pause frame quanta
96802 + *
96803 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
96804 + * 0 - MAC stops transmit process for the duration specified
96805 + * in the Pause frame quanta of a received Pause frame.
96806 + * 1 - MAC ignores received Pause frames.
96807 + */
96808 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
96809 +
96810 +/**
96811 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
96812 + * @regs: Pointer to TGEC register block
96813 + * @en: enable/disable timestamp functionality
96814 + *
96815 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
96816 + * IEEE 1588 timestamp functionality control:
96817 + * 0 disabled, 1 enabled
96818 + */
96819 +
96820 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
96821 +
96822 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
96823 +
96824 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
96825 +
96826 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
96827 +
96828 +/**
96829 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
96830 + * @regs: Pointer to TGEC register block
96831 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
96832 + *
96833 + * Sets the additional station MAC address
96834 + */
96835 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
96836 +
96837 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
96838 +
96839 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
96840 +
96841 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
96842 +
96843 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
96844 +
96845 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
96846 +
96847 +
96848 +/**
96849 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
96850 + * @regs: Pointer to TGEC register block
96851 + */
96852 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
96853 +
96854 +/**
96855 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
96856 + * main tgec configuration parameters
96857 + * @regs: Pointer to TGEC register block
96858 + *
96859 + * TODO
96860 + */
96861 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
96862 + *regs);
96863 +
96864 +
96865 +#endif /* __FSL_FMAN_TGEC_H */
96866 --- /dev/null
96867 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
96868 @@ -0,0 +1,291 @@
96869 +/*
96870 + * Copyright 2012 Freescale Semiconductor Inc.
96871 + *
96872 + * Redistribution and use in source and binary forms, with or without
96873 + * modification, are permitted provided that the following conditions are met:
96874 + * * Redistributions of source code must retain the above copyright
96875 + * notice, this list of conditions and the following disclaimer.
96876 + * * Redistributions in binary form must reproduce the above copyright
96877 + * notice, this list of conditions and the following disclaimer in the
96878 + * documentation and/or other materials provided with the distribution.
96879 + * * Neither the name of Freescale Semiconductor nor the
96880 + * names of its contributors may be used to endorse or promote products
96881 + * derived from this software without specific prior written permission.
96882 + *
96883 + *
96884 + * ALTERNATIVELY, this software may be distributed under the terms of the
96885 + * GNU General Public License ("GPL") as published by the Free Software
96886 + * Foundation, either version 2 of that License or (at your option) any
96887 + * later version.
96888 + *
96889 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96890 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96891 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96892 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96893 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96894 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96895 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96896 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96897 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96898 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96899 + */
96900 +
96901 +/**
96902 +
96903 + @File dpaa_integration_ext.h
96904 +
96905 + @Description T4240 FM external definitions and structures.
96906 +*//***************************************************************************/
96907 +#ifndef __DPAA_INTEGRATION_EXT_H
96908 +#define __DPAA_INTEGRATION_EXT_H
96909 +
96910 +#include "std_ext.h"
96911 +
96912 +
96913 +#define DPAA_VERSION 11
96914 +
96915 +/**************************************************************************//**
96916 + @Description DPAA SW Portals Enumeration.
96917 +*//***************************************************************************/
96918 +typedef enum
96919 +{
96920 + e_DPAA_SWPORTAL0 = 0,
96921 + e_DPAA_SWPORTAL1,
96922 + e_DPAA_SWPORTAL2,
96923 + e_DPAA_SWPORTAL3,
96924 + e_DPAA_SWPORTAL4,
96925 + e_DPAA_SWPORTAL5,
96926 + e_DPAA_SWPORTAL6,
96927 + e_DPAA_SWPORTAL7,
96928 + e_DPAA_SWPORTAL8,
96929 + e_DPAA_SWPORTAL9,
96930 + e_DPAA_SWPORTAL10,
96931 + e_DPAA_SWPORTAL11,
96932 + e_DPAA_SWPORTAL12,
96933 + e_DPAA_SWPORTAL13,
96934 + e_DPAA_SWPORTAL14,
96935 + e_DPAA_SWPORTAL15,
96936 + e_DPAA_SWPORTAL16,
96937 + e_DPAA_SWPORTAL17,
96938 + e_DPAA_SWPORTAL18,
96939 + e_DPAA_SWPORTAL19,
96940 + e_DPAA_SWPORTAL20,
96941 + e_DPAA_SWPORTAL21,
96942 + e_DPAA_SWPORTAL22,
96943 + e_DPAA_SWPORTAL23,
96944 + e_DPAA_SWPORTAL24,
96945 + e_DPAA_SWPORTAL_DUMMY_LAST
96946 +} e_DpaaSwPortal;
96947 +
96948 +/**************************************************************************//**
96949 + @Description DPAA Direct Connect Portals Enumeration.
96950 +*//***************************************************************************/
96951 +typedef enum
96952 +{
96953 + e_DPAA_DCPORTAL0 = 0,
96954 + e_DPAA_DCPORTAL1,
96955 + e_DPAA_DCPORTAL2,
96956 + e_DPAA_DCPORTAL_DUMMY_LAST
96957 +} e_DpaaDcPortal;
96958 +
96959 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
96960 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
96961 +
96962 +/*****************************************************************************
96963 + QMan INTEGRATION-SPECIFIC DEFINITIONS
96964 +******************************************************************************/
96965 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
96966 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
96967 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
96968 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
96969 + /**< FQIDs range - 24 bits */
96970 +
96971 +/**************************************************************************//**
96972 + @Description Work Queue Channel assignments in QMan.
96973 +*//***************************************************************************/
96974 +typedef enum
96975 +{
96976 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
96977 + e_QM_FQ_CHANNEL_SWPORTAL1,
96978 + e_QM_FQ_CHANNEL_SWPORTAL2,
96979 + e_QM_FQ_CHANNEL_SWPORTAL3,
96980 + e_QM_FQ_CHANNEL_SWPORTAL4,
96981 + e_QM_FQ_CHANNEL_SWPORTAL5,
96982 + e_QM_FQ_CHANNEL_SWPORTAL6,
96983 + e_QM_FQ_CHANNEL_SWPORTAL7,
96984 + e_QM_FQ_CHANNEL_SWPORTAL8,
96985 + e_QM_FQ_CHANNEL_SWPORTAL9,
96986 + e_QM_FQ_CHANNEL_SWPORTAL10,
96987 + e_QM_FQ_CHANNEL_SWPORTAL11,
96988 + e_QM_FQ_CHANNEL_SWPORTAL12,
96989 + e_QM_FQ_CHANNEL_SWPORTAL13,
96990 + e_QM_FQ_CHANNEL_SWPORTAL14,
96991 + e_QM_FQ_CHANNEL_SWPORTAL15,
96992 + e_QM_FQ_CHANNEL_SWPORTAL16,
96993 + e_QM_FQ_CHANNEL_SWPORTAL17,
96994 + e_QM_FQ_CHANNEL_SWPORTAL18,
96995 + e_QM_FQ_CHANNEL_SWPORTAL19,
96996 + e_QM_FQ_CHANNEL_SWPORTAL20,
96997 + e_QM_FQ_CHANNEL_SWPORTAL21,
96998 + e_QM_FQ_CHANNEL_SWPORTAL22,
96999 + e_QM_FQ_CHANNEL_SWPORTAL23,
97000 + e_QM_FQ_CHANNEL_SWPORTAL24,
97001 +
97002 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97003 + e_QM_FQ_CHANNEL_POOL2,
97004 + e_QM_FQ_CHANNEL_POOL3,
97005 + e_QM_FQ_CHANNEL_POOL4,
97006 + e_QM_FQ_CHANNEL_POOL5,
97007 + e_QM_FQ_CHANNEL_POOL6,
97008 + e_QM_FQ_CHANNEL_POOL7,
97009 + e_QM_FQ_CHANNEL_POOL8,
97010 + e_QM_FQ_CHANNEL_POOL9,
97011 + e_QM_FQ_CHANNEL_POOL10,
97012 + e_QM_FQ_CHANNEL_POOL11,
97013 + e_QM_FQ_CHANNEL_POOL12,
97014 + e_QM_FQ_CHANNEL_POOL13,
97015 + e_QM_FQ_CHANNEL_POOL14,
97016 + e_QM_FQ_CHANNEL_POOL15,
97017 +
97018 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97019 + connected to FMan 0; assigned in incrementing order to
97020 + each sub-portal (SP) in the portal */
97021 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97022 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97023 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97024 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97025 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97026 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97027 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97028 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97029 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97030 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97031 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97032 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97033 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97034 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97035 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97036 +
97037 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97038 + e_QM_FQ_CHANNEL_RMAN_SP1,
97039 +
97040 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97041 + connected to SEC */
97042 +} e_QmFQChannel;
97043 +
97044 +/*****************************************************************************
97045 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97046 +******************************************************************************/
97047 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97048 +
97049 +/*****************************************************************************
97050 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97051 +******************************************************************************/
97052 +#define SEC_NUM_OF_DECOS 3
97053 +#define SEC_ALL_DECOS_MASK 0x00000003
97054 +
97055 +
97056 +/*****************************************************************************
97057 + FM INTEGRATION-SPECIFIC DEFINITIONS
97058 +******************************************************************************/
97059 +#define INTG_MAX_NUM_OF_FM 2
97060 +/* Ports defines */
97061 +#define FM_MAX_NUM_OF_1G_MACS 6
97062 +#define FM_MAX_NUM_OF_10G_MACS 2
97063 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97064 +#define FM_MAX_NUM_OF_OH_PORTS 6
97065 +
97066 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97067 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97068 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97069 +
97070 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97071 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97072 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97073 +
97074 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97075 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97076 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97077 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97078 +
97079 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
97080 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97081 +
97082 +/* RAMs defines */
97083 +#define FM_MURAM_SIZE (384 * KILOBYTE)
97084 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
97085 +#define FM_NUM_OF_CTRL 4
97086 +
97087 +/* PCD defines */
97088 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97089 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97090 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97091 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97092 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97093 +
97094 +/* RTC defines */
97095 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97096 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97097 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97098 +
97099 +/* QMI defines */
97100 +#define QMI_MAX_NUM_OF_TNUMS 64
97101 +#define QMI_DEF_TNUMS_THRESH 32
97102 +/* FPM defines */
97103 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97104 +
97105 +/* DMA defines */
97106 +#define DMA_THRESH_MAX_COMMQ 83
97107 +#define DMA_THRESH_MAX_BUF 127
97108 +
97109 +/* BMI defines */
97110 +#define BMI_MAX_NUM_OF_TASKS 128
97111 +#define BMI_MAX_NUM_OF_DMAS 84
97112 +
97113 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97114 +#define PORT_MAX_WEIGHT 16
97115 +
97116 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97117 +
97118 +/* Unique T4240 */
97119 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97120 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97121 +#define FM_NO_OP_OBSERVED_POOLS
97122 +#define FM_FRAME_END_PARAMS_FOR_OP
97123 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97124 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97125 +
97126 +#define FM_NO_GUARANTEED_RESET_VALUES
97127 +
97128 +/* FM errata */
97129 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97130 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
97131 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97132 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97133 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97134 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97135 +
97136 +#define FM_BCB_ERRATA_BMI_SW001
97137 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97138 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97139 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97140 +
97141 +/*****************************************************************************
97142 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97143 +******************************************************************************/
97144 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97145 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97146 +
97147 +/* RMan erratas */
97148 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97149 +
97150 +/*****************************************************************************
97151 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97152 +******************************************************************************/
97153 +#define NUM_OF_RX_SC 16
97154 +#define NUM_OF_TX_SC 16
97155 +
97156 +#define NUM_OF_SA_PER_RX_SC 2
97157 +#define NUM_OF_SA_PER_TX_SC 2
97158 +
97159 +#endif /* __DPAA_INTEGRATION_EXT_H */
97160 --- /dev/null
97161 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97162 @@ -0,0 +1,71 @@
97163 +/*
97164 + * Copyright 2012 Freescale Semiconductor Inc.
97165 + *
97166 + * Redistribution and use in source and binary forms, with or without
97167 + * modification, are permitted provided that the following conditions are met:
97168 + * * Redistributions of source code must retain the above copyright
97169 + * notice, this list of conditions and the following disclaimer.
97170 + * * Redistributions in binary form must reproduce the above copyright
97171 + * notice, this list of conditions and the following disclaimer in the
97172 + * documentation and/or other materials provided with the distribution.
97173 + * * Neither the name of Freescale Semiconductor nor the
97174 + * names of its contributors may be used to endorse or promote products
97175 + * derived from this software without specific prior written permission.
97176 + *
97177 + *
97178 + * ALTERNATIVELY, this software may be distributed under the terms of the
97179 + * GNU General Public License ("GPL") as published by the Free Software
97180 + * Foundation, either version 2 of that License or (at your option) any
97181 + * later version.
97182 + *
97183 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97184 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97185 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97186 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97187 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97188 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97189 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97190 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97191 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97192 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97193 + */
97194 +
97195 +/**************************************************************************//**
97196 +
97197 + @File part_ext.h
97198 +
97199 + @Description Definitions for the part (integration) module.
97200 +*//***************************************************************************/
97201 +
97202 +#ifndef __PART_EXT_H
97203 +#define __PART_EXT_H
97204 +
97205 +#include "std_ext.h"
97206 +#include "part_integration_ext.h"
97207 +
97208 +#if !(defined(P1023) || \
97209 + defined(P2041) || \
97210 + defined(P3041) || \
97211 + defined(P4080) || \
97212 + defined(P5020) || \
97213 + defined(P5040) || \
97214 + defined(B4860) || \
97215 + defined(T4240))
97216 +#error "unable to proceed without chip-definition"
97217 +#endif
97218 +
97219 +
97220 +/**************************************************************************//*
97221 + @Description Part data structure - must be contained in any integration
97222 + data structure.
97223 +*//***************************************************************************/
97224 +typedef struct t_Part
97225 +{
97226 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97227 + /**< Returns the address of the module's memory map base. */
97228 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97229 + /**< Returns the module's ID according to its memory map base. */
97230 +} t_Part;
97231 +
97232 +
97233 +#endif /* __PART_EXT_H */
97234 --- /dev/null
97235 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97236 @@ -0,0 +1,304 @@
97237 +/*
97238 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97239 + *
97240 + * Redistribution and use in source and binary forms, with or without
97241 + * modification, are permitted provided that the following conditions are met:
97242 + * * Redistributions of source code must retain the above copyright
97243 + * notice, this list of conditions and the following disclaimer.
97244 + * * Redistributions in binary form must reproduce the above copyright
97245 + * notice, this list of conditions and the following disclaimer in the
97246 + * documentation and/or other materials provided with the distribution.
97247 + * * Neither the name of Freescale Semiconductor nor the
97248 + * names of its contributors may be used to endorse or promote products
97249 + * derived from this software without specific prior written permission.
97250 + *
97251 + *
97252 + * ALTERNATIVELY, this software may be distributed under the terms of the
97253 + * GNU General Public License ("GPL") as published by the Free Software
97254 + * Foundation, either version 2 of that License or (at your option) any
97255 + * later version.
97256 + *
97257 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97258 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97259 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97260 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97261 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97262 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97263 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97264 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97265 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97266 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97267 + */
97268 +
97269 +/**
97270 +
97271 + @File part_integration_ext.h
97272 +
97273 + @Description T4240 external definitions and structures.
97274 +*//***************************************************************************/
97275 +#ifndef __PART_INTEGRATION_EXT_H
97276 +#define __PART_INTEGRATION_EXT_H
97277 +
97278 +#include "std_ext.h"
97279 +#include "ddr_std_ext.h"
97280 +#include "enet_ext.h"
97281 +#include "dpaa_integration_ext.h"
97282 +
97283 +
97284 +/**************************************************************************//**
97285 + @Group T4240_chip_id T4240 Application Programming Interface
97286 +
97287 + @Description T4240 Chip functions,definitions and enums.
97288 +
97289 + @{
97290 +*//***************************************************************************/
97291 +
97292 +#define CORE_E6500
97293 +
97294 +#define INTG_MAX_NUM_OF_CORES 24
97295 +
97296 +
97297 +/**************************************************************************//**
97298 + @Description Module types.
97299 +*//***************************************************************************/
97300 +typedef enum e_ModuleId
97301 +{
97302 + e_MODULE_ID_DUART_1 = 0,
97303 + e_MODULE_ID_DUART_2,
97304 + e_MODULE_ID_DUART_3,
97305 + e_MODULE_ID_DUART_4,
97306 + e_MODULE_ID_LAW,
97307 + e_MODULE_ID_IFC,
97308 + e_MODULE_ID_PAMU,
97309 + e_MODULE_ID_QM, /**< Queue manager module */
97310 + e_MODULE_ID_BM, /**< Buffer manager module */
97311 + e_MODULE_ID_QM_CE_PORTAL_0,
97312 + e_MODULE_ID_QM_CI_PORTAL_0,
97313 + e_MODULE_ID_QM_CE_PORTAL_1,
97314 + e_MODULE_ID_QM_CI_PORTAL_1,
97315 + e_MODULE_ID_QM_CE_PORTAL_2,
97316 + e_MODULE_ID_QM_CI_PORTAL_2,
97317 + e_MODULE_ID_QM_CE_PORTAL_3,
97318 + e_MODULE_ID_QM_CI_PORTAL_3,
97319 + e_MODULE_ID_QM_CE_PORTAL_4,
97320 + e_MODULE_ID_QM_CI_PORTAL_4,
97321 + e_MODULE_ID_QM_CE_PORTAL_5,
97322 + e_MODULE_ID_QM_CI_PORTAL_5,
97323 + e_MODULE_ID_QM_CE_PORTAL_6,
97324 + e_MODULE_ID_QM_CI_PORTAL_6,
97325 + e_MODULE_ID_QM_CE_PORTAL_7,
97326 + e_MODULE_ID_QM_CI_PORTAL_7,
97327 + e_MODULE_ID_QM_CE_PORTAL_8,
97328 + e_MODULE_ID_QM_CI_PORTAL_8,
97329 + e_MODULE_ID_QM_CE_PORTAL_9,
97330 + e_MODULE_ID_QM_CI_PORTAL_9,
97331 + e_MODULE_ID_BM_CE_PORTAL_0,
97332 + e_MODULE_ID_BM_CI_PORTAL_0,
97333 + e_MODULE_ID_BM_CE_PORTAL_1,
97334 + e_MODULE_ID_BM_CI_PORTAL_1,
97335 + e_MODULE_ID_BM_CE_PORTAL_2,
97336 + e_MODULE_ID_BM_CI_PORTAL_2,
97337 + e_MODULE_ID_BM_CE_PORTAL_3,
97338 + e_MODULE_ID_BM_CI_PORTAL_3,
97339 + e_MODULE_ID_BM_CE_PORTAL_4,
97340 + e_MODULE_ID_BM_CI_PORTAL_4,
97341 + e_MODULE_ID_BM_CE_PORTAL_5,
97342 + e_MODULE_ID_BM_CI_PORTAL_5,
97343 + e_MODULE_ID_BM_CE_PORTAL_6,
97344 + e_MODULE_ID_BM_CI_PORTAL_6,
97345 + e_MODULE_ID_BM_CE_PORTAL_7,
97346 + e_MODULE_ID_BM_CI_PORTAL_7,
97347 + e_MODULE_ID_BM_CE_PORTAL_8,
97348 + e_MODULE_ID_BM_CI_PORTAL_8,
97349 + e_MODULE_ID_BM_CE_PORTAL_9,
97350 + e_MODULE_ID_BM_CI_PORTAL_9,
97351 + e_MODULE_ID_FM, /**< Frame manager module */
97352 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
97353 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
97354 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
97355 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
97356 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
97357 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
97358 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
97359 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
97360 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
97361 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
97362 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
97363 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
97364 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
97365 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
97366 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
97367 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
97368 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
97369 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
97370 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
97371 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
97372 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
97373 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
97374 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
97375 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
97376 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
97377 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
97378 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
97379 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
97380 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
97381 + e_MODULE_ID_FM_KG, /**< FM Keygen */
97382 + e_MODULE_ID_FM_DMA, /**< FM DMA */
97383 + e_MODULE_ID_FM_FPM, /**< FM FPM */
97384 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
97385 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
97386 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
97387 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
97388 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
97389 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
97390 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
97391 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
97392 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
97393 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
97394 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
97395 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
97396 +
97397 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
97398 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
97399 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
97400 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
97401 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
97402 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
97403 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
97404 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
97405 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
97406 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
97407 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
97408 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
97409 +
97410 + e_MODULE_ID_PIC, /**< PIC */
97411 + e_MODULE_ID_GPIO, /**< GPIO */
97412 + e_MODULE_ID_SERDES, /**< SERDES */
97413 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
97414 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
97415 +
97416 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
97417 +
97418 + e_MODULE_ID_DUMMY_LAST
97419 +} e_ModuleId;
97420 +
97421 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
97422 +
97423 +#if 0 /* using unified values */
97424 +/*****************************************************************************
97425 + INTEGRATION-SPECIFIC MODULE CODES
97426 +******************************************************************************/
97427 +#define MODULE_UNKNOWN 0x00000000
97428 +#define MODULE_MEM 0x00010000
97429 +#define MODULE_MM 0x00020000
97430 +#define MODULE_CORE 0x00030000
97431 +#define MODULE_T4240 0x00040000
97432 +#define MODULE_T4240_PLATFORM 0x00050000
97433 +#define MODULE_PM 0x00060000
97434 +#define MODULE_MMU 0x00070000
97435 +#define MODULE_PIC 0x00080000
97436 +#define MODULE_CPC 0x00090000
97437 +#define MODULE_DUART 0x000a0000
97438 +#define MODULE_SERDES 0x000b0000
97439 +#define MODULE_PIO 0x000c0000
97440 +#define MODULE_QM 0x000d0000
97441 +#define MODULE_BM 0x000e0000
97442 +#define MODULE_SEC 0x000f0000
97443 +#define MODULE_LAW 0x00100000
97444 +#define MODULE_LBC 0x00110000
97445 +#define MODULE_PAMU 0x00120000
97446 +#define MODULE_FM 0x00130000
97447 +#define MODULE_FM_MURAM 0x00140000
97448 +#define MODULE_FM_PCD 0x00150000
97449 +#define MODULE_FM_RTC 0x00160000
97450 +#define MODULE_FM_MAC 0x00170000
97451 +#define MODULE_FM_PORT 0x00180000
97452 +#define MODULE_FM_SP 0x00190000
97453 +#define MODULE_DPA_PORT 0x001a0000
97454 +#define MODULE_MII 0x001b0000
97455 +#define MODULE_I2C 0x001c0000
97456 +#define MODULE_DMA 0x001d0000
97457 +#define MODULE_DDR 0x001e0000
97458 +#define MODULE_ESPI 0x001f0000
97459 +#define MODULE_DPAA_IPSEC 0x00200000
97460 +#endif /* using unified values */
97461 +
97462 +/*****************************************************************************
97463 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
97464 +******************************************************************************/
97465 +#define PAMU_NUM_OF_PARTITIONS 4
97466 +
97467 +/*****************************************************************************
97468 + LAW INTEGRATION-SPECIFIC DEFINITIONS
97469 +******************************************************************************/
97470 +#define LAW_NUM_OF_WINDOWS 32
97471 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
97472 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
97473 +
97474 +
97475 +/*****************************************************************************
97476 + LBC INTEGRATION-SPECIFIC DEFINITIONS
97477 +******************************************************************************/
97478 +/**************************************************************************//**
97479 + @Group lbc_exception_grp LBC Exception Unit
97480 +
97481 + @Description LBC Exception unit API functions, definitions and enums
97482 +
97483 + @{
97484 +*//***************************************************************************/
97485 +
97486 +/**************************************************************************//**
97487 + @Anchor lbc_exbm
97488 +
97489 + @Collection LBC Errors Bit Mask
97490 +
97491 + These errors are reported through the exceptions callback..
97492 + The values can be or'ed in any combination in the errors mask
97493 + parameter of the errors report structure.
97494 +
97495 + These errors can also be passed as a bit-mask to
97496 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
97497 + for enabling or disabling error checking.
97498 + @{
97499 +*//***************************************************************************/
97500 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
97501 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
97502 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
97503 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
97504 +
97505 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
97506 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
97507 + /**< All possible errors */
97508 +/* @} */
97509 +/** @} */ /* end of lbc_exception_grp group */
97510 +
97511 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
97512 +
97513 +#define LBC_NUM_OF_BANKS 8
97514 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
97515 +#define LBC_PARITY_SUPPORT
97516 +#define LBC_ADDRESS_HOLD_TIME_CTRL
97517 +#define LBC_HIGH_CLK_DIVIDERS
97518 +#define LBC_FCM_AVAILABLE
97519 +
97520 +/*****************************************************************************
97521 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
97522 +******************************************************************************/
97523 +#define GPIO_PORT_OFFSET_0x1000
97524 +
97525 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
97526 + Each port contains up to 32 I/O pins. */
97527 +
97528 +#define GPIO_VALID_PIN_MASKS \
97529 + { /* Port A */ 0xFFFFFFFF, \
97530 + /* Port B */ 0xFFFFFFFF, \
97531 + /* Port C */ 0xFFFFFFFF }
97532 +
97533 +#define GPIO_VALID_INTR_MASKS \
97534 + { /* Port A */ 0xFFFFFFFF, \
97535 + /* Port B */ 0xFFFFFFFF, \
97536 + /* Port C */ 0xFFFFFFFF }
97537 +
97538 +
97539 +
97540 +#endif /* __PART_INTEGRATION_EXT_H */
97541 --- /dev/null
97542 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
97543 @@ -0,0 +1,293 @@
97544 +/*
97545 + * Copyright 2012 Freescale Semiconductor Inc.
97546 + *
97547 + * Redistribution and use in source and binary forms, with or without
97548 + * modification, are permitted provided that the following conditions are met:
97549 + * * Redistributions of source code must retain the above copyright
97550 + * notice, this list of conditions and the following disclaimer.
97551 + * * Redistributions in binary form must reproduce the above copyright
97552 + * notice, this list of conditions and the following disclaimer in the
97553 + * documentation and/or other materials provided with the distribution.
97554 + * * Neither the name of Freescale Semiconductor nor the
97555 + * names of its contributors may be used to endorse or promote products
97556 + * derived from this software without specific prior written permission.
97557 + *
97558 + *
97559 + * ALTERNATIVELY, this software may be distributed under the terms of the
97560 + * GNU General Public License ("GPL") as published by the Free Software
97561 + * Foundation, either version 2 of that License or (at your option) any
97562 + * later version.
97563 + *
97564 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97565 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97566 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97567 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97568 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97569 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97570 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97571 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97572 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97573 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97574 + */
97575 +
97576 +/**
97577 +
97578 + @File dpaa_integration_ext.h
97579 +
97580 + @Description T4240 FM external definitions and structures.
97581 +*//***************************************************************************/
97582 +#ifndef __DPAA_INTEGRATION_EXT_H
97583 +#define __DPAA_INTEGRATION_EXT_H
97584 +
97585 +#include "std_ext.h"
97586 +
97587 +
97588 +#define DPAA_VERSION 11
97589 +
97590 +/**************************************************************************//**
97591 + @Description DPAA SW Portals Enumeration.
97592 +*//***************************************************************************/
97593 +typedef enum
97594 +{
97595 + e_DPAA_SWPORTAL0 = 0,
97596 + e_DPAA_SWPORTAL1,
97597 + e_DPAA_SWPORTAL2,
97598 + e_DPAA_SWPORTAL3,
97599 + e_DPAA_SWPORTAL4,
97600 + e_DPAA_SWPORTAL5,
97601 + e_DPAA_SWPORTAL6,
97602 + e_DPAA_SWPORTAL7,
97603 + e_DPAA_SWPORTAL8,
97604 + e_DPAA_SWPORTAL9,
97605 + e_DPAA_SWPORTAL10,
97606 + e_DPAA_SWPORTAL11,
97607 + e_DPAA_SWPORTAL12,
97608 + e_DPAA_SWPORTAL13,
97609 + e_DPAA_SWPORTAL14,
97610 + e_DPAA_SWPORTAL15,
97611 + e_DPAA_SWPORTAL16,
97612 + e_DPAA_SWPORTAL17,
97613 + e_DPAA_SWPORTAL18,
97614 + e_DPAA_SWPORTAL19,
97615 + e_DPAA_SWPORTAL20,
97616 + e_DPAA_SWPORTAL21,
97617 + e_DPAA_SWPORTAL22,
97618 + e_DPAA_SWPORTAL23,
97619 + e_DPAA_SWPORTAL24,
97620 + e_DPAA_SWPORTAL_DUMMY_LAST
97621 +} e_DpaaSwPortal;
97622 +
97623 +/**************************************************************************//**
97624 + @Description DPAA Direct Connect Portals Enumeration.
97625 +*//***************************************************************************/
97626 +typedef enum
97627 +{
97628 + e_DPAA_DCPORTAL0 = 0,
97629 + e_DPAA_DCPORTAL1,
97630 + e_DPAA_DCPORTAL2,
97631 + e_DPAA_DCPORTAL_DUMMY_LAST
97632 +} e_DpaaDcPortal;
97633 +
97634 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97635 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97636 +
97637 +/*****************************************************************************
97638 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97639 +******************************************************************************/
97640 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97641 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97642 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97643 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97644 + /**< FQIDs range - 24 bits */
97645 +
97646 +/**************************************************************************//**
97647 + @Description Work Queue Channel assignments in QMan.
97648 +*//***************************************************************************/
97649 +typedef enum
97650 +{
97651 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97652 + e_QM_FQ_CHANNEL_SWPORTAL1,
97653 + e_QM_FQ_CHANNEL_SWPORTAL2,
97654 + e_QM_FQ_CHANNEL_SWPORTAL3,
97655 + e_QM_FQ_CHANNEL_SWPORTAL4,
97656 + e_QM_FQ_CHANNEL_SWPORTAL5,
97657 + e_QM_FQ_CHANNEL_SWPORTAL6,
97658 + e_QM_FQ_CHANNEL_SWPORTAL7,
97659 + e_QM_FQ_CHANNEL_SWPORTAL8,
97660 + e_QM_FQ_CHANNEL_SWPORTAL9,
97661 + e_QM_FQ_CHANNEL_SWPORTAL10,
97662 + e_QM_FQ_CHANNEL_SWPORTAL11,
97663 + e_QM_FQ_CHANNEL_SWPORTAL12,
97664 + e_QM_FQ_CHANNEL_SWPORTAL13,
97665 + e_QM_FQ_CHANNEL_SWPORTAL14,
97666 + e_QM_FQ_CHANNEL_SWPORTAL15,
97667 + e_QM_FQ_CHANNEL_SWPORTAL16,
97668 + e_QM_FQ_CHANNEL_SWPORTAL17,
97669 + e_QM_FQ_CHANNEL_SWPORTAL18,
97670 + e_QM_FQ_CHANNEL_SWPORTAL19,
97671 + e_QM_FQ_CHANNEL_SWPORTAL20,
97672 + e_QM_FQ_CHANNEL_SWPORTAL21,
97673 + e_QM_FQ_CHANNEL_SWPORTAL22,
97674 + e_QM_FQ_CHANNEL_SWPORTAL23,
97675 + e_QM_FQ_CHANNEL_SWPORTAL24,
97676 +
97677 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97678 + e_QM_FQ_CHANNEL_POOL2,
97679 + e_QM_FQ_CHANNEL_POOL3,
97680 + e_QM_FQ_CHANNEL_POOL4,
97681 + e_QM_FQ_CHANNEL_POOL5,
97682 + e_QM_FQ_CHANNEL_POOL6,
97683 + e_QM_FQ_CHANNEL_POOL7,
97684 + e_QM_FQ_CHANNEL_POOL8,
97685 + e_QM_FQ_CHANNEL_POOL9,
97686 + e_QM_FQ_CHANNEL_POOL10,
97687 + e_QM_FQ_CHANNEL_POOL11,
97688 + e_QM_FQ_CHANNEL_POOL12,
97689 + e_QM_FQ_CHANNEL_POOL13,
97690 + e_QM_FQ_CHANNEL_POOL14,
97691 + e_QM_FQ_CHANNEL_POOL15,
97692 +
97693 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97694 + connected to FMan 0; assigned in incrementing order to
97695 + each sub-portal (SP) in the portal */
97696 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97697 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97698 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97699 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97700 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97701 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97702 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97703 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97704 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97705 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97706 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97707 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97708 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97709 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97710 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97711 +
97712 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97713 + e_QM_FQ_CHANNEL_RMAN_SP1,
97714 +
97715 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97716 + connected to SEC */
97717 +} e_QmFQChannel;
97718 +
97719 +/*****************************************************************************
97720 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97721 +******************************************************************************/
97722 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97723 +
97724 +/*****************************************************************************
97725 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97726 +******************************************************************************/
97727 +#define SEC_NUM_OF_DECOS 3
97728 +#define SEC_ALL_DECOS_MASK 0x00000003
97729 +
97730 +
97731 +/*****************************************************************************
97732 + FM INTEGRATION-SPECIFIC DEFINITIONS
97733 +******************************************************************************/
97734 +#define INTG_MAX_NUM_OF_FM 1
97735 +/* Ports defines */
97736 +#define FM_MAX_NUM_OF_1G_MACS 5
97737 +#define FM_MAX_NUM_OF_10G_MACS 1
97738 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97739 +#define FM_MAX_NUM_OF_OH_PORTS 4
97740 +
97741 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97742 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97743 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97744 +
97745 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97746 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97747 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97748 +
97749 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
97750 +
97751 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97752 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97753 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97754 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97755 +
97756 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
97757 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97758 +
97759 +/* RAMs defines */
97760 +#define FM_MURAM_SIZE (192 * KILOBYTE)
97761 +#define FM_IRAM_SIZE(major, minor) \
97762 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
97763 +#define FM_NUM_OF_CTRL 2
97764 +
97765 +/* PCD defines */
97766 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97767 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97768 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97769 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97770 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97771 +
97772 +/* RTC defines */
97773 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97774 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97775 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97776 +
97777 +/* QMI defines */
97778 +#define QMI_MAX_NUM_OF_TNUMS 64
97779 +#define QMI_DEF_TNUMS_THRESH 32
97780 +/* FPM defines */
97781 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97782 +
97783 +/* DMA defines */
97784 +#define DMA_THRESH_MAX_COMMQ 83
97785 +#define DMA_THRESH_MAX_BUF 127
97786 +
97787 +/* BMI defines */
97788 +#define BMI_MAX_NUM_OF_TASKS 64
97789 +#define BMI_MAX_NUM_OF_DMAS 32
97790 +
97791 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97792 +#define PORT_MAX_WEIGHT 16
97793 +
97794 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97795 +
97796 +/* Unique T4240 */
97797 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97798 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97799 +#define FM_NO_OP_OBSERVED_POOLS
97800 +#define FM_FRAME_END_PARAMS_FOR_OP
97801 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97802 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97803 +
97804 +#define FM_NO_GUARANTEED_RESET_VALUES
97805 +
97806 +/* FM errata */
97807 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97808 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97809 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97810 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97811 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97812 +
97813 +#define FM_BCB_ERRATA_BMI_SW001
97814 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97815 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97816 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97817 +
97818 +/*****************************************************************************
97819 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97820 +******************************************************************************/
97821 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97822 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97823 +
97824 +/* RMan erratas */
97825 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97826 +
97827 +/*****************************************************************************
97828 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97829 +******************************************************************************/
97830 +#define NUM_OF_RX_SC 16
97831 +#define NUM_OF_TX_SC 16
97832 +
97833 +#define NUM_OF_SA_PER_RX_SC 2
97834 +#define NUM_OF_SA_PER_TX_SC 2
97835 +
97836 +#endif /* __DPAA_INTEGRATION_EXT_H */
97837 --- /dev/null
97838 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
97839 @@ -0,0 +1,59 @@
97840 +/*
97841 + * Copyright 2012 Freescale Semiconductor Inc.
97842 + *
97843 + * Redistribution and use in source and binary forms, with or without
97844 + * modification, are permitted provided that the following conditions are met:
97845 + * * Redistributions of source code must retain the above copyright
97846 + * notice, this list of conditions and the following disclaimer.
97847 + * * Redistributions in binary form must reproduce the above copyright
97848 + * notice, this list of conditions and the following disclaimer in the
97849 + * documentation and/or other materials provided with the distribution.
97850 + * * Neither the name of Freescale Semiconductor nor the
97851 + * names of its contributors may be used to endorse or promote products
97852 + * derived from this software without specific prior written permission.
97853 + *
97854 + *
97855 + * ALTERNATIVELY, this software may be distributed under the terms of the
97856 + * GNU General Public License ("GPL") as published by the Free Software
97857 + * Foundation, either version 2 of that License or (at your option) any
97858 + * later version.
97859 + *
97860 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97861 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97862 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97863 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97864 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97865 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97866 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97867 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97868 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97869 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97870 + */
97871 +
97872 +/**************************************************************************//**
97873 +
97874 + @File part_ext.h
97875 +
97876 + @Description Definitions for the part (integration) module.
97877 +*//***************************************************************************/
97878 +
97879 +#ifndef __PART_EXT_H
97880 +#define __PART_EXT_H
97881 +
97882 +#include "std_ext.h"
97883 +#include "part_integration_ext.h"
97884 +
97885 +/**************************************************************************//*
97886 + @Description Part data structure - must be contained in any integration
97887 + data structure.
97888 +*//***************************************************************************/
97889 +typedef struct t_Part
97890 +{
97891 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97892 + /**< Returns the address of the module's memory map base. */
97893 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97894 + /**< Returns the module's ID according to its memory map base. */
97895 +} t_Part;
97896 +
97897 +
97898 +#endif /* __PART_EXT_H */
97899 --- /dev/null
97900 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
97901 @@ -0,0 +1,304 @@
97902 +/*
97903 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97904 + *
97905 + * Redistribution and use in source and binary forms, with or without
97906 + * modification, are permitted provided that the following conditions are met:
97907 + * * Redistributions of source code must retain the above copyright
97908 + * notice, this list of conditions and the following disclaimer.
97909 + * * Redistributions in binary form must reproduce the above copyright
97910 + * notice, this list of conditions and the following disclaimer in the
97911 + * documentation and/or other materials provided with the distribution.
97912 + * * Neither the name of Freescale Semiconductor nor the
97913 + * names of its contributors may be used to endorse or promote products
97914 + * derived from this software without specific prior written permission.
97915 + *
97916 + *
97917 + * ALTERNATIVELY, this software may be distributed under the terms of the
97918 + * GNU General Public License ("GPL") as published by the Free Software
97919 + * Foundation, either version 2 of that License or (at your option) any
97920 + * later version.
97921 + *
97922 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97923 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97924 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97925 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97926 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97927 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97928 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97930 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97931 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97932 + */
97933 +
97934 +/**
97935 +
97936 + @File part_integration_ext.h
97937 +
97938 + @Description T4240 external definitions and structures.
97939 +*//***************************************************************************/
97940 +#ifndef __PART_INTEGRATION_EXT_H
97941 +#define __PART_INTEGRATION_EXT_H
97942 +
97943 +#include "std_ext.h"
97944 +#include "ddr_std_ext.h"
97945 +#include "enet_ext.h"
97946 +#include "dpaa_integration_ext.h"
97947 +
97948 +
97949 +/**************************************************************************//**
97950 + @Group T4240_chip_id T4240 Application Programming Interface
97951 +
97952 + @Description T4240 Chip functions,definitions and enums.
97953 +
97954 + @{
97955 +*//***************************************************************************/
97956 +
97957 +#define CORE_E6500
97958 +
97959 +#define INTG_MAX_NUM_OF_CORES 24
97960 +
97961 +
97962 +/**************************************************************************//**
97963 + @Description Module types.
97964 +*//***************************************************************************/
97965 +typedef enum e_ModuleId
97966 +{
97967 + e_MODULE_ID_DUART_1 = 0,
97968 + e_MODULE_ID_DUART_2,
97969 + e_MODULE_ID_DUART_3,
97970 + e_MODULE_ID_DUART_4,
97971 + e_MODULE_ID_LAW,
97972 + e_MODULE_ID_IFC,
97973 + e_MODULE_ID_PAMU,
97974 + e_MODULE_ID_QM, /**< Queue manager module */
97975 + e_MODULE_ID_BM, /**< Buffer manager module */
97976 + e_MODULE_ID_QM_CE_PORTAL_0,
97977 + e_MODULE_ID_QM_CI_PORTAL_0,
97978 + e_MODULE_ID_QM_CE_PORTAL_1,
97979 + e_MODULE_ID_QM_CI_PORTAL_1,
97980 + e_MODULE_ID_QM_CE_PORTAL_2,
97981 + e_MODULE_ID_QM_CI_PORTAL_2,
97982 + e_MODULE_ID_QM_CE_PORTAL_3,
97983 + e_MODULE_ID_QM_CI_PORTAL_3,
97984 + e_MODULE_ID_QM_CE_PORTAL_4,
97985 + e_MODULE_ID_QM_CI_PORTAL_4,
97986 + e_MODULE_ID_QM_CE_PORTAL_5,
97987 + e_MODULE_ID_QM_CI_PORTAL_5,
97988 + e_MODULE_ID_QM_CE_PORTAL_6,
97989 + e_MODULE_ID_QM_CI_PORTAL_6,
97990 + e_MODULE_ID_QM_CE_PORTAL_7,
97991 + e_MODULE_ID_QM_CI_PORTAL_7,
97992 + e_MODULE_ID_QM_CE_PORTAL_8,
97993 + e_MODULE_ID_QM_CI_PORTAL_8,
97994 + e_MODULE_ID_QM_CE_PORTAL_9,
97995 + e_MODULE_ID_QM_CI_PORTAL_9,
97996 + e_MODULE_ID_BM_CE_PORTAL_0,
97997 + e_MODULE_ID_BM_CI_PORTAL_0,
97998 + e_MODULE_ID_BM_CE_PORTAL_1,
97999 + e_MODULE_ID_BM_CI_PORTAL_1,
98000 + e_MODULE_ID_BM_CE_PORTAL_2,
98001 + e_MODULE_ID_BM_CI_PORTAL_2,
98002 + e_MODULE_ID_BM_CE_PORTAL_3,
98003 + e_MODULE_ID_BM_CI_PORTAL_3,
98004 + e_MODULE_ID_BM_CE_PORTAL_4,
98005 + e_MODULE_ID_BM_CI_PORTAL_4,
98006 + e_MODULE_ID_BM_CE_PORTAL_5,
98007 + e_MODULE_ID_BM_CI_PORTAL_5,
98008 + e_MODULE_ID_BM_CE_PORTAL_6,
98009 + e_MODULE_ID_BM_CI_PORTAL_6,
98010 + e_MODULE_ID_BM_CE_PORTAL_7,
98011 + e_MODULE_ID_BM_CI_PORTAL_7,
98012 + e_MODULE_ID_BM_CE_PORTAL_8,
98013 + e_MODULE_ID_BM_CI_PORTAL_8,
98014 + e_MODULE_ID_BM_CE_PORTAL_9,
98015 + e_MODULE_ID_BM_CI_PORTAL_9,
98016 + e_MODULE_ID_FM, /**< Frame manager module */
98017 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98018 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98019 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98020 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98021 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98022 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98023 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98024 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98025 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98026 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98027 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98028 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98029 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98030 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98031 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98032 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98033 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98034 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98035 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98036 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98037 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98038 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98039 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98040 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98041 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98042 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98043 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98044 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98045 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98046 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98047 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98048 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98049 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98050 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98051 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98052 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98053 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98054 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98055 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98056 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98057 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98058 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98059 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98060 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98061 +
98062 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98063 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98064 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98065 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98066 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98067 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98068 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98069 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98070 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98071 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98072 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98073 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98074 +
98075 + e_MODULE_ID_PIC, /**< PIC */
98076 + e_MODULE_ID_GPIO, /**< GPIO */
98077 + e_MODULE_ID_SERDES, /**< SERDES */
98078 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98079 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98080 +
98081 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98082 +
98083 + e_MODULE_ID_DUMMY_LAST
98084 +} e_ModuleId;
98085 +
98086 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98087 +
98088 +#if 0 /* using unified values */
98089 +/*****************************************************************************
98090 + INTEGRATION-SPECIFIC MODULE CODES
98091 +******************************************************************************/
98092 +#define MODULE_UNKNOWN 0x00000000
98093 +#define MODULE_MEM 0x00010000
98094 +#define MODULE_MM 0x00020000
98095 +#define MODULE_CORE 0x00030000
98096 +#define MODULE_T4240 0x00040000
98097 +#define MODULE_T4240_PLATFORM 0x00050000
98098 +#define MODULE_PM 0x00060000
98099 +#define MODULE_MMU 0x00070000
98100 +#define MODULE_PIC 0x00080000
98101 +#define MODULE_CPC 0x00090000
98102 +#define MODULE_DUART 0x000a0000
98103 +#define MODULE_SERDES 0x000b0000
98104 +#define MODULE_PIO 0x000c0000
98105 +#define MODULE_QM 0x000d0000
98106 +#define MODULE_BM 0x000e0000
98107 +#define MODULE_SEC 0x000f0000
98108 +#define MODULE_LAW 0x00100000
98109 +#define MODULE_LBC 0x00110000
98110 +#define MODULE_PAMU 0x00120000
98111 +#define MODULE_FM 0x00130000
98112 +#define MODULE_FM_MURAM 0x00140000
98113 +#define MODULE_FM_PCD 0x00150000
98114 +#define MODULE_FM_RTC 0x00160000
98115 +#define MODULE_FM_MAC 0x00170000
98116 +#define MODULE_FM_PORT 0x00180000
98117 +#define MODULE_FM_SP 0x00190000
98118 +#define MODULE_DPA_PORT 0x001a0000
98119 +#define MODULE_MII 0x001b0000
98120 +#define MODULE_I2C 0x001c0000
98121 +#define MODULE_DMA 0x001d0000
98122 +#define MODULE_DDR 0x001e0000
98123 +#define MODULE_ESPI 0x001f0000
98124 +#define MODULE_DPAA_IPSEC 0x00200000
98125 +#endif /* using unified values */
98126 +
98127 +/*****************************************************************************
98128 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98129 +******************************************************************************/
98130 +#define PAMU_NUM_OF_PARTITIONS 4
98131 +
98132 +/*****************************************************************************
98133 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98134 +******************************************************************************/
98135 +#define LAW_NUM_OF_WINDOWS 32
98136 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98137 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98138 +
98139 +
98140 +/*****************************************************************************
98141 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98142 +******************************************************************************/
98143 +/**************************************************************************//**
98144 + @Group lbc_exception_grp LBC Exception Unit
98145 +
98146 + @Description LBC Exception unit API functions, definitions and enums
98147 +
98148 + @{
98149 +*//***************************************************************************/
98150 +
98151 +/**************************************************************************//**
98152 + @Anchor lbc_exbm
98153 +
98154 + @Collection LBC Errors Bit Mask
98155 +
98156 + These errors are reported through the exceptions callback..
98157 + The values can be or'ed in any combination in the errors mask
98158 + parameter of the errors report structure.
98159 +
98160 + These errors can also be passed as a bit-mask to
98161 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98162 + for enabling or disabling error checking.
98163 + @{
98164 +*//***************************************************************************/
98165 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98166 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98167 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98168 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98169 +
98170 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98171 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98172 + /**< All possible errors */
98173 +/* @} */
98174 +/** @} */ /* end of lbc_exception_grp group */
98175 +
98176 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98177 +
98178 +#define LBC_NUM_OF_BANKS 8
98179 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98180 +#define LBC_PARITY_SUPPORT
98181 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98182 +#define LBC_HIGH_CLK_DIVIDERS
98183 +#define LBC_FCM_AVAILABLE
98184 +
98185 +/*****************************************************************************
98186 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98187 +******************************************************************************/
98188 +#define GPIO_PORT_OFFSET_0x1000
98189 +
98190 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98191 + Each port contains up to 32 I/O pins. */
98192 +
98193 +#define GPIO_VALID_PIN_MASKS \
98194 + { /* Port A */ 0xFFFFFFFF, \
98195 + /* Port B */ 0xFFFFFFFF, \
98196 + /* Port C */ 0xFFFFFFFF }
98197 +
98198 +#define GPIO_VALID_INTR_MASKS \
98199 + { /* Port A */ 0xFFFFFFFF, \
98200 + /* Port B */ 0xFFFFFFFF, \
98201 + /* Port C */ 0xFFFFFFFF }
98202 +
98203 +
98204 +
98205 +#endif /* __PART_INTEGRATION_EXT_H */
98206 --- /dev/null
98207 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98208 @@ -0,0 +1,291 @@
98209 +/*
98210 + * Copyright 2012 Freescale Semiconductor Inc.
98211 + *
98212 + * Redistribution and use in source and binary forms, with or without
98213 + * modification, are permitted provided that the following conditions are met:
98214 + * * Redistributions of source code must retain the above copyright
98215 + * notice, this list of conditions and the following disclaimer.
98216 + * * Redistributions in binary form must reproduce the above copyright
98217 + * notice, this list of conditions and the following disclaimer in the
98218 + * documentation and/or other materials provided with the distribution.
98219 + * * Neither the name of Freescale Semiconductor nor the
98220 + * names of its contributors may be used to endorse or promote products
98221 + * derived from this software without specific prior written permission.
98222 + *
98223 + *
98224 + * ALTERNATIVELY, this software may be distributed under the terms of the
98225 + * GNU General Public License ("GPL") as published by the Free Software
98226 + * Foundation, either version 2 of that License or (at your option) any
98227 + * later version.
98228 + *
98229 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98230 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98231 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98232 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98233 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98234 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98235 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98236 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98237 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98238 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98239 + */
98240 +
98241 +/**
98242 +
98243 + @File dpaa_integration_ext.h
98244 +
98245 + @Description T4240 FM external definitions and structures.
98246 +*//***************************************************************************/
98247 +#ifndef __DPAA_INTEGRATION_EXT_H
98248 +#define __DPAA_INTEGRATION_EXT_H
98249 +
98250 +#include "std_ext.h"
98251 +
98252 +
98253 +#define DPAA_VERSION 11
98254 +
98255 +/**************************************************************************//**
98256 + @Description DPAA SW Portals Enumeration.
98257 +*//***************************************************************************/
98258 +typedef enum
98259 +{
98260 + e_DPAA_SWPORTAL0 = 0,
98261 + e_DPAA_SWPORTAL1,
98262 + e_DPAA_SWPORTAL2,
98263 + e_DPAA_SWPORTAL3,
98264 + e_DPAA_SWPORTAL4,
98265 + e_DPAA_SWPORTAL5,
98266 + e_DPAA_SWPORTAL6,
98267 + e_DPAA_SWPORTAL7,
98268 + e_DPAA_SWPORTAL8,
98269 + e_DPAA_SWPORTAL9,
98270 + e_DPAA_SWPORTAL10,
98271 + e_DPAA_SWPORTAL11,
98272 + e_DPAA_SWPORTAL12,
98273 + e_DPAA_SWPORTAL13,
98274 + e_DPAA_SWPORTAL14,
98275 + e_DPAA_SWPORTAL15,
98276 + e_DPAA_SWPORTAL16,
98277 + e_DPAA_SWPORTAL17,
98278 + e_DPAA_SWPORTAL18,
98279 + e_DPAA_SWPORTAL19,
98280 + e_DPAA_SWPORTAL20,
98281 + e_DPAA_SWPORTAL21,
98282 + e_DPAA_SWPORTAL22,
98283 + e_DPAA_SWPORTAL23,
98284 + e_DPAA_SWPORTAL24,
98285 + e_DPAA_SWPORTAL_DUMMY_LAST
98286 +} e_DpaaSwPortal;
98287 +
98288 +/**************************************************************************//**
98289 + @Description DPAA Direct Connect Portals Enumeration.
98290 +*//***************************************************************************/
98291 +typedef enum
98292 +{
98293 + e_DPAA_DCPORTAL0 = 0,
98294 + e_DPAA_DCPORTAL1,
98295 + e_DPAA_DCPORTAL2,
98296 + e_DPAA_DCPORTAL_DUMMY_LAST
98297 +} e_DpaaDcPortal;
98298 +
98299 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98300 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98301 +
98302 +/*****************************************************************************
98303 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98304 +******************************************************************************/
98305 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98306 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98307 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98308 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98309 + /**< FQIDs range - 24 bits */
98310 +
98311 +/**************************************************************************//**
98312 + @Description Work Queue Channel assignments in QMan.
98313 +*//***************************************************************************/
98314 +typedef enum
98315 +{
98316 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98317 + e_QM_FQ_CHANNEL_SWPORTAL1,
98318 + e_QM_FQ_CHANNEL_SWPORTAL2,
98319 + e_QM_FQ_CHANNEL_SWPORTAL3,
98320 + e_QM_FQ_CHANNEL_SWPORTAL4,
98321 + e_QM_FQ_CHANNEL_SWPORTAL5,
98322 + e_QM_FQ_CHANNEL_SWPORTAL6,
98323 + e_QM_FQ_CHANNEL_SWPORTAL7,
98324 + e_QM_FQ_CHANNEL_SWPORTAL8,
98325 + e_QM_FQ_CHANNEL_SWPORTAL9,
98326 + e_QM_FQ_CHANNEL_SWPORTAL10,
98327 + e_QM_FQ_CHANNEL_SWPORTAL11,
98328 + e_QM_FQ_CHANNEL_SWPORTAL12,
98329 + e_QM_FQ_CHANNEL_SWPORTAL13,
98330 + e_QM_FQ_CHANNEL_SWPORTAL14,
98331 + e_QM_FQ_CHANNEL_SWPORTAL15,
98332 + e_QM_FQ_CHANNEL_SWPORTAL16,
98333 + e_QM_FQ_CHANNEL_SWPORTAL17,
98334 + e_QM_FQ_CHANNEL_SWPORTAL18,
98335 + e_QM_FQ_CHANNEL_SWPORTAL19,
98336 + e_QM_FQ_CHANNEL_SWPORTAL20,
98337 + e_QM_FQ_CHANNEL_SWPORTAL21,
98338 + e_QM_FQ_CHANNEL_SWPORTAL22,
98339 + e_QM_FQ_CHANNEL_SWPORTAL23,
98340 + e_QM_FQ_CHANNEL_SWPORTAL24,
98341 +
98342 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98343 + e_QM_FQ_CHANNEL_POOL2,
98344 + e_QM_FQ_CHANNEL_POOL3,
98345 + e_QM_FQ_CHANNEL_POOL4,
98346 + e_QM_FQ_CHANNEL_POOL5,
98347 + e_QM_FQ_CHANNEL_POOL6,
98348 + e_QM_FQ_CHANNEL_POOL7,
98349 + e_QM_FQ_CHANNEL_POOL8,
98350 + e_QM_FQ_CHANNEL_POOL9,
98351 + e_QM_FQ_CHANNEL_POOL10,
98352 + e_QM_FQ_CHANNEL_POOL11,
98353 + e_QM_FQ_CHANNEL_POOL12,
98354 + e_QM_FQ_CHANNEL_POOL13,
98355 + e_QM_FQ_CHANNEL_POOL14,
98356 + e_QM_FQ_CHANNEL_POOL15,
98357 +
98358 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98359 + connected to FMan 0; assigned in incrementing order to
98360 + each sub-portal (SP) in the portal */
98361 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98362 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98363 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98364 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98365 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98366 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98367 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98368 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98369 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98370 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98371 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98372 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98373 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98374 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98375 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98376 +
98377 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98378 + e_QM_FQ_CHANNEL_RMAN_SP1,
98379 +
98380 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98381 + connected to SEC */
98382 +} e_QmFQChannel;
98383 +
98384 +/*****************************************************************************
98385 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98386 +******************************************************************************/
98387 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98388 +
98389 +/*****************************************************************************
98390 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98391 +******************************************************************************/
98392 +#define SEC_NUM_OF_DECOS 3
98393 +#define SEC_ALL_DECOS_MASK 0x00000003
98394 +
98395 +
98396 +/*****************************************************************************
98397 + FM INTEGRATION-SPECIFIC DEFINITIONS
98398 +******************************************************************************/
98399 +#define INTG_MAX_NUM_OF_FM 2
98400 +
98401 +/* Ports defines */
98402 +#define FM_MAX_NUM_OF_1G_MACS 6
98403 +#define FM_MAX_NUM_OF_10G_MACS 2
98404 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98405 +#define FM_MAX_NUM_OF_OH_PORTS 6
98406 +
98407 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98408 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98409 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98410 +
98411 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98412 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98413 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98414 +
98415 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98416 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98417 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98418 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98419 +
98420 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
98421 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98422 +
98423 +/* RAMs defines */
98424 +#define FM_MURAM_SIZE (384 * KILOBYTE)
98425 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
98426 +#define FM_NUM_OF_CTRL 4
98427 +
98428 +/* PCD defines */
98429 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98430 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98431 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98432 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98433 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98434 +
98435 +/* RTC defines */
98436 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98437 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98438 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98439 +
98440 +/* QMI defines */
98441 +#define QMI_MAX_NUM_OF_TNUMS 64
98442 +#define QMI_DEF_TNUMS_THRESH 32
98443 +/* FPM defines */
98444 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98445 +
98446 +/* DMA defines */
98447 +#define DMA_THRESH_MAX_COMMQ 83
98448 +#define DMA_THRESH_MAX_BUF 127
98449 +
98450 +/* BMI defines */
98451 +#define BMI_MAX_NUM_OF_TASKS 128
98452 +#define BMI_MAX_NUM_OF_DMAS 84
98453 +
98454 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98455 +#define PORT_MAX_WEIGHT 16
98456 +
98457 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98458 +
98459 +/* Unique T4240 */
98460 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98461 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98462 +#define FM_NO_OP_OBSERVED_POOLS
98463 +#define FM_FRAME_END_PARAMS_FOR_OP
98464 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98465 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98466 +
98467 +#define FM_NO_GUARANTEED_RESET_VALUES
98468 +
98469 +/* FM errata */
98470 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98471 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
98472 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98473 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98474 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98475 +
98476 +#define FM_BCB_ERRATA_BMI_SW001
98477 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98478 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98479 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98480 +
98481 +/*****************************************************************************
98482 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98483 +******************************************************************************/
98484 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98485 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98486 +
98487 +/* RMan erratas */
98488 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98489 +
98490 +/*****************************************************************************
98491 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98492 +******************************************************************************/
98493 +#define NUM_OF_RX_SC 16
98494 +#define NUM_OF_TX_SC 16
98495 +
98496 +#define NUM_OF_SA_PER_RX_SC 2
98497 +#define NUM_OF_SA_PER_TX_SC 2
98498 +
98499 +#endif /* __DPAA_INTEGRATION_EXT_H */
98500 --- /dev/null
98501 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
98502 @@ -0,0 +1,64 @@
98503 +/*
98504 + * Copyright 2012 Freescale Semiconductor Inc.
98505 + *
98506 + * Redistribution and use in source and binary forms, with or without
98507 + * modification, are permitted provided that the following conditions are met:
98508 + * * Redistributions of source code must retain the above copyright
98509 + * notice, this list of conditions and the following disclaimer.
98510 + * * Redistributions in binary form must reproduce the above copyright
98511 + * notice, this list of conditions and the following disclaimer in the
98512 + * documentation and/or other materials provided with the distribution.
98513 + * * Neither the name of Freescale Semiconductor nor the
98514 + * names of its contributors may be used to endorse or promote products
98515 + * derived from this software without specific prior written permission.
98516 + *
98517 + *
98518 + * ALTERNATIVELY, this software may be distributed under the terms of the
98519 + * GNU General Public License ("GPL") as published by the Free Software
98520 + * Foundation, either version 2 of that License or (at your option) any
98521 + * later version.
98522 + *
98523 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98524 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98525 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98526 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98527 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98528 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98529 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98530 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98531 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98532 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98533 + */
98534 +
98535 +/**************************************************************************//**
98536 +
98537 + @File part_ext.h
98538 +
98539 + @Description Definitions for the part (integration) module.
98540 +*//***************************************************************************/
98541 +
98542 +#ifndef __PART_EXT_H
98543 +#define __PART_EXT_H
98544 +
98545 +#include "std_ext.h"
98546 +#include "part_integration_ext.h"
98547 +
98548 +#if !(defined(LS1043))
98549 +#error "unable to proceed without chip-definition"
98550 +#endif
98551 +
98552 +
98553 +/**************************************************************************//*
98554 + @Description Part data structure - must be contained in any integration
98555 + data structure.
98556 +*//***************************************************************************/
98557 +typedef struct t_Part
98558 +{
98559 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98560 + /**< Returns the address of the module's memory map base. */
98561 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98562 + /**< Returns the module's ID according to its memory map base. */
98563 +} t_Part;
98564 +
98565 +
98566 +#endif /* __PART_EXT_H */
98567 --- /dev/null
98568 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
98569 @@ -0,0 +1,185 @@
98570 +/*
98571 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98572 + *
98573 + * Redistribution and use in source and binary forms, with or without
98574 + * modification, are permitted provided that the following conditions are met:
98575 + * * Redistributions of source code must retain the above copyright
98576 + * notice, this list of conditions and the following disclaimer.
98577 + * * Redistributions in binary form must reproduce the above copyright
98578 + * notice, this list of conditions and the following disclaimer in the
98579 + * documentation and/or other materials provided with the distribution.
98580 + * * Neither the name of Freescale Semiconductor nor the
98581 + * names of its contributors may be used to endorse or promote products
98582 + * derived from this software without specific prior written permission.
98583 + *
98584 + *
98585 + * ALTERNATIVELY, this software may be distributed under the terms of the
98586 + * GNU General Public License ("GPL") as published by the Free Software
98587 + * Foundation, either version 2 of that License or (at your option) any
98588 + * later version.
98589 + *
98590 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98591 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98592 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98593 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98594 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98595 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98596 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98597 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98598 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98599 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98600 + */
98601 +
98602 +/**
98603 +
98604 + @File part_integration_ext.h
98605 +
98606 + @Description T4240 external definitions and structures.
98607 +*//***************************************************************************/
98608 +#ifndef __PART_INTEGRATION_EXT_H
98609 +#define __PART_INTEGRATION_EXT_H
98610 +
98611 +#include "std_ext.h"
98612 +#include "ddr_std_ext.h"
98613 +#include "enet_ext.h"
98614 +#include "dpaa_integration_ext.h"
98615 +
98616 +
98617 +/**************************************************************************//**
98618 + @Group T4240_chip_id T4240 Application Programming Interface
98619 +
98620 + @Description T4240 Chip functions,definitions and enums.
98621 +
98622 + @{
98623 +*//***************************************************************************/
98624 +
98625 +#define INTG_MAX_NUM_OF_CORES 4
98626 +
98627 +/**************************************************************************//**
98628 + @Description Module types.
98629 +*//***************************************************************************/
98630 +typedef enum e_ModuleId
98631 +{
98632 + e_MODULE_ID_DUART_1 = 0,
98633 + e_MODULE_ID_DUART_2,
98634 + e_MODULE_ID_DUART_3,
98635 + e_MODULE_ID_DUART_4,
98636 + e_MODULE_ID_LAW,
98637 + e_MODULE_ID_IFC,
98638 + e_MODULE_ID_PAMU,
98639 + e_MODULE_ID_QM, /**< Queue manager module */
98640 + e_MODULE_ID_BM, /**< Buffer manager module */
98641 + e_MODULE_ID_QM_CE_PORTAL_0,
98642 + e_MODULE_ID_QM_CI_PORTAL_0,
98643 + e_MODULE_ID_QM_CE_PORTAL_1,
98644 + e_MODULE_ID_QM_CI_PORTAL_1,
98645 + e_MODULE_ID_QM_CE_PORTAL_2,
98646 + e_MODULE_ID_QM_CI_PORTAL_2,
98647 + e_MODULE_ID_QM_CE_PORTAL_3,
98648 + e_MODULE_ID_QM_CI_PORTAL_3,
98649 + e_MODULE_ID_QM_CE_PORTAL_4,
98650 + e_MODULE_ID_QM_CI_PORTAL_4,
98651 + e_MODULE_ID_QM_CE_PORTAL_5,
98652 + e_MODULE_ID_QM_CI_PORTAL_5,
98653 + e_MODULE_ID_QM_CE_PORTAL_6,
98654 + e_MODULE_ID_QM_CI_PORTAL_6,
98655 + e_MODULE_ID_QM_CE_PORTAL_7,
98656 + e_MODULE_ID_QM_CI_PORTAL_7,
98657 + e_MODULE_ID_QM_CE_PORTAL_8,
98658 + e_MODULE_ID_QM_CI_PORTAL_8,
98659 + e_MODULE_ID_QM_CE_PORTAL_9,
98660 + e_MODULE_ID_QM_CI_PORTAL_9,
98661 + e_MODULE_ID_BM_CE_PORTAL_0,
98662 + e_MODULE_ID_BM_CI_PORTAL_0,
98663 + e_MODULE_ID_BM_CE_PORTAL_1,
98664 + e_MODULE_ID_BM_CI_PORTAL_1,
98665 + e_MODULE_ID_BM_CE_PORTAL_2,
98666 + e_MODULE_ID_BM_CI_PORTAL_2,
98667 + e_MODULE_ID_BM_CE_PORTAL_3,
98668 + e_MODULE_ID_BM_CI_PORTAL_3,
98669 + e_MODULE_ID_BM_CE_PORTAL_4,
98670 + e_MODULE_ID_BM_CI_PORTAL_4,
98671 + e_MODULE_ID_BM_CE_PORTAL_5,
98672 + e_MODULE_ID_BM_CI_PORTAL_5,
98673 + e_MODULE_ID_BM_CE_PORTAL_6,
98674 + e_MODULE_ID_BM_CI_PORTAL_6,
98675 + e_MODULE_ID_BM_CE_PORTAL_7,
98676 + e_MODULE_ID_BM_CI_PORTAL_7,
98677 + e_MODULE_ID_BM_CE_PORTAL_8,
98678 + e_MODULE_ID_BM_CI_PORTAL_8,
98679 + e_MODULE_ID_BM_CE_PORTAL_9,
98680 + e_MODULE_ID_BM_CI_PORTAL_9,
98681 + e_MODULE_ID_FM, /**< Frame manager module */
98682 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98683 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98684 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98685 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98686 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98687 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98688 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98689 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98690 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98691 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98692 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98693 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98694 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98695 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98696 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98697 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98698 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98699 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98700 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98701 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98702 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98703 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98704 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98705 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98706 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98707 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98708 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98709 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98710 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98711 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98712 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98713 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98714 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98715 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98716 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98717 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98718 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98719 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98720 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98721 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98722 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98723 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98724 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98725 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98726 +
98727 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98728 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98729 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98730 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98731 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98732 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98733 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98734 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98735 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98736 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98737 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98738 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98739 +
98740 + e_MODULE_ID_PIC, /**< PIC */
98741 + e_MODULE_ID_GPIO, /**< GPIO */
98742 + e_MODULE_ID_SERDES, /**< SERDES */
98743 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98744 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98745 +
98746 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98747 +
98748 + e_MODULE_ID_DUMMY_LAST
98749 +} e_ModuleId;
98750 +
98751 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98752 +
98753 +
98754 +#endif /* __PART_INTEGRATION_EXT_H */
98755 --- /dev/null
98756 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
98757 @@ -0,0 +1,213 @@
98758 +/*
98759 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98760 + *
98761 + * Redistribution and use in source and binary forms, with or without
98762 + * modification, are permitted provided that the following conditions are met:
98763 + * * Redistributions of source code must retain the above copyright
98764 + * notice, this list of conditions and the following disclaimer.
98765 + * * Redistributions in binary form must reproduce the above copyright
98766 + * notice, this list of conditions and the following disclaimer in the
98767 + * documentation and/or other materials provided with the distribution.
98768 + * * Neither the name of Freescale Semiconductor nor the
98769 + * names of its contributors may be used to endorse or promote products
98770 + * derived from this software without specific prior written permission.
98771 + *
98772 + *
98773 + * ALTERNATIVELY, this software may be distributed under the terms of the
98774 + * GNU General Public License ("GPL") as published by the Free Software
98775 + * Foundation, either version 2 of that License or (at your option) any
98776 + * later version.
98777 + *
98778 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98779 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98780 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98781 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98782 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98783 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98784 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98785 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98786 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98787 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98788 + */
98789 +
98790 +
98791 +/**
98792 +
98793 + @File dpaa_integration_ext.h
98794 +
98795 + @Description P1023 FM external definitions and structures.
98796 +*//***************************************************************************/
98797 +#ifndef __DPAA_INTEGRATION_EXT_H
98798 +#define __DPAA_INTEGRATION_EXT_H
98799 +
98800 +#include "std_ext.h"
98801 +
98802 +
98803 +#define DPAA_VERSION 10
98804 +
98805 +typedef enum e_DpaaSwPortal {
98806 + e_DPAA_SWPORTAL0 = 0,
98807 + e_DPAA_SWPORTAL1,
98808 + e_DPAA_SWPORTAL2,
98809 + e_DPAA_SWPORTAL_DUMMY_LAST
98810 +} e_DpaaSwPortal;
98811 +
98812 +typedef enum {
98813 + e_DPAA_DCPORTAL0 = 0,
98814 + e_DPAA_DCPORTAL2,
98815 + e_DPAA_DCPORTAL_DUMMY_LAST
98816 +} e_DpaaDcPortal;
98817 +
98818 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98819 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98820 +
98821 +/*****************************************************************************
98822 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
98823 +******************************************************************************/
98824 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
98825 +#define QM_MAX_NUM_OF_WQ 8
98826 +#define QM_MAX_NUM_OF_SWP_AS 2
98827 +#define QM_MAX_NUM_OF_CGS 64
98828 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
98829 +
98830 +typedef enum {
98831 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
98832 + e_QM_FQ_CHANNEL_SWPORTAL1,
98833 + e_QM_FQ_CHANNEL_SWPORTAL2,
98834 +
98835 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
98836 + e_QM_FQ_CHANNEL_POOL2,
98837 + e_QM_FQ_CHANNEL_POOL3,
98838 +
98839 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
98840 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98841 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98842 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98843 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98844 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98845 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98846 +
98847 +
98848 + e_QM_FQ_CHANNEL_CAAM = 0x80
98849 +} e_QmFQChannel;
98850 +
98851 +/*****************************************************************************
98852 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
98853 +******************************************************************************/
98854 +#define BM_MAX_NUM_OF_POOLS 8
98855 +
98856 +/*****************************************************************************
98857 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98858 +******************************************************************************/
98859 +#define SEC_NUM_OF_DECOS 2
98860 +#define SEC_ALL_DECOS_MASK 0x00000003
98861 +#define SEC_RNGB
98862 +#define SEC_NO_ESP_TRAILER_REMOVAL
98863 +
98864 +/*****************************************************************************
98865 + FM INTEGRATION-SPECIFIC DEFINITIONS
98866 +******************************************************************************/
98867 +#define INTG_MAX_NUM_OF_FM 1
98868 +
98869 +/* Ports defines */
98870 +#define FM_MAX_NUM_OF_1G_MACS 2
98871 +#define FM_MAX_NUM_OF_10G_MACS 0
98872 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98873 +#define FM_MAX_NUM_OF_OH_PORTS 5
98874 +
98875 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98876 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98877 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98878 +
98879 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98880 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98881 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98882 +
98883 +#define FM_MAX_NUM_OF_MACSECS 1
98884 +
98885 +#define FM_MACSEC_SUPPORT
98886 +
98887 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
98888 +
98889 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98890 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
98891 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
98892 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
98893 +
98894 +/* Rams defines */
98895 +#define FM_MURAM_SIZE (64*KILOBYTE)
98896 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
98897 +#define FM_NUM_OF_CTRL 2
98898 +
98899 +/* PCD defines */
98900 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
98901 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
98902 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
98903 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< 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
98908 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
98909 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
98910 +
98911 +/* QMI defines */
98912 +#define QMI_MAX_NUM_OF_TNUMS 15
98913 +
98914 +/* FPM defines */
98915 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98916 +
98917 +/* DMA defines */
98918 +#define DMA_THRESH_MAX_COMMQ 15
98919 +#define DMA_THRESH_MAX_BUF 7
98920 +
98921 +/* BMI defines */
98922 +#define BMI_MAX_NUM_OF_TASKS 64
98923 +#define BMI_MAX_NUM_OF_DMAS 16
98924 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98925 +#define PORT_MAX_WEIGHT 4
98926 +
98927 +/*****************************************************************************
98928 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98929 +******************************************************************************/
98930 +#define NUM_OF_RX_SC 16
98931 +#define NUM_OF_TX_SC 16
98932 +
98933 +#define NUM_OF_SA_PER_RX_SC 2
98934 +#define NUM_OF_SA_PER_TX_SC 2
98935 +
98936 +/**************************************************************************//**
98937 + @Description Enum for inter-module interrupts registration
98938 +*//***************************************************************************/
98939 +
98940 +/* 1023 unique features */
98941 +#define FM_QMI_NO_ECC_EXCEPTIONS
98942 +#define FM_CSI_CFED_LIMIT
98943 +#define FM_PEDANTIC_DMA
98944 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
98945 +#define FM_FIFO_ALLOCATION_ALG
98946 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98947 +#define FM_HAS_TOTAL_DMAS
98948 +#define FM_KG_NO_IPPID_SUPPORT
98949 +#define FM_NO_GUARANTEED_RESET_VALUES
98950 +#define FM_MAC_RESET
98951 +
98952 +/* FM erratas */
98953 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
98954 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
98955 +
98956 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
98957 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
98958 +
98959 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
98960 +
98961 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
98962 +
98963 +/*
98964 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
98965 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
98966 +*/
98967 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
98968 +
98969 +
98970 +#endif /* __DPAA_INTEGRATION_EXT_H */
98971 --- /dev/null
98972 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
98973 @@ -0,0 +1,82 @@
98974 +/*
98975 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98976 + *
98977 + * Redistribution and use in source and binary forms, with or without
98978 + * modification, are permitted provided that the following conditions are met:
98979 + * * Redistributions of source code must retain the above copyright
98980 + * notice, this list of conditions and the following disclaimer.
98981 + * * Redistributions in binary form must reproduce the above copyright
98982 + * notice, this list of conditions and the following disclaimer in the
98983 + * documentation and/or other materials provided with the distribution.
98984 + * * Neither the name of Freescale Semiconductor nor the
98985 + * names of its contributors may be used to endorse or promote products
98986 + * derived from this software without specific prior written permission.
98987 + *
98988 + *
98989 + * ALTERNATIVELY, this software may be distributed under the terms of the
98990 + * GNU General Public License ("GPL") as published by the Free Software
98991 + * Foundation, either version 2 of that License or (at your option) any
98992 + * later version.
98993 + *
98994 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98995 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98996 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98997 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98998 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98999 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99000 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99001 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99002 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99003 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99004 + */
99005 +
99006 +
99007 +/**************************************************************************//**
99008 +
99009 + @File part_ext.h
99010 +
99011 + @Description Definitions for the part (integration) module.
99012 +*//***************************************************************************/
99013 +
99014 +#ifndef __PART_EXT_H
99015 +#define __PART_EXT_H
99016 +
99017 +#include "std_ext.h"
99018 +#include "part_integration_ext.h"
99019 +
99020 +
99021 +#if !(defined(MPC8306) || \
99022 + defined(MPC8309) || \
99023 + defined(MPC834x) || \
99024 + defined(MPC836x) || \
99025 + defined(MPC832x) || \
99026 + defined(MPC837x) || \
99027 + defined(MPC8568) || \
99028 + defined(MPC8569) || \
99029 + defined(P1020) || \
99030 + defined(P1021) || \
99031 + defined(P1022) || \
99032 + defined(P1023) || \
99033 + defined(P2020) || \
99034 + defined(P3041) || \
99035 + defined(P4080) || \
99036 + defined(P5020) || \
99037 + defined(MSC814x))
99038 +#error "unable to proceed without chip-definition"
99039 +#endif
99040 +
99041 +
99042 +/**************************************************************************//*
99043 + @Description Part data structure - must be contained in any integration
99044 + data structure.
99045 +*//***************************************************************************/
99046 +typedef struct t_Part
99047 +{
99048 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99049 + /**< Returns the address of the module's memory map base. */
99050 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
99051 + /**< Returns the module's ID according to its memory map base. */
99052 +} t_Part;
99053 +
99054 +
99055 +#endif /* __PART_EXT_H */
99056 --- /dev/null
99057 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99058 @@ -0,0 +1,635 @@
99059 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
99060 + * All rights reserved.
99061 + *
99062 + * Redistribution and use in source and binary forms, with or without
99063 + * modification, are permitted provided that the following conditions are met:
99064 + * * Redistributions of source code must retain the above copyright
99065 + * notice, this list of conditions and the following disclaimer.
99066 + * * Redistributions in binary form must reproduce the above copyright
99067 + * notice, this list of conditions and the following disclaimer in the
99068 + * documentation and/or other materials provided with the distribution.
99069 + * * Neither the name of Freescale Semiconductor nor the
99070 + * names of its contributors may be used to endorse or promote products
99071 + * derived from this software without specific prior written permission.
99072 + *
99073 + *
99074 + * ALTERNATIVELY, this software may be distributed under the terms of the
99075 + * GNU General Public License ("GPL") as published by the Free Software
99076 + * Foundation, either version 2 of that License or (at your option) any
99077 + * later version.
99078 + *
99079 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99080 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99081 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99082 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99083 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99084 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99085 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99086 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99087 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99088 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99089 + */
99090 +
99091 +/**************************************************************************//**
99092 + @File part_integration_ext.h
99093 +
99094 + @Description P1023 external definitions and structures.
99095 +*//***************************************************************************/
99096 +#ifndef __PART_INTEGRATION_EXT_H
99097 +#define __PART_INTEGRATION_EXT_H
99098 +
99099 +#include "std_ext.h"
99100 +#include "dpaa_integration_ext.h"
99101 +
99102 +
99103 +/**************************************************************************//**
99104 + @Group 1023_chip_id P1023 Application Programming Interface
99105 +
99106 + @Description P1023 Chip functions,definitions and enums.
99107 +
99108 + @{
99109 +*//***************************************************************************/
99110 +
99111 +#define INTG_MAX_NUM_OF_CORES 2
99112 +
99113 +
99114 +/**************************************************************************//**
99115 + @Description Module types.
99116 +*//***************************************************************************/
99117 +typedef enum e_ModuleId
99118 +{
99119 + e_MODULE_ID_LAW, /**< Local Access module */
99120 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
99121 + e_MODULE_ID_DDR, /**< DDR memory controller */
99122 + e_MODULE_ID_I2C_1, /**< I2C 1 */
99123 + e_MODULE_ID_I2C_2, /**< I2C 1 */
99124 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
99125 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
99126 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
99127 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
99128 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
99129 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
99130 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
99131 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
99132 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
99133 + e_MODULE_ID_MSI, /**< MSI registers */
99134 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
99135 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
99136 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
99137 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
99138 + e_MODULE_ID_ESPI, /**< ESPI module */
99139 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
99140 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99141 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99142 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99143 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99144 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99145 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99146 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99147 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99148 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99149 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99150 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99151 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99152 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
99153 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
99154 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
99155 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
99156 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
99157 + e_MODULE_ID_GUTS, /**< Serial DMA */
99158 + e_MODULE_ID_PM, /**< Performance Monitor module */
99159 + e_MODULE_ID_QM, /**< Queue manager module */
99160 + e_MODULE_ID_BM, /**< Buffer manager module */
99161 + e_MODULE_ID_QM_CE_PORTAL,
99162 + e_MODULE_ID_QM_CI_PORTAL,
99163 + e_MODULE_ID_BM_CE_PORTAL,
99164 + e_MODULE_ID_BM_CI_PORTAL,
99165 + e_MODULE_ID_FM, /**< Frame manager #1 module */
99166 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99167 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99168 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99169 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99170 + e_MODULE_ID_FM_PRS, /**< FM parser block */
99171 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
99172 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99173 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99174 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99175 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99176 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
99177 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99178 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
99179 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99180 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99181 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99182 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99183 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99184 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99185 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
99186 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
99187 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99188 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
99189 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
99190 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
99191 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99192 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
99193 +
99194 + e_MODULE_ID_DUMMY_LAST
99195 +} e_ModuleId;
99196 +
99197 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99198 +
99199 +
99200 +#define P1023_OFFSET_LAW 0x00000C08
99201 +#define P1023_OFFSET_ECM 0x00001000
99202 +#define P1023_OFFSET_DDR 0x00002000
99203 +#define P1023_OFFSET_I2C1 0x00003000
99204 +#define P1023_OFFSET_I2C2 0x00003100
99205 +#define P1023_OFFSET_DUART1 0x00004500
99206 +#define P1023_OFFSET_DUART2 0x00004600
99207 +#define P1023_OFFSET_LBC 0x00005000
99208 +#define P1023_OFFSET_ESPI 0x00007000
99209 +#define P1023_OFFSET_PCIE2 0x00009000
99210 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
99211 +#define P1023_OFFSET_PCIE1 0x0000A000
99212 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
99213 +#define P1023_OFFSET_PCIE3 0x0000B000
99214 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
99215 +#define P1023_OFFSET_DMA2 0x0000C100
99216 +#define P1023_OFFSET_GPIO 0x0000F000
99217 +#define P1023_OFFSET_L2_SRAM 0x00020000
99218 +#define P1023_OFFSET_DMA1 0x00021100
99219 +#define P1023_OFFSET_USB1 0x00022000
99220 +#define P1023_OFFSET_SEC_GEN 0x00030000
99221 +#define P1023_OFFSET_SEC_JQ0 0x00031000
99222 +#define P1023_OFFSET_SEC_JQ1 0x00032000
99223 +#define P1023_OFFSET_SEC_JQ2 0x00033000
99224 +#define P1023_OFFSET_SEC_JQ3 0x00034000
99225 +#define P1023_OFFSET_SEC_RTIC 0x00036000
99226 +#define P1023_OFFSET_SEC_QI 0x00037000
99227 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
99228 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
99229 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
99230 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
99231 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
99232 +#define P1023_OFFSET_PIC 0x00040000
99233 +#define P1023_OFFSET_MSI 0x00041600
99234 +#define P1023_OFFSET_AXI 0x00081000
99235 +#define P1023_OFFSET_QM 0x00088000
99236 +#define P1023_OFFSET_BM 0x0008A000
99237 +#define P1022_OFFSET_PM 0x000E1000
99238 +
99239 +#define P1023_OFFSET_GUTIL 0x000E0000
99240 +#define P1023_OFFSET_PM 0x000E1000
99241 +#define P1023_OFFSET_DEBUG 0x000E2000
99242 +#define P1023_OFFSET_SERDES 0x000E3000
99243 +#define P1023_OFFSET_ROM 0x000F0000
99244 +#define P1023_OFFSET_FM 0x00100000
99245 +
99246 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
99247 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
99248 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
99249 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
99250 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
99251 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
99252 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
99253 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
99254 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
99255 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
99256 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
99257 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
99258 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
99259 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
99260 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
99261 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
99262 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
99263 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
99264 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
99265 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
99266 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
99267 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
99268 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
99269 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
99270 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
99271 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
99272 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
99273 +
99274 +/* Offsets relative to QM or BM portals base */
99275 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
99276 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
99277 +
99278 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
99279 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
99280 +
99281 +/**************************************************************************//**
99282 + @Description Transaction source ID (for memory controllers error reporting).
99283 +*//***************************************************************************/
99284 +typedef enum e_TransSrc
99285 +{
99286 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
99287 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
99288 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
99289 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
99290 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
99291 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
99292 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
99293 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
99294 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
99295 +} e_TransSrc;
99296 +
99297 +/**************************************************************************//**
99298 + @Description Local Access Window Target interface ID
99299 +*//***************************************************************************/
99300 +typedef enum e_P1023LawTargetId
99301 +{
99302 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
99303 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
99304 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
99305 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
99306 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
99307 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
99308 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
99309 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
99310 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
99311 +} e_P1023LawTargetId;
99312 +
99313 +
99314 +/**************************************************************************//**
99315 + @Group 1023_init_grp P1023 Initialization Unit
99316 +
99317 + @Description P1023 initialization unit API functions, definitions and enums
99318 +
99319 + @{
99320 +*//***************************************************************************/
99321 +
99322 +/**************************************************************************//**
99323 + @Description Part ID and revision number
99324 +*//***************************************************************************/
99325 +typedef enum e_P1023DeviceName
99326 +{
99327 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
99328 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
99329 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
99330 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
99331 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
99332 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
99333 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
99334 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
99335 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
99336 +} e_P1023DeviceName;
99337 +
99338 +/**************************************************************************//**
99339 + @Description structure representing P1023 initialization parameters
99340 +*//***************************************************************************/
99341 +typedef struct t_P1023Params
99342 +{
99343 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
99344 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
99345 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
99346 +} t_P1023Params;
99347 +
99348 +/**************************************************************************//**
99349 + @Function P1023_ConfigAndInit
99350 +
99351 + @Description General initiation of the chip registers.
99352 +
99353 + @Param[in] p_P1023Params - A pointer to data structure of parameters
99354 +
99355 + @Return A handle to the P1023 data structure.
99356 +*//***************************************************************************/
99357 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
99358 +
99359 +/**************************************************************************//**
99360 + @Function P1023_Free
99361 +
99362 + @Description Free all resources.
99363 +
99364 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
99365 +
99366 + @Return E_OK on success; Other value otherwise.
99367 +*//***************************************************************************/
99368 +t_Error P1023_Free(t_Handle h_P1023);
99369 +
99370 +/**************************************************************************//**
99371 + @Function P1023_GetRevInfo
99372 +
99373 + @Description This routine enables access to chip and revision information.
99374 +
99375 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99376 +
99377 + @Return Part ID and revision.
99378 +*//***************************************************************************/
99379 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
99380 +
99381 +/**************************************************************************//**
99382 + @Function P1023_GetE500Factor
99383 +
99384 + @Description Returns E500 core clock multiplication factor.
99385 +
99386 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99387 + @Param[in] coreId - Id of the requested core.
99388 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
99389 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
99390 +
99391 + @Return E_OK on success; Other value otherwise.
99392 +*
99393 +*//***************************************************************************/
99394 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
99395 + uint32_t coreId,
99396 + uint32_t *p_E500MulFactor,
99397 + uint32_t *p_E500DivFactor);
99398 +
99399 +/**************************************************************************//**
99400 + @Function P1023_GetFmFactor
99401 +
99402 + @Description returns FM multiplication factors. (This value is returned using
99403 + two parameters to avoid using float parameter).
99404 +
99405 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99406 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
99407 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
99408 +
99409 + @Return E_OK on success; Other value otherwise.
99410 +*//***************************************************************************/
99411 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
99412 +
99413 +/**************************************************************************//**
99414 + @Function P1023_GetCcbFactor
99415 +
99416 + @Description returns system multiplication factor.
99417 +
99418 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99419 +
99420 + @Return System multiplication factor.
99421 +*//***************************************************************************/
99422 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
99423 +
99424 +#if 0
99425 +/**************************************************************************//**
99426 + @Function P1023_GetDdrFactor
99427 +
99428 + @Description returns the multiplication factor of the clock in for the DDR clock .
99429 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
99430 +
99431 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99432 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
99433 + @Param p_DdrDivFactor - returns DDR division factor.
99434 +
99435 + @Return E_OK on success; Other value otherwise..
99436 +*//***************************************************************************/
99437 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
99438 + uint32_t *p_DdrMulFactor,
99439 + uint32_t *p_DdrDivFactor);
99440 +
99441 +/**************************************************************************//**
99442 + @Function P1023_GetDdrType
99443 +
99444 + @Description returns the multiplication factor of the clock in for the DDR clock .
99445 +
99446 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99447 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
99448 +
99449 + @Return E_OK on success; Other value otherwise.
99450 +*//***************************************************************************/
99451 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
99452 +#endif
99453 +
99454 +/** @} */ /* end of 1023_init_grp group */
99455 +/** @} */ /* end of 1023_grp group */
99456 +
99457 +#define CORE_E500V2
99458 +
99459 +#if 0 /* using unified values */
99460 +/*****************************************************************************
99461 + INTEGRATION-SPECIFIC MODULE CODES
99462 +******************************************************************************/
99463 +#define MODULE_UNKNOWN 0x00000000
99464 +#define MODULE_MEM 0x00010000
99465 +#define MODULE_MM 0x00020000
99466 +#define MODULE_CORE 0x00030000
99467 +#define MODULE_P1023 0x00040000
99468 +#define MODULE_MII 0x00050000
99469 +#define MODULE_PM 0x00060000
99470 +#define MODULE_MMU 0x00070000
99471 +#define MODULE_PIC 0x00080000
99472 +#define MODULE_L2_CACHE 0x00090000
99473 +#define MODULE_DUART 0x000a0000
99474 +#define MODULE_SERDES 0x000b0000
99475 +#define MODULE_PIO 0x000c0000
99476 +#define MODULE_QM 0x000d0000
99477 +#define MODULE_BM 0x000e0000
99478 +#define MODULE_SEC 0x000f0000
99479 +#define MODULE_FM 0x00100000
99480 +#define MODULE_FM_MURAM 0x00110000
99481 +#define MODULE_FM_PCD 0x00120000
99482 +#define MODULE_FM_RTC 0x00130000
99483 +#define MODULE_FM_MAC 0x00140000
99484 +#define MODULE_FM_PORT 0x00150000
99485 +#define MODULE_FM_MACSEC 0x00160000
99486 +#define MODULE_FM_MACSEC_SECY 0x00170000
99487 +#define MODULE_FM_SP 0x00280000
99488 +#define MODULE_ECM 0x00190000
99489 +#define MODULE_DMA 0x001a0000
99490 +#define MODULE_DDR 0x001b0000
99491 +#define MODULE_LAW 0x001c0000
99492 +#define MODULE_LBC 0x001d0000
99493 +#define MODULE_I2C 0x001e0000
99494 +#define MODULE_ESPI 0x001f0000
99495 +#define MODULE_PCI 0x00200000
99496 +#define MODULE_DPA_PORT 0x00210000
99497 +#define MODULE_USB 0x00220000
99498 +#endif /* using unified values */
99499 +
99500 +/*****************************************************************************
99501 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99502 +******************************************************************************/
99503 +/**************************************************************************//**
99504 + @Group lbc_exception_grp LBC Exception Unit
99505 +
99506 + @Description LBC Exception unit API functions, definitions and enums
99507 +
99508 + @{
99509 +*//***************************************************************************/
99510 +
99511 +/**************************************************************************//**
99512 + @Anchor lbc_exbm
99513 +
99514 + @Collection LBC Errors Bit Mask
99515 +
99516 + These errors are reported through the exceptions callback..
99517 + The values can be or'ed in any combination in the errors mask
99518 + parameter of the errors report structure.
99519 +
99520 + These errors can also be passed as a bit-mask to
99521 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99522 + for enabling or disabling error checking.
99523 + @{
99524 +*//***************************************************************************/
99525 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99526 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99527 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99528 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99529 +
99530 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99531 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99532 + /**< All possible errors */
99533 +/* @} */
99534 +/** @} */ /* end of lbc_exception_grp group */
99535 +
99536 +#define LBC_NUM_OF_BANKS 2
99537 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
99538 +#define LBC_ATOMIC_OPERATION_SUPPORT
99539 +#define LBC_PARITY_SUPPORT
99540 +#define LBC_ADDRESS_SHIFT_SUPPORT
99541 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99542 +#define LBC_HIGH_CLK_DIVIDERS
99543 +#define LBC_FCM_AVAILABLE
99544 +
99545 +
99546 +/*****************************************************************************
99547 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99548 +******************************************************************************/
99549 +#define LAW_ARCH_CCB
99550 +#define LAW_NUM_OF_WINDOWS 12
99551 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
99552 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
99553 +
99554 +
99555 +/*****************************************************************************
99556 + SPI INTEGRATION-SPECIFIC DEFINITIONS
99557 +******************************************************************************/
99558 +#define SPI_NUM_OF_CONTROLLERS 1
99559 +
99560 +/*****************************************************************************
99561 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
99562 +******************************************************************************/
99563 +
99564 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
99565 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
99566 +
99567 +/**************************************************************************//**
99568 + @Description Target interface of an inbound window
99569 +*//***************************************************************************/
99570 +typedef enum e_PciTargetInterface
99571 +{
99572 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
99573 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
99574 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
99575 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
99576 +
99577 +} e_PciTargetInterface;
99578 +
99579 +/*****************************************************************************
99580 + DDR INTEGRATION-SPECIFIC DEFINITIONS
99581 +******************************************************************************/
99582 +#define DDR_NUM_OF_VALID_CS 2
99583 +
99584 +/*****************************************************************************
99585 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99586 +******************************************************************************/
99587 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
99588 +
99589 +/*****************************************************************************
99590 + DMA INTEGRATION-SPECIFIC DEFINITIONS
99591 +******************************************************************************/
99592 +#define DMA_NUM_OF_CONTROLLERS 2
99593 +
99594 +
99595 +
99596 +
99597 +/*****************************************************************************
99598 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
99599 +******************************************************************************/
99600 +#define PTP_V2
99601 +
99602 +/**************************************************************************//**
99603 + @Function P1023_GetMuxControlReg
99604 +
99605 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
99606 + Control Register)
99607 +
99608 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99609 +
99610 + @Return Value of PMUXCR
99611 +*//***************************************************************************/
99612 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
99613 +
99614 +/**************************************************************************//**
99615 + @Function P1023_SetMuxControlReg
99616 +
99617 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
99618 + Control Register)
99619 +
99620 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99621 + @Param[in] val - the new value for PMUXCR.
99622 +
99623 + @Return None
99624 +*//***************************************************************************/
99625 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
99626 +
99627 +/**************************************************************************//**
99628 + @Function P1023_GetDeviceDisableStatusRegister
99629 +
99630 + @Description Returns the value of DEVDISR (Device Disable Register)
99631 +
99632 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99633 +
99634 + @Return Value of DEVDISR
99635 +*//***************************************************************************/
99636 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
99637 +
99638 +/**************************************************************************//**
99639 + @Function P1023_GetPorDeviceStatusRegister
99640 +
99641 + @Description Returns the value of POR Device Status Register
99642 +
99643 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99644 +
99645 + @Return POR Device Status Register
99646 +*//***************************************************************************/
99647 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
99648 +
99649 +/**************************************************************************//**
99650 + @Function P1023_GetPorBootModeStatusRegister
99651 +
99652 + @Description Returns the value of POR Boot Mode Status Register
99653 +
99654 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99655 +
99656 + @Return POR Boot Mode Status Register value
99657 +*//***************************************************************************/
99658 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
99659 +
99660 +
99661 +#define PORDEVSR_SGMII1_DIS 0x10000000
99662 +#define PORDEVSR_SGMII2_DIS 0x08000000
99663 +#define PORDEVSR_ECP1 0x02000000
99664 +#define PORDEVSR_IO_SEL 0x00780000
99665 +#define PORDEVSR_IO_SEL_SHIFT 19
99666 +#define PORBMSR_HA 0x00070000
99667 +#define PORBMSR_HA_SHIFT 16
99668 +
99669 +#define DEVDISR_QM_BM 0x80000000
99670 +#define DEVDISR_FM 0x40000000
99671 +#define DEVDISR_PCIE1 0x20000000
99672 +#define DEVDISR_MAC_SEC 0x10000000
99673 +#define DEVDISR_ELBC 0x08000000
99674 +#define DEVDISR_PCIE2 0x04000000
99675 +#define DEVDISR_PCIE3 0x02000000
99676 +#define DEVDISR_CAAM 0x01000000
99677 +#define DEVDISR_USB0 0x00800000
99678 +#define DEVDISR_1588 0x00020000
99679 +#define DEVDISR_CORE0 0x00008000
99680 +#define DEVDISR_TB0 0x00004000
99681 +#define DEVDISR_CORE1 0x00002000
99682 +#define DEVDISR_TB1 0x00001000
99683 +#define DEVDISR_DMA1 0x00000400
99684 +#define DEVDISR_DMA2 0x00000200
99685 +#define DEVDISR_DDR 0x00000010
99686 +#define DEVDISR_TSEC1 0x00000080
99687 +#define DEVDISR_TSEC2 0x00000040
99688 +#define DEVDISR_SPI 0x00000008
99689 +#define DEVDISR_I2C 0x00000004
99690 +#define DEVDISR_DUART 0x00000002
99691 +
99692 +
99693 +#endif /* __PART_INTEGRATION_EXT_H */
99694 --- /dev/null
99695 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
99696 @@ -0,0 +1,276 @@
99697 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
99698 + * All rights reserved.
99699 + *
99700 + * Redistribution and use in source and binary forms, with or without
99701 + * modification, are permitted provided that the following conditions are met:
99702 + * * Redistributions of source code must retain the above copyright
99703 + * notice, this list of conditions and the following disclaimer.
99704 + * * Redistributions in binary form must reproduce the above copyright
99705 + * notice, this list of conditions and the following disclaimer in the
99706 + * documentation and/or other materials provided with the distribution.
99707 + * * Neither the name of Freescale Semiconductor nor the
99708 + * names of its contributors may be used to endorse or promote products
99709 + * derived from this software without specific prior written permission.
99710 + *
99711 + *
99712 + * ALTERNATIVELY, this software may be distributed under the terms of the
99713 + * GNU General Public License ("GPL") as published by the Free Software
99714 + * Foundation, either version 2 of that License or (at your option) any
99715 + * later version.
99716 + *
99717 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99718 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99719 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99720 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99721 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99722 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99723 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99724 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99725 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99726 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99727 + */
99728 +
99729 +/**************************************************************************//**
99730 + @File dpaa_integration_ext.h
99731 +
99732 + @Description P3040/P4080/P5020 FM external definitions and structures.
99733 +*//***************************************************************************/
99734 +#ifndef __DPAA_INTEGRATION_EXT_H
99735 +#define __DPAA_INTEGRATION_EXT_H
99736 +
99737 +#include "std_ext.h"
99738 +
99739 +
99740 +#define DPAA_VERSION 10
99741 +
99742 +typedef enum {
99743 + e_DPAA_SWPORTAL0 = 0,
99744 + e_DPAA_SWPORTAL1,
99745 + e_DPAA_SWPORTAL2,
99746 + e_DPAA_SWPORTAL3,
99747 + e_DPAA_SWPORTAL4,
99748 + e_DPAA_SWPORTAL5,
99749 + e_DPAA_SWPORTAL6,
99750 + e_DPAA_SWPORTAL7,
99751 + e_DPAA_SWPORTAL8,
99752 + e_DPAA_SWPORTAL9,
99753 + e_DPAA_SWPORTAL_DUMMY_LAST
99754 +} e_DpaaSwPortal;
99755 +
99756 +typedef enum {
99757 + e_DPAA_DCPORTAL0 = 0,
99758 + e_DPAA_DCPORTAL1,
99759 + e_DPAA_DCPORTAL2,
99760 + e_DPAA_DCPORTAL3,
99761 + e_DPAA_DCPORTAL4,
99762 + e_DPAA_DCPORTAL_DUMMY_LAST
99763 +} e_DpaaDcPortal;
99764 +
99765 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99766 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99767 +
99768 +/*****************************************************************************
99769 + QMan INTEGRATION-SPECIFIC DEFINITIONS
99770 +******************************************************************************/
99771 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
99772 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
99773 +#define QM_MAX_NUM_OF_SWP_AS 4
99774 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
99775 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
99776 +
99777 +/**************************************************************************//**
99778 + @Description Work Queue Channel assignments in QMan.
99779 +*//***************************************************************************/
99780 +typedef enum
99781 +{
99782 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
99783 + e_QM_FQ_CHANNEL_SWPORTAL1,
99784 + e_QM_FQ_CHANNEL_SWPORTAL2,
99785 + e_QM_FQ_CHANNEL_SWPORTAL3,
99786 + e_QM_FQ_CHANNEL_SWPORTAL4,
99787 + e_QM_FQ_CHANNEL_SWPORTAL5,
99788 + e_QM_FQ_CHANNEL_SWPORTAL6,
99789 + e_QM_FQ_CHANNEL_SWPORTAL7,
99790 + e_QM_FQ_CHANNEL_SWPORTAL8,
99791 + e_QM_FQ_CHANNEL_SWPORTAL9,
99792 +
99793 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
99794 + e_QM_FQ_CHANNEL_POOL2,
99795 + e_QM_FQ_CHANNEL_POOL3,
99796 + e_QM_FQ_CHANNEL_POOL4,
99797 + e_QM_FQ_CHANNEL_POOL5,
99798 + e_QM_FQ_CHANNEL_POOL6,
99799 + e_QM_FQ_CHANNEL_POOL7,
99800 + e_QM_FQ_CHANNEL_POOL8,
99801 + e_QM_FQ_CHANNEL_POOL9,
99802 + e_QM_FQ_CHANNEL_POOL10,
99803 + e_QM_FQ_CHANNEL_POOL11,
99804 + e_QM_FQ_CHANNEL_POOL12,
99805 + e_QM_FQ_CHANNEL_POOL13,
99806 + e_QM_FQ_CHANNEL_POOL14,
99807 + e_QM_FQ_CHANNEL_POOL15,
99808 +
99809 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
99810 + connected to FMan 0; assigned in incrementing order to
99811 + each sub-portal (SP) in the portal */
99812 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99813 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99814 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99815 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99816 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99817 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99818 + e_QM_FQ_CHANNEL_FMAN0_SP7,
99819 + e_QM_FQ_CHANNEL_FMAN0_SP8,
99820 + e_QM_FQ_CHANNEL_FMAN0_SP9,
99821 + e_QM_FQ_CHANNEL_FMAN0_SP10,
99822 + e_QM_FQ_CHANNEL_FMAN0_SP11,
99823 +/* difference between 5020 and 4080 :) */
99824 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
99825 + e_QM_FQ_CHANNEL_FMAN1_SP1,
99826 + e_QM_FQ_CHANNEL_FMAN1_SP2,
99827 + e_QM_FQ_CHANNEL_FMAN1_SP3,
99828 + e_QM_FQ_CHANNEL_FMAN1_SP4,
99829 + e_QM_FQ_CHANNEL_FMAN1_SP5,
99830 + e_QM_FQ_CHANNEL_FMAN1_SP6,
99831 + e_QM_FQ_CHANNEL_FMAN1_SP7,
99832 + e_QM_FQ_CHANNEL_FMAN1_SP8,
99833 + e_QM_FQ_CHANNEL_FMAN1_SP9,
99834 + e_QM_FQ_CHANNEL_FMAN1_SP10,
99835 + e_QM_FQ_CHANNEL_FMAN1_SP11,
99836 +
99837 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
99838 + connected to SEC 4.x */
99839 +
99840 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
99841 + connected to PME */
99842 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
99843 + connected to RAID */
99844 +} e_QmFQChannel;
99845 +
99846 +/*****************************************************************************
99847 + BMan INTEGRATION-SPECIFIC DEFINITIONS
99848 +******************************************************************************/
99849 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
99850 +
99851 +
99852 +/*****************************************************************************
99853 + FM INTEGRATION-SPECIFIC DEFINITIONS
99854 +******************************************************************************/
99855 +#define INTG_MAX_NUM_OF_FM 2
99856 +
99857 +/* Ports defines */
99858 +#define FM_MAX_NUM_OF_1G_MACS 5
99859 +#define FM_MAX_NUM_OF_10G_MACS 1
99860 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99861 +#define FM_MAX_NUM_OF_OH_PORTS 7
99862 +
99863 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99864 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99865 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99866 +
99867 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99868 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99869 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99870 +
99871 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
99872 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
99873 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
99874 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
99875 +
99876 +/* Rams defines */
99877 +#define FM_MURAM_SIZE (160*KILOBYTE)
99878 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
99879 +#define FM_NUM_OF_CTRL 2
99880 +
99881 +/* PCD defines */
99882 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
99883 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
99884 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
99885 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
99886 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99887 +
99888 +/* RTC defines */
99889 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
99890 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
99891 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
99892 +
99893 +/* QMI defines */
99894 +#define QMI_MAX_NUM_OF_TNUMS 64
99895 +#define QMI_DEF_TNUMS_THRESH 48
99896 +
99897 +/* FPM defines */
99898 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99899 +
99900 +/* DMA defines */
99901 +#define DMA_THRESH_MAX_COMMQ 31
99902 +#define DMA_THRESH_MAX_BUF 127
99903 +
99904 +/* BMI defines */
99905 +#define BMI_MAX_NUM_OF_TASKS 128
99906 +#define BMI_MAX_NUM_OF_DMAS 32
99907 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99908 +#define PORT_MAX_WEIGHT 16
99909 +
99910 +
99911 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
99912 +
99913 +/* p4080-rev1 unique features */
99914 +#define QM_CGS_NO_FRAME_MODE
99915 +
99916 +/* p4080 unique features */
99917 +#define FM_NO_DISPATCH_RAM_ECC
99918 +#define FM_NO_WATCHDOG
99919 +#define FM_NO_TNUM_AGING
99920 +#define FM_KG_NO_BYPASS_FQID_GEN
99921 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
99922 +#define FM_NO_BACKUP_POOLS
99923 +#define FM_NO_OP_OBSERVED_POOLS
99924 +#define FM_NO_ADVANCED_RATE_LIMITER
99925 +#define FM_NO_OP_OBSERVED_CGS
99926 +#define FM_HAS_TOTAL_DMAS
99927 +#define FM_KG_NO_IPPID_SUPPORT
99928 +#define FM_NO_GUARANTEED_RESET_VALUES
99929 +#define FM_MAC_RESET
99930 +
99931 +/* FM erratas */
99932 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
99933 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
99934 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
99935 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
99936 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
99937 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
99938 +
99939 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
99940 +#define FM_GRS_ERRATA_DTSEC_A002
99941 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
99942 +#define FM_GTS_ERRATA_DTSEC_A004
99943 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
99944 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
99945 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
99946 +
99947 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
99948 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
99949 +
99950 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
99951 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
99952 +
99953 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
99954 +
99955 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
99956 +
99957 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
99958 +
99959 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
99960 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
99961 +
99962 +/*****************************************************************************
99963 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99964 +******************************************************************************/
99965 +#define NUM_OF_RX_SC 16
99966 +#define NUM_OF_TX_SC 16
99967 +
99968 +#define NUM_OF_SA_PER_RX_SC 2
99969 +#define NUM_OF_SA_PER_TX_SC 2
99970 +
99971 +
99972 +#endif /* __DPAA_INTEGRATION_EXT_H */
99973 --- /dev/null
99974 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
99975 @@ -0,0 +1,83 @@
99976 +/*
99977 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99978 + *
99979 + * Redistribution and use in source and binary forms, with or without
99980 + * modification, are permitted provided that the following conditions are met:
99981 + * * Redistributions of source code must retain the above copyright
99982 + * notice, this list of conditions and the following disclaimer.
99983 + * * Redistributions in binary form must reproduce the above copyright
99984 + * notice, this list of conditions and the following disclaimer in the
99985 + * documentation and/or other materials provided with the distribution.
99986 + * * Neither the name of Freescale Semiconductor nor the
99987 + * names of its contributors may be used to endorse or promote products
99988 + * derived from this software without specific prior written permission.
99989 + *
99990 + *
99991 + * ALTERNATIVELY, this software may be distributed under the terms of the
99992 + * GNU General Public License ("GPL") as published by the Free Software
99993 + * Foundation, either version 2 of that License or (at your option) any
99994 + * later version.
99995 + *
99996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100006 + */
100007 +
100008 +/**************************************************************************//**
100009 +
100010 + @File part_ext.h
100011 +
100012 + @Description Definitions for the part (integration) module.
100013 +*//***************************************************************************/
100014 +
100015 +#ifndef __PART_EXT_H
100016 +#define __PART_EXT_H
100017 +
100018 +#include "std_ext.h"
100019 +#include "part_integration_ext.h"
100020 +
100021 +
100022 +#if !(defined(MPC8306) || \
100023 + defined(MPC8309) || \
100024 + defined(MPC834x) || \
100025 + defined(MPC836x) || \
100026 + defined(MPC832x) || \
100027 + defined(MPC837x) || \
100028 + defined(MPC8568) || \
100029 + defined(MPC8569) || \
100030 + defined(P1020) || \
100031 + defined(P1021) || \
100032 + defined(P1022) || \
100033 + defined(P1023) || \
100034 + defined(P2020) || \
100035 + defined(P2040) || \
100036 + defined(P3041) || \
100037 + defined(P4080) || \
100038 + defined(SC4080) || \
100039 + defined(P5020) || \
100040 + defined(MSC814x))
100041 +#error "unable to proceed without chip-definition"
100042 +#endif /* !(defined(MPC834x) || ... */
100043 +
100044 +
100045 +/**************************************************************************//*
100046 + @Description Part data structure - must be contained in any integration
100047 + data structure.
100048 +*//***************************************************************************/
100049 +typedef struct t_Part
100050 +{
100051 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100052 + /**< Returns the address of the module's memory map base. */
100053 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100054 + /**< Returns the module's ID according to its memory map base. */
100055 +} t_Part;
100056 +
100057 +
100058 +#endif /* __PART_EXT_H */
100059 --- /dev/null
100060 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100061 @@ -0,0 +1,336 @@
100062 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100063 + * All rights reserved.
100064 + *
100065 + * Redistribution and use in source and binary forms, with or without
100066 + * modification, are permitted provided that the following conditions are met:
100067 + * * Redistributions of source code must retain the above copyright
100068 + * notice, this list of conditions and the following disclaimer.
100069 + * * Redistributions in binary form must reproduce the above copyright
100070 + * notice, this list of conditions and the following disclaimer in the
100071 + * documentation and/or other materials provided with the distribution.
100072 + * * Neither the name of Freescale Semiconductor nor the
100073 + * names of its contributors may be used to endorse or promote products
100074 + * derived from this software without specific prior written permission.
100075 + *
100076 + *
100077 + * ALTERNATIVELY, this software may be distributed under the terms of the
100078 + * GNU General Public License ("GPL") as published by the Free Software
100079 + * Foundation, either version 2 of that License or (at your option) any
100080 + * later version.
100081 + *
100082 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100083 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100084 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100085 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100086 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100087 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100088 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100089 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100090 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100091 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100092 + */
100093 +
100094 +/**************************************************************************//**
100095 + @File part_integration_ext.h
100096 +
100097 + @Description P3040/P4080/P5020 external definitions and structures.
100098 +*//***************************************************************************/
100099 +#ifndef __PART_INTEGRATION_EXT_H
100100 +#define __PART_INTEGRATION_EXT_H
100101 +
100102 +#include "std_ext.h"
100103 +#include "dpaa_integration_ext.h"
100104 +
100105 +
100106 +/**************************************************************************//**
100107 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
100108 +
100109 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
100110 +
100111 + @{
100112 +*//***************************************************************************/
100113 +
100114 +#define CORE_E500MC
100115 +
100116 +#define INTG_MAX_NUM_OF_CORES 1
100117 +
100118 +
100119 +/**************************************************************************//**
100120 + @Description Module types.
100121 +*//***************************************************************************/
100122 +typedef enum e_ModuleId
100123 +{
100124 + e_MODULE_ID_DUART_1 = 0,
100125 + e_MODULE_ID_DUART_2,
100126 + e_MODULE_ID_DUART_3,
100127 + e_MODULE_ID_DUART_4,
100128 + e_MODULE_ID_LAW,
100129 + e_MODULE_ID_LBC,
100130 + e_MODULE_ID_PAMU,
100131 + e_MODULE_ID_QM, /**< Queue manager module */
100132 + e_MODULE_ID_BM, /**< Buffer manager module */
100133 + e_MODULE_ID_QM_CE_PORTAL_0,
100134 + e_MODULE_ID_QM_CI_PORTAL_0,
100135 + e_MODULE_ID_QM_CE_PORTAL_1,
100136 + e_MODULE_ID_QM_CI_PORTAL_1,
100137 + e_MODULE_ID_QM_CE_PORTAL_2,
100138 + e_MODULE_ID_QM_CI_PORTAL_2,
100139 + e_MODULE_ID_QM_CE_PORTAL_3,
100140 + e_MODULE_ID_QM_CI_PORTAL_3,
100141 + e_MODULE_ID_QM_CE_PORTAL_4,
100142 + e_MODULE_ID_QM_CI_PORTAL_4,
100143 + e_MODULE_ID_QM_CE_PORTAL_5,
100144 + e_MODULE_ID_QM_CI_PORTAL_5,
100145 + e_MODULE_ID_QM_CE_PORTAL_6,
100146 + e_MODULE_ID_QM_CI_PORTAL_6,
100147 + e_MODULE_ID_QM_CE_PORTAL_7,
100148 + e_MODULE_ID_QM_CI_PORTAL_7,
100149 + e_MODULE_ID_QM_CE_PORTAL_8,
100150 + e_MODULE_ID_QM_CI_PORTAL_8,
100151 + e_MODULE_ID_QM_CE_PORTAL_9,
100152 + e_MODULE_ID_QM_CI_PORTAL_9,
100153 + e_MODULE_ID_BM_CE_PORTAL_0,
100154 + e_MODULE_ID_BM_CI_PORTAL_0,
100155 + e_MODULE_ID_BM_CE_PORTAL_1,
100156 + e_MODULE_ID_BM_CI_PORTAL_1,
100157 + e_MODULE_ID_BM_CE_PORTAL_2,
100158 + e_MODULE_ID_BM_CI_PORTAL_2,
100159 + e_MODULE_ID_BM_CE_PORTAL_3,
100160 + e_MODULE_ID_BM_CI_PORTAL_3,
100161 + e_MODULE_ID_BM_CE_PORTAL_4,
100162 + e_MODULE_ID_BM_CI_PORTAL_4,
100163 + e_MODULE_ID_BM_CE_PORTAL_5,
100164 + e_MODULE_ID_BM_CI_PORTAL_5,
100165 + e_MODULE_ID_BM_CE_PORTAL_6,
100166 + e_MODULE_ID_BM_CI_PORTAL_6,
100167 + e_MODULE_ID_BM_CE_PORTAL_7,
100168 + e_MODULE_ID_BM_CI_PORTAL_7,
100169 + e_MODULE_ID_BM_CE_PORTAL_8,
100170 + e_MODULE_ID_BM_CI_PORTAL_8,
100171 + e_MODULE_ID_BM_CE_PORTAL_9,
100172 + e_MODULE_ID_BM_CI_PORTAL_9,
100173 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
100174 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
100175 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
100176 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
100177 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
100178 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
100179 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100180 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100181 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100182 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100183 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100184 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100185 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100186 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100187 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100188 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100189 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100190 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100191 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100192 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100193 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100194 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100195 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100196 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100197 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100198 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
100199 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
100200 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
100201 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
100202 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
100203 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100204 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100205 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100206 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100207 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
100208 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100209 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
100210 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
100211 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
100212 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
100213 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
100214 +
100215 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
100216 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
100217 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
100218 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
100219 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
100220 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
100221 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100222 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100223 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100224 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100225 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100226 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100227 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100228 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100229 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100230 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100231 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100232 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100233 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100234 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100235 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100236 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100237 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100238 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
100239 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
100240 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
100241 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
100242 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
100243 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100244 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100245 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100246 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100247 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
100248 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100249 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
100250 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
100251 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
100252 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
100253 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
100254 +
100255 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100256 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100257 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100258 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100259 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100260 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100261 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100262 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100263 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100264 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100265 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100266 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100267 +
100268 + e_MODULE_ID_MPIC, /**< MPIC */
100269 + e_MODULE_ID_GPIO, /**< GPIO */
100270 + e_MODULE_ID_SERDES, /**< SERDES */
100271 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100272 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100273 +
100274 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100275 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
100276 +
100277 + e_MODULE_ID_DUMMY_LAST
100278 +} e_ModuleId;
100279 +
100280 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100281 +
100282 +#if 0 /* using unified values */
100283 +/*****************************************************************************
100284 + INTEGRATION-SPECIFIC MODULE CODES
100285 +******************************************************************************/
100286 +#define MODULE_UNKNOWN 0x00000000
100287 +#define MODULE_MEM 0x00010000
100288 +#define MODULE_MM 0x00020000
100289 +#define MODULE_CORE 0x00030000
100290 +#define MODULE_CHIP 0x00040000
100291 +#define MODULE_PLTFRM 0x00050000
100292 +#define MODULE_PM 0x00060000
100293 +#define MODULE_MMU 0x00070000
100294 +#define MODULE_PIC 0x00080000
100295 +#define MODULE_CPC 0x00090000
100296 +#define MODULE_DUART 0x000a0000
100297 +#define MODULE_SERDES 0x000b0000
100298 +#define MODULE_PIO 0x000c0000
100299 +#define MODULE_QM 0x000d0000
100300 +#define MODULE_BM 0x000e0000
100301 +#define MODULE_SEC 0x000f0000
100302 +#define MODULE_LAW 0x00100000
100303 +#define MODULE_LBC 0x00110000
100304 +#define MODULE_PAMU 0x00120000
100305 +#define MODULE_FM 0x00130000
100306 +#define MODULE_FM_MURAM 0x00140000
100307 +#define MODULE_FM_PCD 0x00150000
100308 +#define MODULE_FM_RTC 0x00160000
100309 +#define MODULE_FM_MAC 0x00170000
100310 +#define MODULE_FM_PORT 0x00180000
100311 +#define MODULE_FM_SP 0x00190000
100312 +#define MODULE_DPA_PORT 0x001a0000
100313 +#define MODULE_MII 0x001b0000
100314 +#define MODULE_I2C 0x001c0000
100315 +#define MODULE_DMA 0x001d0000
100316 +#define MODULE_DDR 0x001e0000
100317 +#define MODULE_ESPI 0x001f0000
100318 +#define MODULE_DPAA_IPSEC 0x00200000
100319 +#endif /* using unified values */
100320 +
100321 +/*****************************************************************************
100322 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100323 +******************************************************************************/
100324 +#define PAMU_NUM_OF_PARTITIONS 5
100325 +
100326 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
100327 +
100328 +/*****************************************************************************
100329 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100330 +******************************************************************************/
100331 +#define LAW_NUM_OF_WINDOWS 32
100332 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100333 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
100334 +
100335 +
100336 +/*****************************************************************************
100337 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100338 +******************************************************************************/
100339 +/**************************************************************************//**
100340 + @Group lbc_exception_grp LBC Exception Unit
100341 +
100342 + @Description LBC Exception unit API functions, definitions and enums
100343 +
100344 + @{
100345 +*//***************************************************************************/
100346 +
100347 +/**************************************************************************//**
100348 + @Anchor lbc_exbm
100349 +
100350 + @Collection LBC Errors Bit Mask
100351 +
100352 + These errors are reported through the exceptions callback..
100353 + The values can be or'ed in any combination in the errors mask
100354 + parameter of the errors report structure.
100355 +
100356 + These errors can also be passed as a bit-mask to
100357 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100358 + for enabling or disabling error checking.
100359 + @{
100360 +*//***************************************************************************/
100361 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100362 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100363 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100364 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
100365 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
100366 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100367 +
100368 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100369 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
100370 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
100371 + /**< All possible errors */
100372 +/* @} */
100373 +/** @} */ /* end of lbc_exception_grp group */
100374 +
100375 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
100376 +
100377 +#define LBC_NUM_OF_BANKS 8
100378 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100379 +#define LBC_ATOMIC_OPERATION_SUPPORT
100380 +#define LBC_PARITY_SUPPORT
100381 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100382 +#define LBC_HIGH_CLK_DIVIDERS
100383 +#define LBC_FCM_AVAILABLE
100384 +
100385 +/*****************************************************************************
100386 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
100387 +******************************************************************************/
100388 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
100389 + Each port contains up to 32 i/O pins. */
100390 +
100391 +#define GPIO_VALID_PIN_MASKS \
100392 + { /* Port A */ 0xFFFFFFFF }
100393 +
100394 +#define GPIO_VALID_INTR_MASKS \
100395 + { /* Port A */ 0xFFFFFFFF }
100396 +
100397 +#endif /* __PART_INTEGRATION_EXT_H */
100398 --- /dev/null
100399 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
100400 @@ -0,0 +1,100 @@
100401 +/*
100402 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100403 + *
100404 + * Redistribution and use in source and binary forms, with or without
100405 + * modification, are permitted provided that the following conditions are met:
100406 + * * Redistributions of source code must retain the above copyright
100407 + * notice, this list of conditions and the following disclaimer.
100408 + * * Redistributions in binary form must reproduce the above copyright
100409 + * notice, this list of conditions and the following disclaimer in the
100410 + * documentation and/or other materials provided with the distribution.
100411 + * * Neither the name of Freescale Semiconductor nor the
100412 + * names of its contributors may be used to endorse or promote products
100413 + * derived from this software without specific prior written permission.
100414 + *
100415 + *
100416 + * ALTERNATIVELY, this software may be distributed under the terms of the
100417 + * GNU General Public License ("GPL") as published by the Free Software
100418 + * Foundation, either version 2 of that License or (at your option) any
100419 + * later version.
100420 + *
100421 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100422 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100423 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100424 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100425 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100426 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100427 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100428 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100429 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100430 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100431 + */
100432 +
100433 +
100434 +#ifndef __MATH_EXT_H
100435 +#define __MATH_EXT_H
100436 +
100437 +
100438 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
100439 +#include <linux/math.h>
100440 +#include <linux/math64.h>
100441 +
100442 +#elif defined(__MWERKS__)
100443 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
100444 +#define HIGH(x) (*(int32_t*)&x)
100445 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
100446 +#define UHIGH(x) (*(uint32_t*)&x)
100447 +
100448 +static const double big = 1.0e300;
100449 +
100450 +/* Macro for checking if a number is a power of 2 */
100451 +static __inline__ double ceil(double x)
100452 +{
100453 + int32_t i0,i1,j0; /*- cc 020130 -*/
100454 + uint32_t i,j; /*- cc 020130 -*/
100455 + i0 = HIGH(x);
100456 + i1 = LOW(x);
100457 + j0 = ((i0>>20)&0x7ff)-0x3ff;
100458 + if(j0<20) {
100459 + if(j0<0) { /* raise inexact if x != 0 */
100460 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
100461 + if(i0<0) {i0=0x80000000;i1=0;}
100462 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
100463 + }
100464 + } else {
100465 + i = (uint32_t)(0x000fffff)>>j0;
100466 + if(((i0&i)|i1)==0) return x; /* x is integral */
100467 + if(big+x>0.0) { /* raise inexact flag */
100468 + if(i0>0) i0 += (0x00100000)>>j0;
100469 + i0 &= (~i); i1=0;
100470 + }
100471 + }
100472 + } else if (j0>51) {
100473 + if(j0==0x400) return x+x; /* inf or NaN */
100474 + else return x; /* x is integral */
100475 + } else {
100476 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
100477 + if((i1&i)==0) return x; /* x is integral */
100478 + if(big+x>0.0) { /* raise inexact flag */
100479 + if(i0>0) {
100480 + if(j0==20) i0+=1;
100481 + else {
100482 + j = (uint32_t)(i1 + (1<<(52-j0)));
100483 + if(j<i1) i0+=1; /* got a carry */
100484 + i1 = (int32_t)j;
100485 + }
100486 + }
100487 + i1 &= (~i);
100488 + }
100489 + }
100490 + HIGH(x) = i0;
100491 + LOW(x) = i1;
100492 + return x;
100493 +}
100494 +
100495 +#else
100496 +#include <math.h>
100497 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
100498 +
100499 +
100500 +#endif /* __MATH_EXT_H */
100501 --- /dev/null
100502 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
100503 @@ -0,0 +1,435 @@
100504 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100505 + * All rights reserved.
100506 + *
100507 + * Redistribution and use in source and binary forms, with or without
100508 + * modification, are permitted provided that the following conditions are met:
100509 + * * Redistributions of source code must retain the above copyright
100510 + * notice, this list of conditions and the following disclaimer.
100511 + * * Redistributions in binary form must reproduce the above copyright
100512 + * notice, this list of conditions and the following disclaimer in the
100513 + * documentation and/or other materials provided with the distribution.
100514 + * * Neither the name of Freescale Semiconductor nor the
100515 + * names of its contributors may be used to endorse or promote products
100516 + * derived from this software without specific prior written permission.
100517 + *
100518 + *
100519 + * ALTERNATIVELY, this software may be distributed under the terms of the
100520 + * GNU General Public License ("GPL") as published by the Free Software
100521 + * Foundation, either version 2 of that License or (at your option) any
100522 + * later version.
100523 + *
100524 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100525 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100526 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100527 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100528 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100529 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100530 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100531 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100532 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100533 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100534 + */
100535 +
100536 +
100537 +/**************************************************************************//**
100538 + @File ncsw_ext.h
100539 +
100540 + @Description General NetCommSw Standard Definitions
100541 +*//***************************************************************************/
100542 +
100543 +#ifndef __NCSW_EXT_H
100544 +#define __NCSW_EXT_H
100545 +
100546 +
100547 +#include "memcpy_ext.h"
100548 +
100549 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
100550 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
100551 +
100552 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
100553 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
100554 +
100555 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
100556 +
100557 +
100558 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
100559 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
100560 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
100561 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
100562 +
100563 +/* Little-Endian access macros */
100564 +
100565 +#define WRITE_UINT16_LE(arg, data) \
100566 + WRITE_UINT16((arg), SwapUint16(data))
100567 +
100568 +#define WRITE_UINT32_LE(arg, data) \
100569 + WRITE_UINT32((arg), SwapUint32(data))
100570 +
100571 +#define WRITE_UINT64_LE(arg, data) \
100572 + WRITE_UINT64((arg), SwapUint64(data))
100573 +
100574 +#define GET_UINT16_LE(arg) \
100575 + SwapUint16(GET_UINT16(arg))
100576 +
100577 +#define GET_UINT32_LE(arg) \
100578 + SwapUint32(GET_UINT32(arg))
100579 +
100580 +#define GET_UINT64_LE(arg) \
100581 + SwapUint64(GET_UINT64(arg))
100582 +
100583 +/* Write and Read again macros */
100584 +#define WRITE_UINT_SYNC(size, arg, data) \
100585 + do { \
100586 + WRITE_UINT##size((arg), (data)); \
100587 + CORE_MemoryBarrier(); \
100588 + } while (0)
100589 +
100590 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
100591 +
100592 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
100593 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
100594 +
100595 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
100596 +
100597 +
100598 +/*----------------------*/
100599 +/* Miscellaneous macros */
100600 +/*----------------------*/
100601 +
100602 +#define UNUSED(_x) ((void)(_x))
100603 +
100604 +#define KILOBYTE 0x400UL /* 1024 */
100605 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
100606 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
100607 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
100608 +
100609 +#ifndef NO_IRQ
100610 +#define NO_IRQ (0)
100611 +#endif
100612 +#define NCSW_MASTER_ID (0)
100613 +
100614 +/* Macro for checking if a number is a power of 2 */
100615 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
100616 +
100617 +/* Macro for calculating log of base 2 */
100618 +#define LOG2(num, log2Num) \
100619 + do \
100620 + { \
100621 + uint64_t tmp = (num); \
100622 + log2Num = 0; \
100623 + while (tmp > 1) \
100624 + { \
100625 + log2Num++; \
100626 + tmp >>= 1; \
100627 + } \
100628 + } while (0)
100629 +
100630 +#define NEXT_POWER_OF_2(_num, _nextPow) \
100631 +do \
100632 +{ \
100633 + if (POWER_OF_2(_num)) \
100634 + _nextPow = (_num); \
100635 + else \
100636 + { \
100637 + uint64_t tmp = (_num); \
100638 + _nextPow = 1; \
100639 + while (tmp) \
100640 + { \
100641 + _nextPow <<= 1; \
100642 + tmp >>= 1; \
100643 + } \
100644 + } \
100645 +} while (0)
100646 +
100647 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
100648 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
100649 +
100650 +/* Round up a number to be a multiple of a second number */
100651 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
100652 +
100653 +/* Timing macro for converting usec units to number of ticks. */
100654 +/* (number of usec * clock_Hz) / 1,000,000) - since */
100655 +/* clk is in MHz units, no division needed. */
100656 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
100657 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
100658 +
100659 +/* Timing macros for converting between nsec units and number of clocks. */
100660 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
100661 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
100662 +
100663 +/* Timing macros for converting between psec units and number of clocks. */
100664 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
100665 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
100666 +
100667 +/* Min, Max macros */
100668 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
100669 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
100670 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
100671 +
100672 +#define ABS(a) ((a<0)?(a*-1):a)
100673 +
100674 +#if !(defined(ARRAY_SIZE))
100675 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
100676 +#endif /* !defined(ARRAY_SIZE) */
100677 +
100678 +
100679 +/* possible alignments */
100680 +#define HALF_WORD_ALIGNMENT 2
100681 +#define WORD_ALIGNMENT 4
100682 +#define DOUBLE_WORD_ALIGNMENT 8
100683 +#define BURST_ALIGNMENT 32
100684 +
100685 +#define HALF_WORD_ALIGNED 0x00000001
100686 +#define WORD_ALIGNED 0x00000003
100687 +#define DOUBLE_WORD_ALIGNED 0x00000007
100688 +#define BURST_ALIGNED 0x0000001f
100689 +#ifndef IS_ALIGNED
100690 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
100691 +#endif /* IS_ALIGNED */
100692 +
100693 +
100694 +#define LAST_BUF 1
100695 +#define FIRST_BUF 2
100696 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
100697 +#define MIDDLE_BUF 4
100698 +
100699 +#define ARRAY_END -1
100700 +
100701 +#define ILLEGAL_BASE (~0)
100702 +
100703 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
100704 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
100705 +
100706 +
100707 +/**************************************************************************//**
100708 + @Description Timers operation mode
100709 +*//***************************************************************************/
100710 +typedef enum e_TimerMode
100711 +{
100712 + e_TIMER_MODE_INVALID = 0,
100713 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
100714 + after reaching the reference value. */
100715 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
100716 + after reaching the reference value. */
100717 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
100718 + after reaching the reference value. */
100719 +} e_TimerMode;
100720 +
100721 +
100722 +/**************************************************************************//**
100723 + @Description Enumeration (bit flags) of communication modes (Transmit,
100724 + receive or both).
100725 +*//***************************************************************************/
100726 +typedef enum e_CommMode
100727 +{
100728 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
100729 + e_COMM_MODE_RX = 1, /**< Only receive communication */
100730 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
100731 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
100732 +} e_CommMode;
100733 +
100734 +/**************************************************************************//**
100735 + @Description General Diagnostic Mode
100736 +*//***************************************************************************/
100737 +typedef enum e_DiagMode
100738 +{
100739 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
100740 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
100741 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
100742 + controller; e.g. IO-pins, SerDes, etc. */
100743 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
100744 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
100745 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
100746 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
100747 +} e_DiagMode;
100748 +
100749 +/**************************************************************************//**
100750 + @Description Possible RxStore callback responses.
100751 +*//***************************************************************************/
100752 +typedef enum e_RxStoreResponse
100753 +{
100754 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
100755 + in polling mode, start again invoking callback
100756 + only next time user invokes the receive routine;
100757 + in interrupt mode, start again invoking callback
100758 + only next time a receive event triggers an interrupt;
100759 + in all cases, received data that are pending are not
100760 + lost, rather, their processing is temporarily deferred;
100761 + in all cases, received data are processed in the order
100762 + in which they were received. */
100763 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
100764 +} e_RxStoreResponse;
100765 +
100766 +
100767 +/**************************************************************************//**
100768 + @Description General Handle
100769 +*//***************************************************************************/
100770 +typedef void * t_Handle; /**< handle, used as object's descriptor */
100771 +
100772 +/**************************************************************************//**
100773 + @Description MUTEX type
100774 +*//***************************************************************************/
100775 +typedef uint32_t t_Mutex;
100776 +
100777 +/**************************************************************************//**
100778 + @Description Error Code.
100779 +
100780 + The high word of the error code is the code of the software
100781 + module (driver). The low word is the error type (e_ErrorType).
100782 + To get the values from the error code, use GET_ERROR_TYPE()
100783 + and GET_ERROR_MODULE().
100784 +*//***************************************************************************/
100785 +typedef uint32_t t_Error;
100786 +
100787 +/**************************************************************************//**
100788 + @Description General prototype of interrupt service routine (ISR).
100789 +
100790 + @Param[in] handle - Optional handle of the module handling the interrupt.
100791 +
100792 + @Return None
100793 + *//***************************************************************************/
100794 +typedef void (t_Isr)(t_Handle handle);
100795 +
100796 +/**************************************************************************//**
100797 + @Anchor mem_attr
100798 +
100799 + @Collection Memory Attributes
100800 +
100801 + Various attributes of memory partitions. These values may be
100802 + or'ed together to create a mask of all memory attributes.
100803 + @{
100804 +*//***************************************************************************/
100805 +#define MEMORY_ATTR_CACHEABLE 0x00000001
100806 + /**< Memory is cacheable */
100807 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
100808 + /**< Memory can be accessed by QUICC Engine
100809 + through its secondary bus interface */
100810 +
100811 +/* @} */
100812 +
100813 +
100814 +/**************************************************************************//**
100815 + @Function t_GetBufFunction
100816 +
100817 + @Description User callback function called by driver to get data buffer.
100818 +
100819 + User provides this function. Driver invokes it.
100820 +
100821 + @Param[in] h_BufferPool - A handle to buffer pool manager
100822 + @Param[out] p_BufContextHandle - Returns the user's private context that
100823 + should be associated with the buffer
100824 +
100825 + @Return Pointer to data buffer, NULL if error
100826 + *//***************************************************************************/
100827 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
100828 + t_Handle *p_BufContextHandle);
100829 +
100830 +/**************************************************************************//**
100831 + @Function t_PutBufFunction
100832 +
100833 + @Description User callback function called by driver to return data buffer.
100834 +
100835 + User provides this function. Driver invokes it.
100836 +
100837 + @Param[in] h_BufferPool - A handle to buffer pool manager
100838 + @Param[in] p_Buffer - A pointer to buffer to return
100839 + @Param[in] h_BufContext - The user's private context associated with
100840 + the returned buffer
100841 +
100842 + @Return E_OK on success; Error code otherwise
100843 + *//***************************************************************************/
100844 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
100845 + uint8_t *p_Buffer,
100846 + t_Handle h_BufContext);
100847 +
100848 +/**************************************************************************//**
100849 + @Function t_PhysToVirt
100850 +
100851 + @Description Translates a physical address to the matching virtual address.
100852 +
100853 + @Param[in] addr - The physical address to translate.
100854 +
100855 + @Return Virtual address.
100856 +*//***************************************************************************/
100857 +typedef void * t_PhysToVirt(physAddress_t addr);
100858 +
100859 +/**************************************************************************//**
100860 + @Function t_VirtToPhys
100861 +
100862 + @Description Translates a virtual address to the matching physical address.
100863 +
100864 + @Param[in] addr - The virtual address to translate.
100865 +
100866 + @Return Physical address.
100867 +*//***************************************************************************/
100868 +typedef physAddress_t t_VirtToPhys(void *addr);
100869 +
100870 +/**************************************************************************//**
100871 + @Description Buffer Pool Information Structure.
100872 +*//***************************************************************************/
100873 +typedef struct t_BufferPoolInfo
100874 +{
100875 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
100876 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
100877 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
100878 + uint16_t bufferSize; /**< Buffer size (in bytes) */
100879 +
100880 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
100881 + physical addresses to virtual addresses */
100882 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
100883 + virtual addresses to physical addresses */
100884 +} t_BufferPoolInfo;
100885 +
100886 +
100887 +/**************************************************************************//**
100888 + @Description User callback function called by driver when transmit completed.
100889 +
100890 + User provides this function. Driver invokes it.
100891 +
100892 + @Param[in] h_App - Application's handle, as was provided to the
100893 + driver by the user
100894 + @Param[in] queueId - Transmit queue ID
100895 + @Param[in] p_Data - Pointer to the data buffer
100896 + @Param[in] h_BufContext - The user's private context associated with
100897 + the given data buffer
100898 + @Param[in] status - Transmit status and errors
100899 + @Param[in] flags - Driver-dependent information
100900 + *//***************************************************************************/
100901 +typedef void (t_TxConfFunction)(t_Handle h_App,
100902 + uint32_t queueId,
100903 + uint8_t *p_Data,
100904 + t_Handle h_BufContext,
100905 + uint16_t status,
100906 + uint32_t flags);
100907 +
100908 +/**************************************************************************//**
100909 + @Description User callback function called by driver with receive data.
100910 +
100911 + User provides this function. Driver invokes it.
100912 +
100913 + @Param[in] h_App - Application's handle, as was provided to the
100914 + driver by the user
100915 + @Param[in] queueId - Receive queue ID
100916 + @Param[in] p_Data - Pointer to the buffer with received data
100917 + @Param[in] h_BufContext - The user's private context associated with
100918 + the given data buffer
100919 + @Param[in] length - Length of received data
100920 + @Param[in] status - Receive status and errors
100921 + @Param[in] position - Position of buffer in frame
100922 + @Param[in] flags - Driver-dependent information
100923 +
100924 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
100925 + operation for all ready data.
100926 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
100927 + *//***************************************************************************/
100928 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
100929 + uint32_t queueId,
100930 + uint8_t *p_Data,
100931 + t_Handle h_BufContext,
100932 + uint32_t length,
100933 + uint16_t status,
100934 + uint8_t position,
100935 + uint32_t flags);
100936 +
100937 +
100938 +#endif /* __NCSW_EXT_H */
100939 --- /dev/null
100940 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
100941 @@ -0,0 +1,430 @@
100942 +/*
100943 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100944 + *
100945 + * Redistribution and use in source and binary forms, with or without
100946 + * modification, are permitted provided that the following conditions are met:
100947 + * * Redistributions of source code must retain the above copyright
100948 + * notice, this list of conditions and the following disclaimer.
100949 + * * Redistributions in binary form must reproduce the above copyright
100950 + * notice, this list of conditions and the following disclaimer in the
100951 + * documentation and/or other materials provided with the distribution.
100952 + * * Neither the name of Freescale Semiconductor nor the
100953 + * names of its contributors may be used to endorse or promote products
100954 + * derived from this software without specific prior written permission.
100955 + *
100956 + *
100957 + * ALTERNATIVELY, this software may be distributed under the terms of the
100958 + * GNU General Public License ("GPL") as published by the Free Software
100959 + * Foundation, either version 2 of that License or (at your option) any
100960 + * later version.
100961 + *
100962 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100963 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100964 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100965 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100966 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100967 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100968 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100969 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100970 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100971 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100972 + */
100973 +
100974 +
100975 +/**************************************************************************//**
100976 + @File net_ext.h
100977 +
100978 + @Description This file contains common and general netcomm headers definitions.
100979 +*//***************************************************************************/
100980 +#ifndef __NET_EXT_H
100981 +#define __NET_EXT_H
100982 +
100983 +#include "std_ext.h"
100984 +
100985 +
100986 +typedef uint8_t headerFieldPpp_t;
100987 +
100988 +#define NET_HEADER_FIELD_PPP_PID (1)
100989 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
100990 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
100991 +
100992 +
100993 +typedef uint8_t headerFieldPppoe_t;
100994 +
100995 +#define NET_HEADER_FIELD_PPPoE_VER (1)
100996 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
100997 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
100998 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
100999 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
101000 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
101001 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
101002 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
101003 +
101004 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
101005 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
101006 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
101007 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
101008 +
101009 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
101010 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
101011 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
101012 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
101013 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
101014 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
101015 +
101016 +
101017 +typedef uint8_t headerFieldEth_t;
101018 +
101019 +#define NET_HEADER_FIELD_ETH_DA (1)
101020 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
101021 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
101022 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
101023 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
101024 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
101025 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
101026 +
101027 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
101028 +
101029 +typedef uint16_t headerFieldIp_t;
101030 +
101031 +#define NET_HEADER_FIELD_IP_VER (1)
101032 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
101033 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
101034 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
101035 +
101036 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
101037 +
101038 +typedef uint16_t headerFieldIpv4_t;
101039 +
101040 +#define NET_HEADER_FIELD_IPv4_VER (1)
101041 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
101042 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
101043 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
101044 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
101045 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
101046 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
101047 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
101048 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
101049 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
101050 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
101051 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
101052 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
101053 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
101054 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
101055 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
101056 +
101057 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
101058 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
101059 +
101060 +
101061 +typedef uint8_t headerFieldIpv6_t;
101062 +
101063 +#define NET_HEADER_FIELD_IPv6_VER (1)
101064 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
101065 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
101066 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
101067 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
101068 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
101069 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
101070 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
101071 +
101072 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
101073 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
101074 +
101075 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
101076 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
101077 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
101078 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
101079 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
101080 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
101081 +
101082 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
101083 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
101084 +
101085 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
101086 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
101087 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
101088 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
101089 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
101090 +
101091 +
101092 +typedef uint16_t headerFieldTcp_t;
101093 +
101094 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
101095 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
101096 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
101097 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
101098 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
101099 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
101100 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
101101 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
101102 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
101103 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
101104 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
101105 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
101106 +
101107 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
101108 +
101109 +
101110 +typedef uint8_t headerFieldSctp_t;
101111 +
101112 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
101113 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
101114 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
101115 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
101116 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
101117 +
101118 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
101119 +
101120 +typedef uint8_t headerFieldDccp_t;
101121 +
101122 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
101123 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
101124 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
101125 +
101126 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
101127 +
101128 +
101129 +typedef uint8_t headerFieldUdp_t;
101130 +
101131 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
101132 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
101133 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
101134 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
101135 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
101136 +
101137 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
101138 +
101139 +typedef uint8_t headerFieldUdpLite_t;
101140 +
101141 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
101142 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
101143 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
101144 +
101145 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
101146 +
101147 +typedef uint8_t headerFieldUdpEncapEsp_t;
101148 +
101149 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
101150 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
101151 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
101152 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
101153 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
101154 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
101155 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
101156 +
101157 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
101158 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
101159 +
101160 +#define NET_HEADER_FIELD_IPHC_CID (1)
101161 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
101162 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
101163 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
101164 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
101165 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
101166 +
101167 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
101168 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
101169 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
101170 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
101171 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
101172 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
101173 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
101174 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
101175 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
101176 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
101177 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
101178 +
101179 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
101180 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
101181 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
101182 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
101183 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
101184 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
101185 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
101186 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
101187 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
101188 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
101189 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
101190 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
101191 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
101192 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
101193 +
101194 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
101195 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
101196 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
101197 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
101198 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
101199 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
101200 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
101201 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
101202 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
101203 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
101204 +
101205 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
101206 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
101207 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
101208 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
101209 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
101210 +
101211 +
101212 +typedef uint8_t headerFieldVlan_t;
101213 +
101214 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
101215 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
101216 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
101217 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
101218 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
101219 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
101220 +
101221 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
101222 + NET_HEADER_FIELD_VLAN_CFI | \
101223 + NET_HEADER_FIELD_VLAN_VID)
101224 +
101225 +
101226 +typedef uint8_t headerFieldLlc_t;
101227 +
101228 +#define NET_HEADER_FIELD_LLC_DSAP (1)
101229 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
101230 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
101231 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
101232 +
101233 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
101234 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
101235 +
101236 +
101237 +typedef uint8_t headerFieldSnap_t;
101238 +
101239 +#define NET_HEADER_FIELD_SNAP_OUI (1)
101240 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
101241 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
101242 +
101243 +
101244 +typedef uint8_t headerFieldLlcSnap_t;
101245 +
101246 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
101247 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
101248 +
101249 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
101250 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
101251 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
101252 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
101253 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
101254 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
101255 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
101256 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
101257 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
101258 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
101259 +
101260 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
101261 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
101262 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
101263 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
101264 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
101265 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
101266 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
101267 +
101268 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
101269 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
101270 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
101271 +
101272 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
101273 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
101274 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
101275 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
101276 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
101277 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
101278 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
101279 +
101280 +
101281 +typedef uint8_t headerFieldGre_t;
101282 +
101283 +#define NET_HEADER_FIELD_GRE_TYPE (1)
101284 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
101285 +
101286 +
101287 +typedef uint8_t headerFieldMinencap_t;
101288 +
101289 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
101290 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
101291 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
101292 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
101293 +
101294 +
101295 +typedef uint8_t headerFieldIpsecAh_t;
101296 +
101297 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
101298 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
101299 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
101300 +
101301 +
101302 +typedef uint8_t headerFieldIpsecEsp_t;
101303 +
101304 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
101305 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
101306 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
101307 +
101308 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
101309 +
101310 +
101311 +typedef uint8_t headerFieldMpls_t;
101312 +
101313 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
101314 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
101315 +
101316 +
101317 +typedef uint8_t headerFieldMacsec_t;
101318 +
101319 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
101320 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
101321 +
101322 +
101323 +typedef enum {
101324 + HEADER_TYPE_NONE = 0,
101325 + HEADER_TYPE_PAYLOAD,
101326 + HEADER_TYPE_ETH,
101327 + HEADER_TYPE_VLAN,
101328 + HEADER_TYPE_IPv4,
101329 + HEADER_TYPE_IPv6,
101330 + HEADER_TYPE_IP,
101331 + HEADER_TYPE_TCP,
101332 + HEADER_TYPE_UDP,
101333 + HEADER_TYPE_UDP_LITE,
101334 + HEADER_TYPE_IPHC,
101335 + HEADER_TYPE_SCTP,
101336 + HEADER_TYPE_SCTP_CHUNK_DATA,
101337 + HEADER_TYPE_PPPoE,
101338 + HEADER_TYPE_PPP,
101339 + HEADER_TYPE_PPPMUX,
101340 + HEADER_TYPE_PPPMUX_SUBFRAME,
101341 + HEADER_TYPE_L2TPv2,
101342 + HEADER_TYPE_L2TPv3_CTRL,
101343 + HEADER_TYPE_L2TPv3_SESS,
101344 + HEADER_TYPE_LLC,
101345 + HEADER_TYPE_LLC_SNAP,
101346 + HEADER_TYPE_NLPID,
101347 + HEADER_TYPE_SNAP,
101348 + HEADER_TYPE_MPLS,
101349 + HEADER_TYPE_IPSEC_AH,
101350 + HEADER_TYPE_IPSEC_ESP,
101351 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
101352 + HEADER_TYPE_MACSEC,
101353 + HEADER_TYPE_GRE,
101354 + HEADER_TYPE_MINENCAP,
101355 + HEADER_TYPE_DCCP,
101356 + HEADER_TYPE_ICMP,
101357 + HEADER_TYPE_IGMP,
101358 + HEADER_TYPE_ARP,
101359 + HEADER_TYPE_CAPWAP,
101360 + HEADER_TYPE_CAPWAP_DTLS,
101361 + HEADER_TYPE_RFC2684,
101362 + HEADER_TYPE_USER_DEFINED_L2,
101363 + HEADER_TYPE_USER_DEFINED_L3,
101364 + HEADER_TYPE_USER_DEFINED_L4,
101365 + HEADER_TYPE_USER_DEFINED_SHIM1,
101366 + HEADER_TYPE_USER_DEFINED_SHIM2,
101367 + MAX_HEADER_TYPE_COUNT
101368 +} e_NetHeaderType;
101369 +
101370 +
101371 +#endif /* __NET_EXT_H */
101372 --- /dev/null
101373 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
101374 @@ -0,0 +1,48 @@
101375 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101376 + * All rights reserved.
101377 + *
101378 + * Redistribution and use in source and binary forms, with or without
101379 + * modification, are permitted provided that the following conditions are met:
101380 + * * Redistributions of source code must retain the above copyright
101381 + * notice, this list of conditions and the following disclaimer.
101382 + * * Redistributions in binary form must reproduce the above copyright
101383 + * notice, this list of conditions and the following disclaimer in the
101384 + * documentation and/or other materials provided with the distribution.
101385 + * * Neither the name of Freescale Semiconductor nor the
101386 + * names of its contributors may be used to endorse or promote products
101387 + * derived from this software without specific prior written permission.
101388 + *
101389 + *
101390 + * ALTERNATIVELY, this software may be distributed under the terms of the
101391 + * GNU General Public License ("GPL") as published by the Free Software
101392 + * Foundation, either version 2 of that License or (at your option) any
101393 + * later version.
101394 + *
101395 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101396 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101397 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101398 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101399 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101400 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101401 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101402 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101403 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101404 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101405 + */
101406 +
101407 +
101408 +/**************************************************************************//**
101409 + @File std_ext.h
101410 +
101411 + @Description General Standard Definitions
101412 +*//***************************************************************************/
101413 +
101414 +#ifndef __STD_EXT_H
101415 +#define __STD_EXT_H
101416 +
101417 +
101418 +#include "types_ext.h"
101419 +#include "ncsw_ext.h"
101420 +
101421 +
101422 +#endif /* __STD_EXT_H */
101423 --- /dev/null
101424 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
101425 @@ -0,0 +1,49 @@
101426 +/*
101427 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101428 + *
101429 + * Redistribution and use in source and binary forms, with or without
101430 + * modification, are permitted provided that the following conditions are met:
101431 + * * Redistributions of source code must retain the above copyright
101432 + * notice, this list of conditions and the following disclaimer.
101433 + * * Redistributions in binary form must reproduce the above copyright
101434 + * notice, this list of conditions and the following disclaimer in the
101435 + * documentation and/or other materials provided with the distribution.
101436 + * * Neither the name of Freescale Semiconductor nor the
101437 + * names of its contributors may be used to endorse or promote products
101438 + * derived from this software without specific prior written permission.
101439 + *
101440 + *
101441 + * ALTERNATIVELY, this software may be distributed under the terms of the
101442 + * GNU General Public License ("GPL") as published by the Free Software
101443 + * Foundation, either version 2 of that License or (at your option) any
101444 + * later version.
101445 + *
101446 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101447 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101448 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101449 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101450 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101451 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101452 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101453 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101454 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101455 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101456 + */
101457 +
101458 +
101459 +#ifndef __STDARG_EXT_H
101460 +#define __STDARG_EXT_H
101461 +
101462 +
101463 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101464 +#include <stdarg.h>
101465 +
101466 +#else
101467 +#include <stdarg.h>
101468 +
101469 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101470 +
101471 +#include "std_ext.h"
101472 +
101473 +
101474 +#endif /* __STDARG_EXT_H */
101475 --- /dev/null
101476 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
101477 @@ -0,0 +1,162 @@
101478 +/*
101479 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101480 + *
101481 + * Redistribution and use in source and binary forms, with or without
101482 + * modification, are permitted provided that the following conditions are met:
101483 + * * Redistributions of source code must retain the above copyright
101484 + * notice, this list of conditions and the following disclaimer.
101485 + * * Redistributions in binary form must reproduce the above copyright
101486 + * notice, this list of conditions and the following disclaimer in the
101487 + * documentation and/or other materials provided with the distribution.
101488 + * * Neither the name of Freescale Semiconductor nor the
101489 + * names of its contributors may be used to endorse or promote products
101490 + * derived from this software without specific prior written permission.
101491 + *
101492 + *
101493 + * ALTERNATIVELY, this software may be distributed under the terms of the
101494 + * GNU General Public License ("GPL") as published by the Free Software
101495 + * Foundation, either version 2 of that License or (at your option) any
101496 + * later version.
101497 + *
101498 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101499 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101500 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101501 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101502 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101503 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101504 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101505 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101506 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101507 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101508 + */
101509 +
101510 +
101511 +
101512 +#ifndef __STDLIB_EXT_H
101513 +#define __STDLIB_EXT_H
101514 +
101515 +
101516 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
101517 +#include "stdarg_ext.h"
101518 +#include "std_ext.h"
101519 +
101520 +
101521 +/**
101522 + * strtoul - convert a string to an uint32_t
101523 + * @cp: The start of the string
101524 + * @endp: A pointer to the end of the parsed string will be placed here
101525 + * @base: The number base to use
101526 + */
101527 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
101528 +
101529 +/**
101530 + * strtol - convert a string to a int32_t
101531 + * @cp: The start of the string
101532 + * @endp: A pointer to the end of the parsed string will be placed here
101533 + * @base: The number base to use
101534 + */
101535 +long strtol(const char *cp,char **endp,uint32_t base);
101536 +
101537 +/**
101538 + * strtoull - convert a string to an uint64_t
101539 + * @cp: The start of the string
101540 + * @endp: A pointer to the end of the parsed string will be placed here
101541 + * @base: The number base to use
101542 + */
101543 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
101544 +
101545 +/**
101546 + * strtoll - convert a string to a int64 long
101547 + * @cp: The start of the string
101548 + * @endp: A pointer to the end of the parsed string will be placed here
101549 + * @base: The number base to use
101550 + */
101551 +long long strtoll(const char *cp,char **endp,uint32_t base);
101552 +
101553 +/**
101554 + * atoi - convert a character to a int
101555 + * @s: The start of the string
101556 + */
101557 +int atoi(const char *s);
101558 +
101559 +/**
101560 + * strnlen - Find the length of a length-limited string
101561 + * @s: The string to be sized
101562 + * @count: The maximum number of bytes to search
101563 + */
101564 +size_t strnlen(const char * s, size_t count);
101565 +
101566 +/**
101567 + * strlen - Find the length of a string
101568 + * @s: The string to be sized
101569 + */
101570 +size_t strlen(const char * s);
101571 +
101572 +/**
101573 + * strtok - Split a string into tokens
101574 + * @s: The string to be searched
101575 + * @ct: The characters to search for
101576 + *
101577 + * WARNING: strtok is deprecated, use strsep instead.
101578 + */
101579 +char * strtok(char * s,const char * ct);
101580 +
101581 +/**
101582 + * strncpy - Copy a length-limited, %NUL-terminated string
101583 + * @dest: Where to copy the string to
101584 + * @src: Where to copy the string from
101585 + * @count: The maximum number of bytes to copy
101586 + *
101587 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
101588 + * However, the result is not %NUL-terminated if the source exceeds
101589 + * @count bytes.
101590 + */
101591 +char * strncpy(char * dest,const char *src,size_t count);
101592 +
101593 +/**
101594 + * strcpy - Copy a %NUL terminated string
101595 + * @dest: Where to copy the string to
101596 + * @src: Where to copy the string from
101597 + */
101598 +char * strcpy(char * dest,const char *src);
101599 +
101600 +/**
101601 + * vsscanf - Unformat a buffer into a list of arguments
101602 + * @buf: input buffer
101603 + * @fmt: format of buffer
101604 + * @args: arguments
101605 + */
101606 +int vsscanf(const char * buf, const char * fmt, va_list args);
101607 +
101608 +/**
101609 + * vsnprintf - Format a string and place it in a buffer
101610 + * @buf: The buffer to place the result into
101611 + * @size: The size of the buffer, including the trailing null space
101612 + * @fmt: The format string to use
101613 + * @args: Arguments for the format string
101614 + *
101615 + * Call this function if you are already dealing with a va_list.
101616 + * You probably want snprintf instead.
101617 + */
101618 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
101619 +
101620 +/**
101621 + * vsprintf - Format a string and place it in a buffer
101622 + * @buf: The buffer to place the result into
101623 + * @fmt: The format string to use
101624 + * @args: Arguments for the format string
101625 + *
101626 + * Call this function if you are already dealing with a va_list.
101627 + * You probably want sprintf instead.
101628 + */
101629 +int vsprintf(char *buf, const char *fmt, va_list args);
101630 +
101631 +#else
101632 +#include <stdlib.h>
101633 +#include <stdio.h>
101634 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101635 +
101636 +#include "std_ext.h"
101637 +
101638 +
101639 +#endif /* __STDLIB_EXT_H */
101640 --- /dev/null
101641 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
101642 @@ -0,0 +1,56 @@
101643 +/*
101644 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101645 + *
101646 + * Redistribution and use in source and binary forms, with or without
101647 + * modification, are permitted provided that the following conditions are met:
101648 + * * Redistributions of source code must retain the above copyright
101649 + * notice, this list of conditions and the following disclaimer.
101650 + * * Redistributions in binary form must reproduce the above copyright
101651 + * notice, this list of conditions and the following disclaimer in the
101652 + * documentation and/or other materials provided with the distribution.
101653 + * * Neither the name of Freescale Semiconductor nor the
101654 + * names of its contributors may be used to endorse or promote products
101655 + * derived from this software without specific prior written permission.
101656 + *
101657 + *
101658 + * ALTERNATIVELY, this software may be distributed under the terms of the
101659 + * GNU General Public License ("GPL") as published by the Free Software
101660 + * Foundation, either version 2 of that License or (at your option) any
101661 + * later version.
101662 + *
101663 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101664 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101665 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101666 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101667 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101668 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101670 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101671 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101672 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101673 + */
101674 +
101675 +
101676 +#ifndef __STRING_EXT_H
101677 +#define __STRING_EXT_H
101678 +
101679 +
101680 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101681 +#include <linux/kernel.h>
101682 +#include <linux/string.h>
101683 +extern char * strtok ( char * str, const char * delimiters );
101684 +
101685 +#elif defined(__KERNEL__)
101686 +#include "linux/types.h"
101687 +#include "linux/posix_types.h"
101688 +#include "linux/string.h"
101689 +
101690 +#else
101691 +#include <string.h>
101692 +
101693 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101694 +
101695 +#include "std_ext.h"
101696 +
101697 +
101698 +#endif /* __STRING_EXT_H */
101699 --- /dev/null
101700 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
101701 @@ -0,0 +1,62 @@
101702 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101703 + * All rights reserved.
101704 + *
101705 + * Redistribution and use in source and binary forms, with or without
101706 + * modification, are permitted provided that the following conditions are met:
101707 + * * Redistributions of source code must retain the above copyright
101708 + * notice, this list of conditions and the following disclaimer.
101709 + * * Redistributions in binary form must reproduce the above copyright
101710 + * notice, this list of conditions and the following disclaimer in the
101711 + * documentation and/or other materials provided with the distribution.
101712 + * * Neither the name of Freescale Semiconductor nor the
101713 + * names of its contributors may be used to endorse or promote products
101714 + * derived from this software without specific prior written permission.
101715 + *
101716 + *
101717 + * ALTERNATIVELY, this software may be distributed under the terms of the
101718 + * GNU General Public License ("GPL") as published by the Free Software
101719 + * Foundation, either version 2 of that License or (at your option) any
101720 + * later version.
101721 + *
101722 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101723 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101724 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101725 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101726 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101727 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101728 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101729 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101730 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101731 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101732 + */
101733 +
101734 +
101735 +/**************************************************************************//**
101736 + @File types_ext.h
101737 +
101738 + @Description General types Standard Definitions
101739 +*//***************************************************************************/
101740 +
101741 +#ifndef __TYPES_EXT_H
101742 +#define __TYPES_EXT_H
101743 +
101744 +#if defined(NCSW_LINUX)
101745 +#include "types_linux.h"
101746 +
101747 +#elif defined(NCSW_VXWORKS)
101748 +#include "types_vxworks.h"
101749 +
101750 +#elif defined(__GNUC__) && defined(__cplusplus)
101751 +#include "types_bb_gpp.h"
101752 +
101753 +#elif defined(__GNUC__)
101754 +#include "types_bb_gcc.h"
101755 +
101756 +#elif defined(__ghs__)
101757 +#include "types_ghs.h"
101758 +
101759 +#else
101760 +#include "types_dflt.h"
101761 +#endif /* defined (__ROCOO__) */
101762 +
101763 +#endif /* __TYPES_EXT_H */
101764 --- /dev/null
101765 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
101766 @@ -0,0 +1,56 @@
101767 +/*
101768 + * Copyright 2012 Freescale Semiconductor Inc.
101769 + *
101770 + * Redistribution and use in source and binary forms, with or without
101771 + * modification, are permitted provided that the following conditions are met:
101772 + * * Redistributions of source code must retain the above copyright
101773 + * notice, this list of conditions and the following disclaimer.
101774 + * * Redistributions in binary form must reproduce the above copyright
101775 + * notice, this list of conditions and the following disclaimer in the
101776 + * documentation and/or other materials provided with the distribution.
101777 + * * Neither the name of Freescale Semiconductor nor the
101778 + * names of its contributors may be used to endorse or promote products
101779 + * derived from this software without specific prior written permission.
101780 + *
101781 + *
101782 + * ALTERNATIVELY, this software may be distributed under the terms of the
101783 + * GNU General Public License ("GPL") as published by the Free Software
101784 + * Foundation, either version 2 of that License or (at your option) any
101785 + * later version.
101786 + *
101787 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101788 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101789 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101790 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101791 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101792 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101793 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101794 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101795 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101796 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101797 + */
101798 +
101799 +
101800 +/**************************************************************************//**
101801 + @File debug_ext.h
101802 +
101803 + @Description Debug mode definitions.
101804 +*//***************************************************************************/
101805 +
101806 +#ifndef __XX_COMMON_H
101807 +#define __XX_COMMON_H
101808 +
101809 +/*****************************************************************************
101810 + * UNIFIED MODULE CODES
101811 + *****************************************************************************/
101812 +#define MODULE_UNKNOWN 0x00000000
101813 +#define MODULE_FM 0x00010000
101814 +#define MODULE_FM_MURAM 0x00020000
101815 +#define MODULE_FM_PCD 0x00030000
101816 +#define MODULE_FM_RTC 0x00040000
101817 +#define MODULE_FM_MAC 0x00050000
101818 +#define MODULE_FM_PORT 0x00060000
101819 +#define MODULE_MM 0x00070000
101820 +#define MODULE_FM_SP 0x00080000
101821 +#define MODULE_FM_MACSEC 0x00090000
101822 +#endif /* __XX_COMMON_H */
101823 --- /dev/null
101824 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
101825 @@ -0,0 +1,791 @@
101826 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101827 + * All rights reserved.
101828 + *
101829 + * Redistribution and use in source and binary forms, with or without
101830 + * modification, are permitted provided that the following conditions are met:
101831 + * * Redistributions of source code must retain the above copyright
101832 + * notice, this list of conditions and the following disclaimer.
101833 + * * Redistributions in binary form must reproduce the above copyright
101834 + * notice, this list of conditions and the following disclaimer in the
101835 + * documentation and/or other materials provided with the distribution.
101836 + * * Neither the name of Freescale Semiconductor nor the
101837 + * names of its contributors may be used to endorse or promote products
101838 + * derived from this software without specific prior written permission.
101839 + *
101840 + *
101841 + * ALTERNATIVELY, this software may be distributed under the terms of the
101842 + * GNU General Public License ("GPL") as published by the Free Software
101843 + * Foundation, either version 2 of that License or (at your option) any
101844 + * later version.
101845 + *
101846 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101847 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101848 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101849 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101850 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101851 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101852 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101853 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101854 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101855 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101856 + */
101857 +
101858 +
101859 +/**************************************************************************//**
101860 + @File xx_ext.h
101861 +
101862 + @Description Prototypes, externals and typedefs for system-supplied
101863 + (external) routines
101864 +*//***************************************************************************/
101865 +
101866 +#ifndef __XX_EXT_H
101867 +#define __XX_EXT_H
101868 +
101869 +#include "std_ext.h"
101870 +#include "xx_common.h"
101871 +#include "part_ext.h"
101872 +
101873 +
101874 +
101875 +/**************************************************************************//**
101876 + @Group xx_id XX Interface (System call hooks)
101877 +
101878 + @Description Prototypes, externals and typedefs for system-supplied
101879 + (external) routines
101880 +
101881 + @{
101882 +*//***************************************************************************/
101883 +
101884 +#ifdef DEBUG_XX_MALLOC
101885 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
101886 +
101887 +void * XX_MallocSmartDebug(uint32_t size,
101888 + int memPartitionId,
101889 + uint32_t alignment,
101890 + char *fname,
101891 + int line);
101892 +
101893 +#define XX_Malloc(sz) \
101894 + XX_MallocDebug((sz), __FILE__, __LINE__)
101895 +
101896 +#define XX_MallocSmart(sz, memt, al) \
101897 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
101898 +
101899 +#else /* not DEBUG_XX_MALLOC */
101900 +/**************************************************************************//**
101901 + @Function XX_Malloc
101902 +
101903 + @Description allocates contiguous block of memory.
101904 +
101905 + @Param[in] size - Number of bytes to allocate.
101906 +
101907 + @Return The address of the newly allocated block on success, NULL on failure.
101908 +*//***************************************************************************/
101909 +void * XX_Malloc(uint32_t size);
101910 +
101911 +/**************************************************************************//**
101912 + @Function XX_MallocSmart
101913 +
101914 + @Description Allocates contiguous block of memory in a specified
101915 + alignment and from the specified segment.
101916 +
101917 + @Param[in] size - Number of bytes to allocate.
101918 + @Param[in] memPartitionId - Memory partition ID; The value zero must
101919 + be mapped to the default heap partition.
101920 + @Param[in] alignment - Required memory alignment (in bytes).
101921 +
101922 + @Return The address of the newly allocated block on success, NULL on failure.
101923 +*//***************************************************************************/
101924 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
101925 +#endif /* not DEBUG_XX_MALLOC */
101926 +
101927 +/**************************************************************************//**
101928 + @Function XX_FreeSmart
101929 +
101930 + @Description Frees the memory block pointed to by "p".
101931 + Only for memory allocated by XX_MallocSmart
101932 +
101933 + @Param[in] p_Memory - pointer to the memory block.
101934 +
101935 + @Return None.
101936 +*//***************************************************************************/
101937 +void XX_FreeSmart(void *p_Memory);
101938 +
101939 +/**************************************************************************//**
101940 + @Function XX_Free
101941 +
101942 + @Description frees the memory block pointed to by "p".
101943 +
101944 + @Param[in] p_Memory - pointer to the memory block.
101945 +
101946 + @Return None.
101947 +*//***************************************************************************/
101948 +void XX_Free(void *p_Memory);
101949 +
101950 +/**************************************************************************//**
101951 + @Function XX_Print
101952 +
101953 + @Description print a string.
101954 +
101955 + @Param[in] str - string to print.
101956 +
101957 + @Return None.
101958 +*//***************************************************************************/
101959 +void XX_Print(char *str, ...);
101960 +
101961 +/**************************************************************************//**
101962 + @Function XX_SetIntr
101963 +
101964 + @Description Set an interrupt service routine for a specific interrupt source.
101965 +
101966 + @Param[in] irq - Interrupt ID (system-specific number).
101967 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
101968 + @Param[in] handle - The argument for the user callback routine.
101969 +
101970 + @Return E_OK on success; error code otherwise..
101971 +*//***************************************************************************/
101972 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
101973 +
101974 +/**************************************************************************//**
101975 + @Function XX_FreeIntr
101976 +
101977 + @Description Free a specific interrupt and a specific callback routine.
101978 +
101979 + @Param[in] irq - Interrupt ID (system-specific number).
101980 +
101981 + @Return E_OK on success; error code otherwise..
101982 +*//***************************************************************************/
101983 +t_Error XX_FreeIntr(int irq);
101984 +
101985 +/**************************************************************************//**
101986 + @Function XX_EnableIntr
101987 +
101988 + @Description Enable a specific interrupt.
101989 +
101990 + @Param[in] irq - Interrupt ID (system-specific number).
101991 +
101992 + @Return E_OK on success; error code otherwise..
101993 +*//***************************************************************************/
101994 +t_Error XX_EnableIntr(int irq);
101995 +
101996 +/**************************************************************************//**
101997 + @Function XX_DisableIntr
101998 +
101999 + @Description Disable a specific interrupt.
102000 +
102001 + @Param[in] irq - Interrupt ID (system-specific number).
102002 +
102003 + @Return E_OK on success; error code otherwise..
102004 +*//***************************************************************************/
102005 +t_Error XX_DisableIntr(int irq);
102006 +
102007 +/**************************************************************************//**
102008 + @Function XX_DisableAllIntr
102009 +
102010 + @Description Disable all interrupts by masking them at the CPU.
102011 +
102012 + @Return A value that represents the interrupts state before the
102013 + operation, and should be passed to the matching
102014 + XX_RestoreAllIntr() call.
102015 +*//***************************************************************************/
102016 +uint32_t XX_DisableAllIntr(void);
102017 +
102018 +/**************************************************************************//**
102019 + @Function XX_RestoreAllIntr
102020 +
102021 + @Description Restore previous state of interrupts level at the CPU.
102022 +
102023 + @Param[in] flags - A value that represents the interrupts state to restore,
102024 + as returned by the matching call for XX_DisableAllIntr().
102025 +
102026 + @Return None.
102027 +*//***************************************************************************/
102028 +void XX_RestoreAllIntr(uint32_t flags);
102029 +
102030 +
102031 +/**************************************************************************//**
102032 + @Function XX_Exit
102033 +
102034 + @Description Stop execution and report status (where it is applicable)
102035 +
102036 + @Param[in] status - exit status
102037 +*//***************************************************************************/
102038 +void XX_Exit(int status);
102039 +
102040 +
102041 +/*****************************************************************************/
102042 +/* Tasklet Service Routines */
102043 +/*****************************************************************************/
102044 +typedef t_Handle t_TaskletHandle;
102045 +
102046 +/**************************************************************************//**
102047 + @Function XX_InitTasklet
102048 +
102049 + @Description Create and initialize a tasklet object.
102050 +
102051 + @Param[in] routine - A routine to be ran as a tasklet.
102052 + @Param[in] data - An argument to pass to the tasklet.
102053 +
102054 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
102055 +*//***************************************************************************/
102056 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
102057 +
102058 +/**************************************************************************//**
102059 + @Function XX_FreeTasklet
102060 +
102061 + @Description Free a tasklet object.
102062 +
102063 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
102064 +
102065 + @Return None.
102066 +*//***************************************************************************/
102067 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
102068 +
102069 +/**************************************************************************//**
102070 + @Function XX_ScheduleTask
102071 +
102072 + @Description Schedule a tasklet object.
102073 +
102074 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102075 + @Param[in] immediate - Indicate whether to schedule this tasklet on
102076 + the immediate queue or on the delayed one.
102077 +
102078 + @Return 0 - on success. Error code - otherwise.
102079 +*//***************************************************************************/
102080 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
102081 +
102082 +/**************************************************************************//**
102083 + @Function XX_FlushScheduledTasks
102084 +
102085 + @Description Flush all tasks there are in the scheduled tasks queue.
102086 +
102087 + @Return None.
102088 +*//***************************************************************************/
102089 +void XX_FlushScheduledTasks(void);
102090 +
102091 +/**************************************************************************//**
102092 + @Function XX_TaskletIsQueued
102093 +
102094 + @Description Check if task is queued.
102095 +
102096 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102097 +
102098 + @Return 1 - task is queued. 0 - otherwise.
102099 +*//***************************************************************************/
102100 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
102101 +
102102 +/**************************************************************************//**
102103 + @Function XX_SetTaskletData
102104 +
102105 + @Description Set data to a scheduled task. Used to change data of already
102106 + scheduled task.
102107 +
102108 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102109 + @Param[in] data - Data to be set.
102110 +*//***************************************************************************/
102111 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
102112 +
102113 +/**************************************************************************//**
102114 + @Function XX_GetTaskletData
102115 +
102116 + @Description Get the data of scheduled task.
102117 +
102118 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102119 +
102120 + @Return handle to the data of the task.
102121 +*//***************************************************************************/
102122 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
102123 +
102124 +/**************************************************************************//**
102125 + @Function XX_BottomHalf
102126 +
102127 + @Description Bottom half implementation, invoked by the interrupt handler.
102128 +
102129 + This routine handles all bottom-half tasklets with interrupts
102130 + enabled.
102131 +
102132 + @Return None.
102133 +*//***************************************************************************/
102134 +void XX_BottomHalf(void);
102135 +
102136 +
102137 +/*****************************************************************************/
102138 +/* Spinlock Service Routines */
102139 +/*****************************************************************************/
102140 +
102141 +/**************************************************************************//**
102142 + @Function XX_InitSpinlock
102143 +
102144 + @Description Creates a spinlock.
102145 +
102146 + @Return Spinlock handle is returned on success; NULL otherwise.
102147 +*//***************************************************************************/
102148 +t_Handle XX_InitSpinlock(void);
102149 +
102150 +/**************************************************************************//**
102151 + @Function XX_FreeSpinlock
102152 +
102153 + @Description Frees the memory allocated for the spinlock creation.
102154 +
102155 + @Param[in] h_Spinlock - A handle to a spinlock.
102156 +
102157 + @Return None.
102158 +*//***************************************************************************/
102159 +void XX_FreeSpinlock(t_Handle h_Spinlock);
102160 +
102161 +/**************************************************************************//**
102162 + @Function XX_LockSpinlock
102163 +
102164 + @Description Locks a spinlock.
102165 +
102166 + @Param[in] h_Spinlock - A handle to a spinlock.
102167 +
102168 + @Return None.
102169 +*//***************************************************************************/
102170 +void XX_LockSpinlock(t_Handle h_Spinlock);
102171 +
102172 +/**************************************************************************//**
102173 + @Function XX_UnlockSpinlock
102174 +
102175 + @Description Unlocks a spinlock.
102176 +
102177 + @Param[in] h_Spinlock - A handle to a spinlock.
102178 +
102179 + @Return None.
102180 +*//***************************************************************************/
102181 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
102182 +
102183 +/**************************************************************************//**
102184 + @Function XX_LockIntrSpinlock
102185 +
102186 + @Description Locks a spinlock (interrupt safe).
102187 +
102188 + @Param[in] h_Spinlock - A handle to a spinlock.
102189 +
102190 + @Return A value that represents the interrupts state before the
102191 + operation, and should be passed to the matching
102192 + XX_UnlockIntrSpinlock() call.
102193 +*//***************************************************************************/
102194 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
102195 +
102196 +/**************************************************************************//**
102197 + @Function XX_UnlockIntrSpinlock
102198 +
102199 + @Description Unlocks a spinlock (interrupt safe).
102200 +
102201 + @Param[in] h_Spinlock - A handle to a spinlock.
102202 + @Param[in] intrFlags - A value that represents the interrupts state to
102203 + restore, as returned by the matching call for
102204 + XX_LockIntrSpinlock().
102205 +
102206 + @Return None.
102207 +*//***************************************************************************/
102208 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
102209 +
102210 +
102211 +/*****************************************************************************/
102212 +/* Timers Service Routines */
102213 +/*****************************************************************************/
102214 +
102215 +/**************************************************************************//**
102216 + @Function XX_CurrentTime
102217 +
102218 + @Description Returns current system time.
102219 +
102220 + @Return Current system time (in milliseconds).
102221 +*//***************************************************************************/
102222 +uint32_t XX_CurrentTime(void);
102223 +
102224 +/**************************************************************************//**
102225 + @Function XX_CreateTimer
102226 +
102227 + @Description Creates a timer.
102228 +
102229 + @Return Timer handle is returned on success; NULL otherwise.
102230 +*//***************************************************************************/
102231 +t_Handle XX_CreateTimer(void);
102232 +
102233 +/**************************************************************************//**
102234 + @Function XX_FreeTimer
102235 +
102236 + @Description Frees the memory allocated for the timer creation.
102237 +
102238 + @Param[in] h_Timer - A handle to a timer.
102239 +
102240 + @Return None.
102241 +*//***************************************************************************/
102242 +void XX_FreeTimer(t_Handle h_Timer);
102243 +
102244 +/**************************************************************************//**
102245 + @Function XX_StartTimer
102246 +
102247 + @Description Starts a timer.
102248 +
102249 + The user can select to start the timer as periodic timer or as
102250 + one-shot timer. The user should provide a callback routine that
102251 + will be called when the timer expires.
102252 +
102253 + @Param[in] h_Timer - A handle to a timer.
102254 + @Param[in] msecs - Timer expiration period (in milliseconds).
102255 + @Param[in] periodic - TRUE for a periodic timer;
102256 + FALSE for a one-shot timer..
102257 + @Param[in] f_TimerExpired - A callback routine to be called when the
102258 + timer expires.
102259 + @Param[in] h_Arg - The argument to pass in the timer-expired
102260 + callback routine.
102261 +
102262 + @Return None.
102263 +*//***************************************************************************/
102264 +void XX_StartTimer(t_Handle h_Timer,
102265 + uint32_t msecs,
102266 + bool periodic,
102267 + void (*f_TimerExpired)(t_Handle h_Arg),
102268 + t_Handle h_Arg);
102269 +
102270 +/**************************************************************************//**
102271 + @Function XX_StopTimer
102272 +
102273 + @Description Frees the memory allocated for the timer creation.
102274 +
102275 + @Param[in] h_Timer - A handle to a timer.
102276 +
102277 + @Return None.
102278 +*//***************************************************************************/
102279 +void XX_StopTimer(t_Handle h_Timer);
102280 +
102281 +/**************************************************************************//**
102282 + @Function XX_ModTimer
102283 +
102284 + @Description Updates the expiration time of a timer.
102285 +
102286 + This routine adds the given time to the current system time,
102287 + and sets this value as the new expiration time of the timer.
102288 +
102289 + @Param[in] h_Timer - A handle to a timer.
102290 + @Param[in] msecs - The new interval until timer expiration
102291 + (in milliseconds).
102292 +
102293 + @Return None.
102294 +*//***************************************************************************/
102295 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
102296 +
102297 +/**************************************************************************//**
102298 + @Function XX_Sleep
102299 +
102300 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
102301 +
102302 + @Param[in] msecs - The requested sleep time (in milliseconds).
102303 +
102304 + @Return Zero if the requested time has elapsed; Otherwise, the value
102305 + returned will be the unslept amount) in milliseconds.
102306 +
102307 + @Cautions This routine enables interrupts during its wait time.
102308 +*//***************************************************************************/
102309 +uint32_t XX_Sleep(uint32_t msecs);
102310 +
102311 +/**************************************************************************//**
102312 + @Function XX_UDelay
102313 +
102314 + @Description Busy-wait until the desired time (in microseconds) has passed.
102315 +
102316 + @Param[in] usecs - The requested delay time (in microseconds).
102317 +
102318 + @Return None.
102319 +
102320 + @Cautions It is highly unrecommended to call this routine during interrupt
102321 + time, because the system time may not be updated properly during
102322 + the delay loop. The behavior of this routine during interrupt
102323 + time is unexpected.
102324 +*//***************************************************************************/
102325 +void XX_UDelay(uint32_t usecs);
102326 +
102327 +
102328 +/*****************************************************************************/
102329 +/* Other Service Routines */
102330 +/*****************************************************************************/
102331 +
102332 +/**************************************************************************//**
102333 + @Function XX_PhysToVirt
102334 +
102335 + @Description Translates a physical address to the matching virtual address.
102336 +
102337 + @Param[in] addr - The physical address to translate.
102338 +
102339 + @Return Virtual address.
102340 +*//***************************************************************************/
102341 +void * XX_PhysToVirt(physAddress_t addr);
102342 +
102343 +/**************************************************************************//**
102344 + @Function XX_VirtToPhys
102345 +
102346 + @Description Translates a virtual address to the matching physical address.
102347 +
102348 + @Param[in] addr - The virtual address to translate.
102349 +
102350 + @Return Physical address.
102351 +*//***************************************************************************/
102352 +physAddress_t XX_VirtToPhys(void *addr);
102353 +
102354 +
102355 +/**************************************************************************//**
102356 + @Group xx_ipc XX Inter-Partition-Communication API
102357 +
102358 + @Description The following API is to be used when working with multiple
102359 + partitions configuration.
102360 +
102361 + @{
102362 +*//***************************************************************************/
102363 +
102364 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
102365 + The IPC service can use this constant to limit
102366 + the storage space for IPC endpoint names. */
102367 +
102368 +
102369 +/**************************************************************************//**
102370 + @Function t_IpcMsgCompletion
102371 +
102372 + @Description Callback function used upon IPC non-blocking transaction completion
102373 + to return message buffer to the caller and to forward reply if available.
102374 +
102375 + This callback function may be attached by the source endpoint to any outgoing
102376 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
102377 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
102378 + the IPC service invokes this callback routine to return the message buffer to the sender
102379 + and to provide the received reply, if requested.
102380 +
102381 + User provides this function. Driver invokes it.
102382 +
102383 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
102384 + in the XX_IpcSendMessage() function; This handle is typically used to point
102385 + to the internal data structure of the source endpoint.
102386 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
102387 + The source endpoint can free (or reuse) this buffer when message
102388 + completion callback is called.
102389 + @Param[in] p_Reply - Pointer to (received) reply buffer;
102390 + This pointer is the same as was provided by the source endpoint in
102391 + XX_IpcSendMessage().
102392 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
102393 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
102394 + timeout.
102395 +
102396 + @Return None
102397 + *//***************************************************************************/
102398 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
102399 + uint8_t *p_Msg,
102400 + uint8_t *p_Reply,
102401 + uint32_t replyLength,
102402 + t_Error status);
102403 +
102404 +/**************************************************************************//**
102405 + @Function t_IpcMsgHandler
102406 +
102407 + @Description Callback function used as IPC message handler.
102408 +
102409 + The IPC service invokes message handlers for each IPC message received.
102410 + The actual function pointer should be registered by each destination endpoint
102411 + via the XX_IpcRegisterMsgHandler() routine.
102412 +
102413 + User provides this function. Driver invokes it.
102414 +
102415 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
102416 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
102417 + typically used to point to the internal data structure of the destination
102418 + endpoint.
102419 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
102420 + @Param[in] msgLength - Length (in bytes) of message data.
102421 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
102422 + by the IPC service;
102423 + The reply buffer is allocated by the IPC service with size equals to the
102424 + replyLength parameter provided in message handler registration (see
102425 + XX_IpcRegisterMsgHandler() function);
102426 + If replyLength was initially specified as zero during message handler registration,
102427 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
102428 + The IPC service is also responsible for freeing the reply buffer after the
102429 + reply has been sent or dismissed.
102430 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102431 + [In] equals the replyLength parameter provided in message handler
102432 + registration (see XX_IpcRegisterMsgHandler() function), and
102433 + [Out] should be updated by message handler to the actual reply length; if
102434 + this value is set to zero, the IPC service must assume that a reply should
102435 + not be sent;
102436 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
102437 +
102438 + @Return E_OK on success; Error code otherwise.
102439 + *//***************************************************************************/
102440 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
102441 + uint8_t *p_Msg,
102442 + uint32_t msgLength,
102443 + uint8_t *p_Reply,
102444 + uint32_t *p_ReplyLength);
102445 +
102446 +/**************************************************************************//**
102447 + @Function XX_IpcRegisterMsgHandler
102448 +
102449 + @Description IPC mailbox registration.
102450 +
102451 + This function is used for registering an IPC message handler in the IPC service.
102452 + This function is called by each destination endpoint to indicate that it is ready
102453 + to handle incoming messages. The IPC service invokes the message handler upon receiving
102454 + a message addressed to the specified destination endpoint.
102455 +
102456 + @Param[in] addr - The address name string associated with the destination endpoint;
102457 + This address must be unique across the IPC service domain to ensure
102458 + correct message routing.
102459 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
102460 + message; invoked by the IPC service upon receiving a message
102461 + addressed to the destination endpoint specified by the addr
102462 + parameter.
102463 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
102464 + to f_MsgHandler callback function.
102465 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
102466 + may generate; the IPC service provides the message handler with buffer
102467 + for reply according to the length specified here (refer also to the description
102468 + of #t_IpcMsgHandler callback function type);
102469 + This size shall be zero if the message handler never generates replies.
102470 +
102471 + @Return E_OK on success; Error code otherwise.
102472 +*//***************************************************************************/
102473 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102474 + t_IpcMsgHandler *f_MsgHandler,
102475 + t_Handle h_Module,
102476 + uint32_t replyLength);
102477 +
102478 +/**************************************************************************//**
102479 + @Function XX_IpcUnregisterMsgHandler
102480 +
102481 + @Description Release IPC mailbox routine.
102482 +
102483 + This function is used for unregistering an IPC message handler from the IPC service.
102484 + This function is called by each destination endpoint to indicate that it is no longer
102485 + capable of handling incoming messages.
102486 +
102487 + @Param[in] addr - The address name string associated with the destination endpoint;
102488 + This address is the same as was used when the message handler was
102489 + registered via XX_IpcRegisterMsgHandler().
102490 +
102491 + @Return E_OK on success; Error code otherwise.
102492 +*//***************************************************************************/
102493 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102494 +
102495 +/**************************************************************************//**
102496 + @Function XX_IpcInitSession
102497 +
102498 + @Description This function is used for creating an IPC session between the source endpoint
102499 + and the destination endpoint.
102500 +
102501 + The actual implementation and representation of a session is left for the IPC service.
102502 + The function returns an abstract handle to the created session. This handle shall be used
102503 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
102504 + The IPC service assumes that before this function is called, no messages are sent from
102505 + the specified source endpoint to the specified destination endpoint.
102506 +
102507 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
102508 + as described below.
102509 +
102510 + @par Connection-Oriented Approach
102511 +
102512 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
102513 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
102514 + and a destination-to-source channel for replies. The returned handle should represent the internal
102515 + representation of these channels.
102516 +
102517 + @par Connectionless Approach
102518 +
102519 + The IPC service may implement a session in a connectionless approach - when this function is called, the
102520 + IPC service should not perform any particular steps, but it must store the pair of source and destination
102521 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
102522 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
102523 + through the connectionless medium.
102524 +
102525 + @Param[in] destAddr - The address name string associated with the destination endpoint.
102526 + @Param[in] srcAddr - The address name string associated with the source endpoint.
102527 +
102528 + @Return Abstract handle to the initialized session, or NULL on error.
102529 +*//***************************************************************************/
102530 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102531 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102532 +
102533 +/**************************************************************************//**
102534 + @Function XX_IpcFreeSession
102535 +
102536 + @Description This function is used for terminating an existing IPC session between a source endpoint
102537 + and a destination endpoint.
102538 +
102539 + The IPC service assumes that after this function is called, no messages shall be sent from
102540 + the associated source endpoint to the associated destination endpoint.
102541 +
102542 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102543 + returned by the XX_IpcInitSession() function.
102544 +
102545 + @Return E_OK on success; Error code otherwise.
102546 +*//***************************************************************************/
102547 +t_Error XX_IpcFreeSession(t_Handle h_Session);
102548 +
102549 +/**************************************************************************//**
102550 + @Function XX_IpcSendMessage
102551 +
102552 + @Description IPC message send routine.
102553 +
102554 + This function may be used by a source endpoint to send an IPC message to a destination
102555 + endpoint. The source endpoint cannot send a message to the destination endpoint without
102556 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
102557 +
102558 + The source endpoint must provide the buffer pointer and length of the outgoing message.
102559 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
102560 + transaction is not considered complete by the IPC service until the reply has been received.
102561 + If the source endpoint does not provide a reply buffer, the transaction is considered
102562 + complete after the message has been sent. The source endpoint must keep the message (and
102563 + optional reply) buffers valid until the transaction is complete.
102564 +
102565 + @par Non-blocking mode
102566 +
102567 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
102568 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
102569 + message and an optional reply), the IPC service invokes this callback routine to return the message
102570 + buffer to the sender and to provide the received reply, if requested.
102571 +
102572 + @par Blocking mode
102573 +
102574 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
102575 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
102576 + was requested) the message has been sent.
102577 +
102578 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102579 + returned by the XX_IpcInitSession() function.
102580 + @Param[in] p_Msg - Pointer to message buffer to send.
102581 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
102582 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
102583 + fills this buffer with the received reply data;
102584 + In blocking mode, the reply data must be valid when the function returns;
102585 + In non-blocking mode, the reply data is valid when f_Completion is called;
102586 + If this pointer is NULL, no reply is expected.
102587 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102588 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
102589 + p_Reply, and
102590 + [Out] in non-blocking mode this value is updated by the IPC service to the
102591 + actual reply length (in bytes).
102592 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
102593 + The completion callback is invoked by the IPC service upon
102594 + completion of the IPC transaction (consisting of a message and an optional
102595 + reply);
102596 + If this pointer is NULL, the function is expected to block until the IPC
102597 + transaction is complete.
102598 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
102599 + callback function as the first argument.
102600 +
102601 + @Return E_OK on success; Error code otherwise.
102602 +*//***************************************************************************/
102603 +t_Error XX_IpcSendMessage(t_Handle h_Session,
102604 + uint8_t *p_Msg,
102605 + uint32_t msgLength,
102606 + uint8_t *p_Reply,
102607 + uint32_t *p_ReplyLength,
102608 + t_IpcMsgCompletion *f_Completion,
102609 + t_Handle h_Arg);
102610 +
102611 +
102612 +/** @} */ /* end of xx_ipc group */
102613 +/** @} */ /* end of xx_id group */
102614 +
102615 +
102616 +#endif /* __XX_EXT_H */
102617 --- /dev/null
102618 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
102619 @@ -0,0 +1,56 @@
102620 +/*
102621 + * Copyright 2012 Freescale Semiconductor Inc.
102622 + *
102623 + * Redistribution and use in source and binary forms, with or without
102624 + * modification, are permitted provided that the following conditions are met:
102625 + * * Redistributions of source code must retain the above copyright
102626 + * notice, this list of conditions and the following disclaimer.
102627 + * * Redistributions in binary form must reproduce the above copyright
102628 + * notice, this list of conditions and the following disclaimer in the
102629 + * documentation and/or other materials provided with the distribution.
102630 + * * Neither the name of Freescale Semiconductor nor the
102631 + * names of its contributors may be used to endorse or promote products
102632 + * derived from this software without specific prior written permission.
102633 + *
102634 + *
102635 + * ALTERNATIVELY, this software may be distributed under the terms of the
102636 + * GNU General Public License ("GPL") as published by the Free Software
102637 + * Foundation, either version 2 of that License or (at your option) any
102638 + * later version.
102639 + *
102640 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102641 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102642 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102643 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102644 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102645 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102646 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102647 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102648 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102649 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102650 + */
102651 +
102652 +#ifndef __dflags_h
102653 +#define __dflags_h
102654 +
102655 +
102656 +#define NCSW_LINUX
102657 +
102658 +#define LS1043
102659 +
102660 +#define DEBUG_ERRORS 1
102661 +
102662 +#if defined(DEBUG)
102663 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102664 +
102665 +#define DEBUG_XX_MALLOC
102666 +#define DEBUG_MEM_LEAKS
102667 +
102668 +#else
102669 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102670 +#endif /* (DEBUG) */
102671 +
102672 +#define REPORT_EVENTS 1
102673 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102674 +
102675 +#endif /* __dflags_h */
102676 --- /dev/null
102677 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
102678 @@ -0,0 +1,53 @@
102679 +#
102680 +# Makefile config for the Freescale NetcommSW
102681 +#
102682 +NET_DPA = $(srctree)/drivers/net
102683 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
102684 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
102685 +
102686 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
102687 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
102688 +endif
102689 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
102690 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
102691 +endif
102692 +ifdef CONFIG_FMAN_V3H
102693 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
102694 +endif
102695 +ifdef CONFIG_FMAN_V3L
102696 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
102697 +endif
102698 +ifdef CONFIG_FMAN_ARM
102699 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
102700 +endif
102701 +
102702 +ccflags-y += -I$(DRV_DPA)/
102703 +ccflags-y += -I$(FMAN)/inc
102704 +ccflags-y += -I$(FMAN)/inc/cores
102705 +ccflags-y += -I$(FMAN)/inc/etc
102706 +ccflags-y += -I$(FMAN)/inc/Peripherals
102707 +ccflags-y += -I$(FMAN)/inc/flib
102708 +
102709 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
102710 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
102711 +endif
102712 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
102713 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
102714 +endif
102715 +ifdef CONFIG_FMAN_V3H
102716 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
102717 +endif
102718 +ifdef CONFIG_FMAN_V3L
102719 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
102720 +endif
102721 +ifdef CONFIG_FMAN_ARM
102722 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
102723 +endif
102724 +
102725 +ccflags-y += -I$(FMAN)/src/inc
102726 +ccflags-y += -I$(FMAN)/src/inc/system
102727 +ccflags-y += -I$(FMAN)/src/inc/wrapper
102728 +ccflags-y += -I$(FMAN)/src/inc/xx
102729 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
102730 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
102731 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
102732 --- /dev/null
102733 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
102734 @@ -0,0 +1,65 @@
102735 +/*
102736 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102737 + *
102738 + * Redistribution and use in source and binary forms, with or without
102739 + * modification, are permitted provided that the following conditions are met:
102740 + * * Redistributions of source code must retain the above copyright
102741 + * notice, this list of conditions and the following disclaimer.
102742 + * * Redistributions in binary form must reproduce the above copyright
102743 + * notice, this list of conditions and the following disclaimer in the
102744 + * documentation and/or other materials provided with the distribution.
102745 + * * Neither the name of Freescale Semiconductor nor the
102746 + * names of its contributors may be used to endorse or promote products
102747 + * derived from this software without specific prior written permission.
102748 + *
102749 + *
102750 + * ALTERNATIVELY, this software may be distributed under the terms of the
102751 + * GNU General Public License ("GPL") as published by the Free Software
102752 + * Foundation, either version 2 of that License or (at your option) any
102753 + * later version.
102754 + *
102755 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102756 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102757 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102758 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102759 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102760 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102761 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102762 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102763 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102764 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102765 + */
102766 +
102767 +#ifndef __dflags_h
102768 +#define __dflags_h
102769 +
102770 +
102771 +#define NCSW_LINUX
102772 +#if 0
102773 +#define DEBUG
102774 +#endif
102775 +
102776 +#define P1023
102777 +#define NCSW_PPC_CORE
102778 +
102779 +#define DEBUG_ERRORS 1
102780 +
102781 +#if defined(DEBUG)
102782 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102783 +
102784 +#define DEBUG_XX_MALLOC
102785 +#define DEBUG_MEM_LEAKS
102786 +
102787 +#else
102788 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102789 +#endif /* (DEBUG) */
102790 +
102791 +#define REPORT_EVENTS 1
102792 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102793 +
102794 +#ifdef CONFIG_P4080_SIM
102795 +#error "Do not define CONFIG_P4080_SIM..."
102796 +#endif
102797 +
102798 +
102799 +#endif /* __dflags_h */
102800 --- /dev/null
102801 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
102802 @@ -0,0 +1,62 @@
102803 +/*
102804 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102805 + *
102806 + * Redistribution and use in source and binary forms, with or without
102807 + * modification, are permitted provided that the following conditions are met:
102808 + * * Redistributions of source code must retain the above copyright
102809 + * notice, this list of conditions and the following disclaimer.
102810 + * * Redistributions in binary form must reproduce the above copyright
102811 + * notice, this list of conditions and the following disclaimer in the
102812 + * documentation and/or other materials provided with the distribution.
102813 + * * Neither the name of Freescale Semiconductor nor the
102814 + * names of its contributors may be used to endorse or promote products
102815 + * derived from this software without specific prior written permission.
102816 + *
102817 + *
102818 + * ALTERNATIVELY, this software may be distributed under the terms of the
102819 + * GNU General Public License ("GPL") as published by the Free Software
102820 + * Foundation, either version 2 of that License or (at your option) any
102821 + * later version.
102822 + *
102823 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102824 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102825 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102826 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102827 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102828 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102829 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102830 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102831 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102832 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102833 + */
102834 +
102835 +#ifndef __dflags_h
102836 +#define __dflags_h
102837 +
102838 +
102839 +#define NCSW_LINUX
102840 +
102841 +#define P4080
102842 +#define NCSW_PPC_CORE
102843 +
102844 +#define DEBUG_ERRORS 1
102845 +
102846 +#if defined(DEBUG)
102847 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
102848 +
102849 +#define DEBUG_XX_MALLOC
102850 +#define DEBUG_MEM_LEAKS
102851 +
102852 +#else
102853 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
102854 +#endif /* (DEBUG) */
102855 +
102856 +#define REPORT_EVENTS 1
102857 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
102858 +
102859 +#ifdef CONFIG_P4080_SIM
102860 +#define SIMULATOR
102861 +#endif /* CONFIG_P4080_SIM */
102862 +
102863 +
102864 +#endif /* __dflags_h */
102865 --- /dev/null
102866 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
102867 @@ -0,0 +1,11 @@
102868 +#
102869 +# Makefile for the Freescale Ethernet controllers
102870 +#
102871 +ccflags-y += -DVERSION=\"\"
102872 +#
102873 +#Include netcomm SW specific definitions
102874 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
102875 +#
102876 +obj-y += system/
102877 +obj-y += wrapper/
102878 +obj-y += xx/
102879 --- /dev/null
102880 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
102881 @@ -0,0 +1,118 @@
102882 +/*
102883 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102884 + *
102885 + * Redistribution and use in source and binary forms, with or without
102886 + * modification, are permitted provided that the following conditions are met:
102887 + * * Redistributions of source code must retain the above copyright
102888 + * notice, this list of conditions and the following disclaimer.
102889 + * * Redistributions in binary form must reproduce the above copyright
102890 + * notice, this list of conditions and the following disclaimer in the
102891 + * documentation and/or other materials provided with the distribution.
102892 + * * Neither the name of Freescale Semiconductor nor the
102893 + * names of its contributors may be used to endorse or promote products
102894 + * derived from this software without specific prior written permission.
102895 + *
102896 + *
102897 + * ALTERNATIVELY, this software may be distributed under the terms of the
102898 + * GNU General Public License ("GPL") as published by the Free Software
102899 + * Foundation, either version 2 of that License or (at your option) any
102900 + * later version.
102901 + *
102902 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102903 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102904 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102905 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102906 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102907 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102908 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102909 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102910 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102911 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102912 + */
102913 +
102914 +#ifndef __SYS_EXT_H
102915 +#define __SYS_EXT_H
102916 +
102917 +#include "std_ext.h"
102918 +
102919 +
102920 +/**************************************************************************//**
102921 + @Group sys_grp System Interfaces
102922 +
102923 + @Description Linux system programming interfaces.
102924 +
102925 + @{
102926 +*//***************************************************************************/
102927 +
102928 +/**************************************************************************//**
102929 + @Group sys_gen_grp System General Interface
102930 +
102931 + @Description General definitions, structures and routines of the linux
102932 + system programming interface.
102933 +
102934 + @{
102935 +*//***************************************************************************/
102936 +
102937 +/**************************************************************************//**
102938 + @Collection Macros for Advanced Configuration Requests
102939 + @{
102940 +*//***************************************************************************/
102941 +#define SYS_MAX_ADV_CONFIG_ARGS 4
102942 + /**< Maximum number of arguments in
102943 + an advanced configuration entry */
102944 +/* @} */
102945 +
102946 +/**************************************************************************//**
102947 + @Description System Object Advanced Configuration Entry
102948 +
102949 + This structure represents a single request for an advanced
102950 + configuration call on the initialized object. An array of such
102951 + requests may be contained in the settings structure of the
102952 + corresponding object.
102953 +
102954 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
102955 +*//***************************************************************************/
102956 +typedef struct t_SysObjectAdvConfigEntry
102957 +{
102958 + void *p_Function; /**< Pointer to advanced configuration routine */
102959 +
102960 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
102961 + /**< Array of arguments for the specified routine;
102962 + All arguments should be casted to uint32_t. */
102963 +} t_SysObjectAdvConfigEntry;
102964 +
102965 +
102966 +/** @} */ /* end of sys_gen_grp */
102967 +/** @} */ /* end of sys_grp */
102968 +
102969 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
102970 +
102971 +#define ADV_CONFIG_PARAMS_1(_type) \
102972 + , (_type)p_Entry->args[0]
102973 +
102974 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
102975 + p_Entry->args[0] = (uintptr_t )(_arg0); \
102976 +
102977 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
102978 +
102979 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
102980 + { \
102981 + t_SysObjectAdvConfigEntry *p_Entry; \
102982 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
102983 + int i=0, max = (_maxEntries); \
102984 +
102985 +#define ADD_ADV_CONFIG_END \
102986 + }
102987 +
102988 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
102989 + { \
102990 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
102991 + t_Error errCode; \
102992 +
102993 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
102994 + if (p_Entry->p_Function == _func) \
102995 + { \
102996 + errCode = _func(_handle _params); \
102997 + } else
102998 +
102999 +#endif /* __SYS_EXT_H */
103000 --- /dev/null
103001 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103002 @@ -0,0 +1,46 @@
103003 +/*
103004 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103005 + *
103006 + * Redistribution and use in source and binary forms, with or without
103007 + * modification, are permitted provided that the following conditions are met:
103008 + * * Redistributions of source code must retain the above copyright
103009 + * notice, this list of conditions and the following disclaimer.
103010 + * * Redistributions in binary form must reproduce the above copyright
103011 + * notice, this list of conditions and the following disclaimer in the
103012 + * documentation and/or other materials provided with the distribution.
103013 + * * Neither the name of Freescale Semiconductor nor the
103014 + * names of its contributors may be used to endorse or promote products
103015 + * derived from this software without specific prior written permission.
103016 + *
103017 + *
103018 + * ALTERNATIVELY, this software may be distributed under the terms of the
103019 + * GNU General Public License ("GPL") as published by the Free Software
103020 + * Foundation, either version 2 of that License or (at your option) any
103021 + * later version.
103022 + *
103023 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103024 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103025 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103026 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103027 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103028 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103029 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103030 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103031 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103032 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103033 + */
103034 +
103035 +#ifndef __SYS_IO_EXT_H
103036 +#define __SYS_IO_EXT_H
103037 +
103038 +#include "std_ext.h"
103039 +#include "error_ext.h"
103040 +
103041 +
103042 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
103043 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
103044 +uint64_t SYS_PhysToVirt (uint64_t addr);
103045 +uint64_t SYS_VirtToPhys (uint64_t addr);
103046 +
103047 +
103048 +#endif /* __SYS_IO_EXT_H */
103049 --- /dev/null
103050 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103051 @@ -0,0 +1,208 @@
103052 +/*
103053 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103054 + *
103055 + * Redistribution and use in source and binary forms, with or without
103056 + * modification, are permitted provided that the following conditions are met:
103057 + * * Redistributions of source code must retain the above copyright
103058 + * notice, this list of conditions and the following disclaimer.
103059 + * * Redistributions in binary form must reproduce the above copyright
103060 + * notice, this list of conditions and the following disclaimer in the
103061 + * documentation and/or other materials provided with the distribution.
103062 + * * Neither the name of Freescale Semiconductor nor the
103063 + * names of its contributors may be used to endorse or promote products
103064 + * derived from this software without specific prior written permission.
103065 + *
103066 + *
103067 + * ALTERNATIVELY, this software may be distributed under the terms of the
103068 + * GNU General Public License ("GPL") as published by the Free Software
103069 + * Foundation, either version 2 of that License or (at your option) any
103070 + * later version.
103071 + *
103072 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103073 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103074 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103075 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103076 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103077 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103078 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103079 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103080 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103081 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103082 + */
103083 +
103084 +#ifndef __TYPES_LINUX_H__
103085 +#define __TYPES_LINUX_H__
103086 +
103087 +#include <linux/version.h>
103088 +
103089 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
103090 +#define MODVERSIONS
103091 +#endif
103092 +#ifdef MODVERSIONS
103093 +#include <config/modversions.h>
103094 +#endif /* MODVERSIONS */
103095 +
103096 +#include <linux/kernel.h>
103097 +#include <linux/types.h>
103098 +#include <asm/io.h>
103099 +#include <linux/delay.h>
103100 +
103101 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
103102 + #error "This kernel is probably not supported!!!"
103103 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
103104 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
103105 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
103106 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
103107 +#endif /* LINUX_VERSION_CODE */
103108 +
103109 +
103110 +typedef float float_t; /* Single precision floating point */
103111 +typedef double double_t; /* Double precision floating point */
103112 +
103113 +
103114 +#define _Packed
103115 +#define _PackedType __attribute__ ((packed))
103116 +
103117 +typedef phys_addr_t physAddress_t;
103118 +
103119 +#define UINT8_MAX 0xFF
103120 +#define UINT8_MIN 0
103121 +#define UINT16_MAX 0xFFFF
103122 +#define UINT16_MIN 0
103123 +#define UINT32_MAX 0xFFFFFFFF
103124 +#define UINT32_MIN 0
103125 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
103126 +#define UINT64_MIN 0
103127 +#define INT8_MAX 0x7F
103128 +#define INT8_MIN 0x80
103129 +#define INT16_MAX 0x7FFF
103130 +#define INT16_MIN 0x8000
103131 +#define INT32_MAX 0x7FFFFFFF
103132 +#define INT32_MIN 0x80000000
103133 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
103134 +#define INT64_MIN 0x8000000000000000LL
103135 +
103136 +#define ON 1
103137 +#define OFF 0
103138 +
103139 +#define FALSE false
103140 +#define TRUE true
103141 +
103142 +
103143 +/************************/
103144 +/* memory access macros */
103145 +/************************/
103146 +#ifdef CONFIG_FMAN_ARM
103147 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
103148 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
103149 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
103150 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
103151 +#endif
103152 +
103153 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
103154 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
103155 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
103156 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
103157 +
103158 +#ifdef VERBOSE_WRITE
103159 +void XX_Print(char *str, ...);
103160 +#define WRITE_UINT8(arg, data) \
103161 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
103162 +#define WRITE_UINT16(arg, data) \
103163 + 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)
103164 +#define WRITE_UINT32(arg, data) \
103165 + 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)
103166 +#define WRITE_UINT64(arg, data) \
103167 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
103168 +
103169 +#else /* not VERBOSE_WRITE */
103170 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
103171 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
103172 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
103173 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
103174 +#endif /* not VERBOSE_WRITE */
103175 +
103176 +
103177 +/*****************************************************************************/
103178 +/* General stuff */
103179 +/*****************************************************************************/
103180 +#ifdef ARRAY_SIZE
103181 +#undef ARRAY_SIZE
103182 +#endif /* ARRAY_SIZE */
103183 +
103184 +#ifdef MAJOR
103185 +#undef MAJOR
103186 +#endif /* MAJOR */
103187 +
103188 +#ifdef MINOR
103189 +#undef MINOR
103190 +#endif /* MINOR */
103191 +
103192 +#ifdef QE_SIZEOF_BD
103193 +#undef QE_SIZEOF_BD
103194 +#endif /* QE_SIZEOF_BD */
103195 +
103196 +#ifdef BD_BUFFER_CLEAR
103197 +#undef BD_BUFFER_CLEAR
103198 +#endif /* BD_BUFFER_CLEAR */
103199 +
103200 +#ifdef BD_BUFFER
103201 +#undef BD_BUFFER
103202 +#endif /* BD_BUFFER */
103203 +
103204 +#ifdef BD_STATUS_AND_LENGTH_SET
103205 +#undef BD_STATUS_AND_LENGTH_SET
103206 +#endif /* BD_STATUS_AND_LENGTH_SET */
103207 +
103208 +#ifdef BD_STATUS_AND_LENGTH
103209 +#undef BD_STATUS_AND_LENGTH
103210 +#endif /* BD_STATUS_AND_LENGTH */
103211 +
103212 +#ifdef BD_BUFFER_ARG
103213 +#undef BD_BUFFER_ARG
103214 +#endif /* BD_BUFFER_ARG */
103215 +
103216 +#ifdef BD_GET_NEXT
103217 +#undef BD_GET_NEXT
103218 +#endif /* BD_GET_NEXT */
103219 +
103220 +#ifdef QE_SDEBCR_BA_MASK
103221 +#undef QE_SDEBCR_BA_MASK
103222 +#endif /* QE_SDEBCR_BA_MASK */
103223 +
103224 +#ifdef BD_BUFFER_SET
103225 +#undef BD_BUFFER_SET
103226 +#endif /* BD_BUFFER_SET */
103227 +
103228 +#ifdef UPGCR_PROTOCOL
103229 +#undef UPGCR_PROTOCOL
103230 +#endif /* UPGCR_PROTOCOL */
103231 +
103232 +#ifdef UPGCR_TMS
103233 +#undef UPGCR_TMS
103234 +#endif /* UPGCR_TMS */
103235 +
103236 +#ifdef UPGCR_RMS
103237 +#undef UPGCR_RMS
103238 +#endif /* UPGCR_RMS */
103239 +
103240 +#ifdef UPGCR_ADDR
103241 +#undef UPGCR_ADDR
103242 +#endif /* UPGCR_ADDR */
103243 +
103244 +#ifdef UPGCR_DIAG
103245 +#undef UPGCR_DIAG
103246 +#endif /* UPGCR_DIAG */
103247 +
103248 +#ifdef NCSW_PARAMS
103249 +#undef NCSW_PARAMS
103250 +#endif /* NCSW_PARAMS */
103251 +
103252 +#ifdef NO_IRQ
103253 +#undef NO_IRQ
103254 +#endif /* NO_IRQ */
103255 +
103256 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
103257 +
103258 +
103259 +#endif /* __TYPES_LINUX_H__ */
103260 --- /dev/null
103261 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103262 @@ -0,0 +1,84 @@
103263 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
103264 + * All rights reserved.
103265 + *
103266 + * Redistribution and use in source and binary forms, with or without
103267 + * modification, are permitted provided that the following conditions are met:
103268 + * * Redistributions of source code must retain the above copyright
103269 + * notice, this list of conditions and the following disclaimer.
103270 + * * Redistributions in binary form must reproduce the above copyright
103271 + * notice, this list of conditions and the following disclaimer in the
103272 + * documentation and/or other materials provided with the distribution.
103273 + * * Neither the name of Freescale Semiconductor nor the
103274 + * names of its contributors may be used to endorse or promote products
103275 + * derived from this software without specific prior written permission.
103276 + *
103277 + *
103278 + * ALTERNATIVELY, this software may be distributed under the terms of the
103279 + * GNU General Public License ("GPL") as published by the Free Software
103280 + * Foundation, either version 2 of that License or (at your option) any
103281 + * later version.
103282 + *
103283 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103284 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103285 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103286 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103287 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103288 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103289 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103290 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103291 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103292 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103293 + */
103294 +
103295 +/******************************************************************************
103296 + @File fsl_fman_test.h
103297 +
103298 + @Description
103299 +*//***************************************************************************/
103300 +
103301 +#ifndef __FSL_FMAN_TEST_H
103302 +#define __FSL_FMAN_TEST_H
103303 +
103304 +#include <linux/types.h>
103305 +#include <linux/smp.h> /* raw_smp_processor_id() */
103306 +
103307 +//#define FMT_K_DBG
103308 +//#define FMT_K_DBG_RUNTIME
103309 +
103310 +#define _fmt_prk(stage, format, arg...) \
103311 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
103312 +
103313 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
103314 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
103315 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
103316 +
103317 +/* there are two macros for debugging: for runtime and generic.
103318 + * Helps when the runtime functions are not targeted for debugging,
103319 + * thus all the unnecessary information will be skipped.
103320 + */
103321 +/* used for generic debugging */
103322 +#if defined(FMT_K_DBG)
103323 + #define _fmt_dbg(format, arg...) \
103324 + printk("fmt [%s:%u](cpu:%u) - " format, \
103325 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103326 +#else
103327 +# define _fmt_dbg(arg...)
103328 +#endif
103329 +
103330 +/* used for debugging runtime functions */
103331 +#if defined(FMT_K_DBG_RUNTIME)
103332 + #define _fmt_dbgr(format, arg...) \
103333 + printk("fmt [%s:%u](cpu:%u) - " format, \
103334 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103335 +#else
103336 +# define _fmt_dbgr(arg...)
103337 +#endif
103338 +
103339 +#define FMT_RX_ERR_Q 0xffffffff
103340 +#define FMT_RX_DFLT_Q 0xfffffffe
103341 +#define FMT_TX_ERR_Q 0xfffffffd
103342 +#define FMT_TX_CONF_Q 0xfffffffc
103343 +
103344 +#define FMAN_TEST_MAX_TX_FQS 8
103345 +
103346 +#endif /* __FSL_FMAN_TEST_H */
103347 --- /dev/null
103348 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
103349 @@ -0,0 +1,128 @@
103350 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
103351 + * All rights reserved.
103352 + *
103353 + * Redistribution and use in source and binary forms, with or without
103354 + * modification, are permitted provided that the following conditions are met:
103355 + * * Redistributions of source code must retain the above copyright
103356 + * notice, this list of conditions and the following disclaimer.
103357 + * * Redistributions in binary form must reproduce the above copyright
103358 + * notice, this list of conditions and the following disclaimer in the
103359 + * documentation and/or other materials provided with the distribution.
103360 + * * Neither the name of Freescale Semiconductor nor the
103361 + * names of its contributors may be used to endorse or promote products
103362 + * derived from this software without specific prior written permission.
103363 + *
103364 + *
103365 + * ALTERNATIVELY, this software may be distributed under the terms of the
103366 + * GNU General Public License ("GPL") as published by the Free Software
103367 + * Foundation, either version 2 of that License or (at your option) any
103368 + * later version.
103369 + *
103370 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103371 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103372 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103373 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103374 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103375 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103376 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103377 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103378 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103379 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103380 + */
103381 +
103382 +/*
103383 + @File lnxwrp_exp_sym.h
103384 + @Description FMan exported routines
103385 +*/
103386 +
103387 +#ifndef __LNXWRP_EXP_SYM_H
103388 +#define __LNXWRP_EXP_SYM_H
103389 +
103390 +#include "fm_port_ext.h"
103391 +#include "fm_pcd_ext.h"
103392 +#include "fm_mac_ext.h"
103393 +
103394 +
103395 +/* FMAN Port exported routines */
103396 +EXPORT_SYMBOL(FM_PORT_Disable);
103397 +EXPORT_SYMBOL(FM_PORT_Enable);
103398 +EXPORT_SYMBOL(FM_PORT_SetPCD);
103399 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
103400 +
103401 +/* Runtime PCD exported routines */
103402 +EXPORT_SYMBOL(FM_PCD_Enable);
103403 +EXPORT_SYMBOL(FM_PCD_Disable);
103404 +EXPORT_SYMBOL(FM_PCD_GetCounter);
103405 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
103406 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
103407 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
103408 +EXPORT_SYMBOL(FM_PCD_SetException);
103409 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
103410 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
103411 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
103412 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
103413 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
103414 +
103415 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
103416 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
103417 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
103418 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
103419 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
103420 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
103421 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
103422 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
103423 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
103424 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
103425 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
103426 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
103427 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
103428 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
103429 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
103430 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
103431 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
103432 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
103433 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
103434 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
103435 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
103436 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
103437 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
103438 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
103439 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
103440 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
103441 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
103442 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
103443 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
103444 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
103445 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
103446 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
103447 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
103448 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
103449 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
103450 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
103451 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
103452 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
103453 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
103454 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
103455 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
103456 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
103457 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
103458 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
103459 +#if (DPAA_VERSION >= 11)
103460 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
103461 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
103462 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
103463 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
103464 +#endif /* DPAA_VERSION >= 11 */
103465 +
103466 +#ifdef FM_CAPWAP_SUPPORT
103467 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
103468 +#endif /* FM_CAPWAP_SUPPORT */
103469 +
103470 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
103471 +
103472 +/* FMAN MAC exported routines */
103473 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
103474 +
103475 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
103476 +
103477 +#endif /* __LNXWRP_EXP_SYM_H */
103478 --- /dev/null
103479 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
103480 @@ -0,0 +1,163 @@
103481 +/*
103482 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103483 + *
103484 + * Redistribution and use in source and binary forms, with or without
103485 + * modification, are permitted provided that the following conditions are met:
103486 + * * Redistributions of source code must retain the above copyright
103487 + * notice, this list of conditions and the following disclaimer.
103488 + * * Redistributions in binary form must reproduce the above copyright
103489 + * notice, this list of conditions and the following disclaimer in the
103490 + * documentation and/or other materials provided with the distribution.
103491 + * * Neither the name of Freescale Semiconductor nor the
103492 + * names of its contributors may be used to endorse or promote products
103493 + * derived from this software without specific prior written permission.
103494 + *
103495 + *
103496 + * ALTERNATIVELY, this software may be distributed under the terms of the
103497 + * GNU General Public License ("GPL") as published by the Free Software
103498 + * Foundation, either version 2 of that License or (at your option) any
103499 + * later version.
103500 + *
103501 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103502 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103503 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103504 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103505 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103506 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103507 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103508 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103509 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103510 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103511 + */
103512 +
103513 +/******************************************************************************
103514 + @File lnxwrp_fm_ext.h
103515 +
103516 + @Description TODO
103517 +*//***************************************************************************/
103518 +
103519 +#ifndef __LNXWRP_FM_EXT_H
103520 +#define __LNXWRP_FM_EXT_H
103521 +
103522 +#include "std_ext.h"
103523 +#include "sys_ext.h"
103524 +#include "fm_ext.h"
103525 +#include "fm_muram_ext.h"
103526 +#include "fm_pcd_ext.h"
103527 +#include "fm_port_ext.h"
103528 +#include "fm_mac_ext.h"
103529 +#include "fm_rtc_ext.h"
103530 +
103531 +
103532 +/**************************************************************************//**
103533 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103534 +
103535 + @Description FM API functions, definitions and enums.
103536 +
103537 + @{
103538 +*//***************************************************************************/
103539 +
103540 +/**************************************************************************//**
103541 + @Group FM_LnxKern_init_grp Initialization Unit
103542 +
103543 + @Description Initialization Unit
103544 +
103545 + Initialization Flow:
103546 + Initialization of the FM Module will be carried out by the Linux
103547 + kernel according to the following sequence:
103548 + a. Calling the initialization routine with no parameters.
103549 + b. The driver will register to the Device-Tree.
103550 + c. The Linux Device-Tree will initiate a call to the driver for
103551 + initialization.
103552 + d. The driver will read the appropriate information from the Device-Tree
103553 + e. [Optional] Calling the advance initialization routines to change
103554 + driver's defaults.
103555 + f. Initialization of the device will be automatically upon using it.
103556 +
103557 + @{
103558 +*//***************************************************************************/
103559 +
103560 +typedef struct t_WrpFmDevSettings
103561 +{
103562 + t_FmParams param;
103563 + t_SysObjectAdvConfigEntry *advConfig;
103564 +} t_WrpFmDevSettings;
103565 +
103566 +typedef struct t_WrpFmPcdDevSettings
103567 +{
103568 + t_FmPcdParams param;
103569 + t_SysObjectAdvConfigEntry *advConfig;
103570 +} t_WrpFmPcdDevSettings;
103571 +
103572 +typedef struct t_WrpFmPortDevSettings
103573 +{
103574 + bool frag_enabled;
103575 + t_FmPortParams param;
103576 + t_SysObjectAdvConfigEntry *advConfig;
103577 +} t_WrpFmPortDevSettings;
103578 +
103579 +typedef struct t_WrpFmMacDevSettings
103580 +{
103581 + t_FmMacParams param;
103582 + t_SysObjectAdvConfigEntry *advConfig;
103583 +} t_WrpFmMacDevSettings;
103584 +
103585 +
103586 +/**************************************************************************//**
103587 + @Function LNXWRP_FM_Init
103588 +
103589 + @Description Initialize the FM linux wrapper.
103590 +
103591 + @Return A handle (descriptor) of the newly created FM Linux wrapper
103592 + structure.
103593 +*//***************************************************************************/
103594 +t_Handle LNXWRP_FM_Init(void);
103595 +
103596 +/**************************************************************************//**
103597 + @Function LNXWRP_FM_Free
103598 +
103599 + @Description Free the FM linux wrapper.
103600 +
103601 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103602 +
103603 + @Return E_OK on success; Error code otherwise.
103604 +*//***************************************************************************/
103605 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
103606 +
103607 +/**************************************************************************//**
103608 + @Function LNXWRP_FM_GetMacHandle
103609 +
103610 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
103611 +
103612 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103613 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
103614 + @Param[in] macId - Index of the mac handle.
103615 +
103616 + @Return A handle of the LLD compressor.
103617 +*//***************************************************************************/
103618 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
103619 +
103620 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
103621 +t_Handle LNXWRP_FM_TEST_Init(void);
103622 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
103623 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
103624 +
103625 +/** @} */ /* end of FM_LnxKern_init_grp group */
103626 +
103627 +
103628 +/**************************************************************************//**
103629 + @Group FM_LnxKern_ctrl_grp Control Unit
103630 +
103631 + @Description Control Unit
103632 +
103633 + TODO
103634 + @{
103635 +*//***************************************************************************/
103636 +
103637 +#include "lnxwrp_fsl_fman.h"
103638 +
103639 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
103640 +/** @} */ /* end of FM_LnxKern_grp group */
103641 +
103642 +
103643 +#endif /* __LNXWRP_FM_EXT_H */
103644 --- /dev/null
103645 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
103646 @@ -0,0 +1,921 @@
103647 +/*
103648 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103649 + *
103650 + * Redistribution and use in source and binary forms, with or without
103651 + * modification, are permitted provided that the following conditions are met:
103652 + * * Redistributions of source code must retain the above copyright
103653 + * notice, this list of conditions and the following disclaimer.
103654 + * * Redistributions in binary form must reproduce the above copyright
103655 + * notice, this list of conditions and the following disclaimer in the
103656 + * documentation and/or other materials provided with the distribution.
103657 + * * Neither the name of Freescale Semiconductor nor the
103658 + * names of its contributors may be used to endorse or promote products
103659 + * derived from this software without specific prior written permission.
103660 + *
103661 + *
103662 + * ALTERNATIVELY, this software may be distributed under the terms of the
103663 + * GNU General Public License ("GPL") as published by the Free Software
103664 + * Foundation, either version 2 of that License or (at your option) any
103665 + * later version.
103666 + *
103667 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103668 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103669 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103670 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103671 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103672 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103673 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103674 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103675 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103676 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103677 + */
103678 +
103679 +/******************************************************************************
103680 + @File lnxwrp_fsl_fman.h
103681 +
103682 + @Description Linux internal kernel API
103683 +*//***************************************************************************/
103684 +
103685 +#ifndef __LNXWRP_FSL_FMAN_H
103686 +#define __LNXWRP_FSL_FMAN_H
103687 +
103688 +#include <linux/types.h>
103689 +#include <linux/device.h> /* struct device */
103690 +#include <linux/fsl_qman.h> /* struct qman_fq */
103691 +#include "dpaa_integration_ext.h"
103692 +#include "fm_port_ext.h"
103693 +#include "fm_mac_ext.h"
103694 +#include "fm_macsec_ext.h"
103695 +#include "fm_rtc_ext.h"
103696 +
103697 +/**************************************************************************//**
103698 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103699 +
103700 + @Description FM API functions, definitions and enums.
103701 +
103702 + @{
103703 +*//***************************************************************************/
103704 +
103705 +/**************************************************************************//**
103706 + @Group FM_LnxKern_ctrl_grp Control Unit
103707 +
103708 + @Description Control Unit
103709 +
103710 + Internal Kernel Control Unit API
103711 + @{
103712 +*//***************************************************************************/
103713 +
103714 +/*****************************************************************************/
103715 +/* Internal Linux kernel routines */
103716 +/*****************************************************************************/
103717 +
103718 +/**************************************************************************//**
103719 + @Description MACSEC Exceptions wrapper
103720 +*//***************************************************************************/
103721 +typedef enum fm_macsec_exception {
103722 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
103723 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
103724 +} fm_macsec_exception;
103725 +
103726 +/**************************************************************************//**
103727 + @Description Unknown sci frame treatment wrapper
103728 +*//***************************************************************************/
103729 +typedef enum fm_macsec_unknown_sci_frame_treatment {
103730 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
103731 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
103732 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
103733 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
103734 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
103735 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
103736 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
103737 +} fm_macsec_unknown_sci_frame_treatment;
103738 +
103739 +/**************************************************************************//**
103740 + @Description Untag frame treatment wrapper
103741 +*//***************************************************************************/
103742 +typedef enum fm_macsec_untag_frame_treatment {
103743 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
103744 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
103745 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
103746 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
103747 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
103748 +} fm_macsec_untag_frame_treatment;
103749 +
103750 +/**************************************************************************//**
103751 +@Description MACSEC SECY Cipher Suite wrapper
103752 +*//***************************************************************************/
103753 +typedef enum fm_macsec_secy_cipher_suite {
103754 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
103755 +#if (DPAA_VERSION >= 11)
103756 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
103757 +#endif /* (DPAA_VERSION >= 11) */
103758 +} fm_macsec_secy_cipher_suite;
103759 +
103760 +/**************************************************************************//**
103761 + @Description MACSEC SECY Exceptions wrapper
103762 +*//***************************************************************************/
103763 +typedef enum fm_macsec_secy_exception {
103764 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
103765 +} fm_macsec_secy_exception;
103766 +
103767 +/**************************************************************************//**
103768 + @Description MACSEC SECY Events wrapper
103769 +*//***************************************************************************/
103770 +typedef enum fm_macsec_secy_event {
103771 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
103772 +} fm_macsec_secy_event;
103773 +
103774 +/**************************************************************************//**
103775 + @Description Valid frame behaviors wrapper
103776 +*//***************************************************************************/
103777 +typedef enum fm_macsec_valid_frame_behavior {
103778 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
103779 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
103780 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
103781 +} fm_macsec_valid_frame_behavior;
103782 +
103783 +/**************************************************************************//**
103784 + @Description SCI insertion modes wrapper
103785 +*//***************************************************************************/
103786 +typedef enum fm_macsec_sci_insertion_mode {
103787 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
103788 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
103789 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
103790 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
103791 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
103792 +} fm_macsec_sci_insertion_mode;
103793 +
103794 +typedef macsecSAKey_t macsec_sa_key_t;
103795 +typedef macsecSCI_t macsec_sci_t;
103796 +typedef macsecAN_t macsec_an_t;
103797 +typedef t_Handle handle_t;
103798 +
103799 +/**************************************************************************//**
103800 + @Function fm_macsec_secy_exception_callback wrapper
103801 + @Description Exceptions user callback routine, will be called upon an
103802 + exception passing the exception identification.
103803 + @Param[in] app_h A handle to an application layer object; This handle
103804 + will be passed by the driver upon calling this callback.
103805 + @Param[in] exception The exception.
103806 +*//***************************************************************************/
103807 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
103808 + fm_macsec_secy_exception exception);
103809 +
103810 +/**************************************************************************//**
103811 + @Function fm_macsec_secy_event_callback wrapper
103812 + @Description Events user callback routine, will be called upon an
103813 + event passing the event identification.
103814 + @Param[in] app_h A handle to an application layer object; This handle
103815 + will be passed by the driver upon calling this callback.
103816 + @Param[in] event The event.
103817 +*//***************************************************************************/
103818 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
103819 + fm_macsec_secy_event event);
103820 +
103821 +/**************************************************************************//**
103822 + @Function fm_macsec_exception_callback wrapper
103823 + @Description Exceptions user callback routine, will be called upon an
103824 + exception passing the exception identification.
103825 + @Param[in] app_h A handle to an application layer object; This handle
103826 + will be passed by the driver upon calling this callback.
103827 + @Param[in] exception The exception.
103828 +*//***************************************************************************/
103829 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
103830 + fm_macsec_exception exception);
103831 +
103832 +/**************************************************************************//**
103833 + @Description MACSEC SecY SC Params wrapper
103834 +*//***************************************************************************/
103835 +struct fm_macsec_secy_sc_params {
103836 + macsec_sci_t sci;
103837 + fm_macsec_secy_cipher_suite cipher_suite;
103838 +};
103839 +
103840 +/**************************************************************************//**
103841 + @Description FM MACSEC SecY config input wrapper
103842 +*//***************************************************************************/
103843 +struct fm_macsec_secy_params {
103844 + handle_t fm_macsec_h;
103845 + struct fm_macsec_secy_sc_params tx_sc_params;
103846 + uint32_t num_receive_channels;
103847 + fm_macsec_secy_exception_callback *exception_f;
103848 + fm_macsec_secy_event_callback *event_f;
103849 + handle_t app_h;
103850 +};
103851 +
103852 +/**************************************************************************//**
103853 + @Description FM MACSEC config input wrapper
103854 +*//***************************************************************************/
103855 +struct fm_macsec_params {
103856 + handle_t fm_h;
103857 + bool guest_mode;
103858 +
103859 + union {
103860 + struct {
103861 + uint8_t fm_mac_id;
103862 + } guest_params;
103863 +
103864 + struct {
103865 + uintptr_t base_addr;
103866 + handle_t fm_mac_h;
103867 + fm_macsec_exception_callback *exception_f;
103868 + handle_t app_h;
103869 + } non_guest_params;
103870 + };
103871 +
103872 +};
103873 +
103874 +/**************************************************************************//**
103875 + @Description FM device opaque structure used for type checking
103876 +*//***************************************************************************/
103877 +struct fm;
103878 +
103879 +/**************************************************************************//**
103880 + @Description FM MAC device opaque structure used for type checking
103881 +*//***************************************************************************/
103882 +struct fm_mac_dev;
103883 +
103884 +/**************************************************************************//**
103885 + @Description FM MACSEC device opaque structure used for type checking
103886 +*//***************************************************************************/
103887 +struct fm_macsec_dev;
103888 +struct fm_macsec_secy_dev;
103889 +
103890 +/**************************************************************************//**
103891 + @Description A structure ..,
103892 +*//***************************************************************************/
103893 +struct fm_port;
103894 +
103895 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
103896 + uint8_t alignment, uint32_t *base_fqid);
103897 +
103898 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
103899 +
103900 +struct fm_port_pcd_param {
103901 + alloc_pcd_fqids cba;
103902 + free_pcd_fqids cbf;
103903 + struct device *dev;
103904 +};
103905 +
103906 +/**************************************************************************//**
103907 + @Description A structure of information about each of the external
103908 + buffer pools used by the port,
103909 +*//***************************************************************************/
103910 +struct fm_port_pool_param {
103911 + uint8_t id; /**< External buffer pool id */
103912 + uint16_t size; /**< External buffer pool buffer size */
103913 +};
103914 +
103915 +/**************************************************************************//**
103916 + @Description structure for additional port parameters
103917 +*//***************************************************************************/
103918 +struct fm_port_params {
103919 + uint32_t errq; /**< Error Queue Id. */
103920 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
103921 + 0 means no Tx conf for processed frames.
103922 + For Rx and OP - default Rx queue. */
103923 + uint8_t num_pools; /**< Number of pools use by this port */
103924 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
103925 + /**< Parameters for each pool */
103926 + uint16_t priv_data_size; /**< Area that user may save for his own
103927 + need (E.g. save the SKB) */
103928 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
103929 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
103930 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
103931 + bool frag_enable; /**< Fragmentation support, for OP only */
103932 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
103933 + if write optimization is used, must be >= 16. */
103934 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
103935 + Note that this field impacts the size of the buffer-prefix
103936 + (i.e. it pushes the data offset); */
103937 +};
103938 +
103939 +/**************************************************************************//**
103940 + @Function fm_bind
103941 +
103942 + @Description Bind to a specific FM device.
103943 +
103944 + @Param[in] fm_dev - the OF handle of the FM device.
103945 +
103946 + @Return A handle of the FM device.
103947 +
103948 + @Cautions Allowed only after the port was created.
103949 +*//***************************************************************************/
103950 +struct fm *fm_bind(struct device *fm_dev);
103951 +
103952 +/**************************************************************************//**
103953 + @Function fm_unbind
103954 +
103955 + @Description Un-bind from a specific FM device.
103956 +
103957 + @Param[in] fm - A handle of the FM device.
103958 +
103959 + @Cautions Allowed only after the port was created.
103960 +*//***************************************************************************/
103961 +void fm_unbind(struct fm *fm);
103962 +
103963 +void *fm_get_handle(struct fm *fm);
103964 +void *fm_get_rtc_handle(struct fm *fm);
103965 +struct resource *fm_get_mem_region(struct fm *fm);
103966 +
103967 +/**************************************************************************//**
103968 + @Function fm_port_bind
103969 +
103970 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
103971 +
103972 + @Param[in] fm_port_dev - the OF handle of the FM port device.
103973 +
103974 + @Return A handle of the FM port device.
103975 +
103976 + @Cautions Allowed only after the port was created.
103977 +*//***************************************************************************/
103978 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
103979 +
103980 +/**************************************************************************//**
103981 + @Function fm_port_unbind
103982 +
103983 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
103984 +
103985 + @Param[in] port - A handle of the FM port device.
103986 +
103987 + @Cautions Allowed only after the port was created.
103988 +*//***************************************************************************/
103989 +void fm_port_unbind(struct fm_port *port);
103990 +
103991 +/**************************************************************************//**
103992 + @Function fm_set_rx_port_params
103993 +
103994 + @Description Configure parameters for a specific Rx FM-port device.
103995 +
103996 + @Param[in] port - A handle of the FM port device.
103997 + @Param[in] params - Rx port parameters
103998 +
103999 + @Cautions Allowed only after the port is binded.
104000 +*//***************************************************************************/
104001 +void fm_set_rx_port_params(struct fm_port *port,
104002 + struct fm_port_params *params);
104003 +
104004 +/**************************************************************************//**
104005 + @Function fm_port_pcd_bind
104006 +
104007 + @Description Bind as a listener on a port PCD.
104008 +
104009 + @Param[in] port - A handle of the FM port device.
104010 + @Param[in] params - PCD port parameters
104011 +
104012 + @Cautions Allowed only after the port is binded.
104013 +*//***************************************************************************/
104014 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
104015 +
104016 +/**************************************************************************//**
104017 + @Function fm_port_get_buff_layout_ext_params
104018 +
104019 + @Description Get data_align and manip_extra_space from the device tree
104020 + chosen node if applied.
104021 + This function will only update these two parameters.
104022 + When this port has no such parameters in the device tree
104023 + values will be set to 0.
104024 +
104025 + @Param[in] port - A handle of the FM port device.
104026 + @Param[in] params - PCD port parameters
104027 +
104028 + @Cautions Allowed only after the port is binded.
104029 +*//***************************************************************************/
104030 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
104031 +
104032 +/**************************************************************************//**
104033 + @Function fm_get_tx_port_channel
104034 +
104035 + @Description Get qman-channel number for this Tx port.
104036 +
104037 + @Param[in] port - A handle of the FM port device.
104038 +
104039 + @Return qman-channel number for this Tx port.
104040 +
104041 + @Cautions Allowed only after the port is binded.
104042 +*//***************************************************************************/
104043 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
104044 +
104045 +/**************************************************************************//**
104046 + @Function fm_set_tx_port_params
104047 +
104048 + @Description Configure parameters for a specific Tx FM-port device
104049 +
104050 + @Param[in] port - A handle of the FM port device.
104051 + @Param[in] params - Tx port parameters
104052 +
104053 + @Cautions Allowed only after the port is binded.
104054 +*//***************************************************************************/
104055 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
104056 +
104057 +
104058 +/**************************************************************************//**
104059 + @Function fm_mac_set_handle
104060 +
104061 + @Description Set mac handle
104062 +
104063 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
104064 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
104065 + @Param[in] mac_id - MAC id.
104066 +*//***************************************************************************/
104067 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
104068 + int mac_id);
104069 +
104070 +/**************************************************************************//**
104071 + @Function fm_port_enable
104072 +
104073 + @Description Enable specific FM-port device (may be Rx or Tx port).
104074 +
104075 + @Param[in] port - A handle of the FM port device.
104076 +
104077 + @Cautions Allowed only after the port is initialized.
104078 +*//***************************************************************************/
104079 +int fm_port_enable(struct fm_port *port);
104080 +
104081 +/**************************************************************************//**
104082 + @Function fm_port_disable
104083 +
104084 + @Description Disable specific FM-port device (may be Rx or Tx port).
104085 +
104086 + @Param[in] port - A handle of the FM port device.
104087 +
104088 + @Cautions Allowed only after the port is initialized.
104089 +*//***************************************************************************/
104090 +int fm_port_disable(struct fm_port *port);
104091 +
104092 +void *fm_port_get_handle(const struct fm_port *port);
104093 +
104094 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
104095 + const void *data);
104096 +
104097 +/**************************************************************************//**
104098 + @Function fm_port_get_base_address
104099 +
104100 + @Description Get base address of this port. Useful for accessing
104101 + port-specific registers (i.e., not common ones).
104102 +
104103 + @Param[in] port - A handle of the FM port device.
104104 +
104105 + @Param[out] base_addr - The port's base addr (virtual address).
104106 +*//***************************************************************************/
104107 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
104108 +
104109 +/**************************************************************************//**
104110 + @Function fm_mutex_lock
104111 +
104112 + @Description Lock function required before any FMD/LLD call.
104113 +*//***************************************************************************/
104114 +void fm_mutex_lock(void);
104115 +
104116 +/**************************************************************************//**
104117 + @Function fm_mutex_unlock
104118 +
104119 + @Description Unlock function required after any FMD/LLD call.
104120 +*//***************************************************************************/
104121 +void fm_mutex_unlock(void);
104122 +
104123 +/**************************************************************************//**
104124 + @Function fm_get_max_frm
104125 +
104126 + @Description Get the maximum frame size
104127 +*//***************************************************************************/
104128 +int fm_get_max_frm(void);
104129 +
104130 +/**************************************************************************//**
104131 + @Function fm_get_rx_extra_headroom
104132 +
104133 + @Description Get the extra headroom size
104134 +*//***************************************************************************/
104135 +int fm_get_rx_extra_headroom(void);
104136 +
104137 +/**************************************************************************//**
104138 +@Function fm_port_set_rate_limit
104139 +
104140 +@Description Configure Shaper parameter on FM-port device (Tx port).
104141 +
104142 +@Param[in] port - A handle of the FM port device.
104143 +@Param[in] max_burst_size - Value of maximum burst size allowed.
104144 +@Param[in] rate_limit - The required rate value.
104145 +
104146 +@Cautions Allowed only after the port is initialized.
104147 +*//***************************************************************************/
104148 +int fm_port_set_rate_limit(struct fm_port *port,
104149 + uint16_t max_burst_size,
104150 + uint32_t rate_limit);
104151 +/**************************************************************************//**
104152 +@Function fm_port_set_rate_limit
104153 +
104154 +@Description Delete Shaper configuration on FM-port device (Tx port).
104155 +
104156 +@Param[in] port - A handle of the FM port device.
104157 +
104158 +@Cautions Allowed only after the port is initialized.
104159 +*//***************************************************************************/
104160 +int fm_port_del_rate_limit(struct fm_port *port);
104161 +
104162 +struct auto_res_tables_sizes
104163 +{
104164 + uint16_t max_num_of_arp_entries;
104165 + uint16_t max_num_of_echo_ipv4_entries;
104166 + uint16_t max_num_of_ndp_entries;
104167 + uint16_t max_num_of_echo_ipv6_entries;
104168 + uint16_t max_num_of_snmp_ipv4_entries;
104169 + uint16_t max_num_of_snmp_ipv6_entries;
104170 + uint16_t max_num_of_snmp_oid_entries;
104171 + uint16_t max_num_of_snmp_char; /* total amount of character needed
104172 + for the snmp table */
104173 + uint16_t max_num_of_ip_prot_filtering;
104174 + uint16_t max_num_of_tcp_port_filtering;
104175 + uint16_t max_num_of_udp_port_filtering;
104176 +};
104177 +/* ARP */
104178 +struct auto_res_arp_entry
104179 +{
104180 + uint32_t ip_address;
104181 + uint8_t mac[6];
104182 + bool is_vlan;
104183 + uint16_t vid;
104184 +};
104185 +struct auto_res_arp_info
104186 +{
104187 + uint8_t table_size;
104188 + struct auto_res_arp_entry *auto_res_table;
104189 + bool enable_conflict_detection; /* when TRUE
104190 + Conflict Detection will be checked and wake the host if
104191 + needed */
104192 +};
104193 +
104194 +/* NDP */
104195 +struct auto_res_ndp_entry
104196 +{
104197 + uint32_t ip_address[4];
104198 + uint8_t mac[6];
104199 + bool is_vlan;
104200 + uint16_t vid;
104201 +};
104202 +struct auto_res_ndp_info
104203 +{
104204 + uint32_t multicast_group;
104205 + uint8_t table_size_assigned;
104206 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
104207 + refer to solicitation IP addresses. Note that all IP adresses
104208 + must be from the same multicast group. This will be checked and
104209 + if not operation will fail. */
104210 + uint8_t table_size_tmp;
104211 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
104212 + refer to temp IP addresses. Note that all temp IP adresses must
104213 + be from the same multicast group. This will be checked and if
104214 + not operation will fail. */
104215 +
104216 + bool enable_conflict_detection; /* when TRUE
104217 + Conflict Detection will be checked and wake the host if
104218 + needed */
104219 +};
104220 +
104221 +/* ICMP ECHO */
104222 +struct auto_res_echo_ipv4_info
104223 +{
104224 + uint8_t table_size;
104225 + struct auto_res_arp_entry *auto_res_table;
104226 +};
104227 +
104228 +struct auto_res_echo_ipv6_info
104229 +{
104230 + uint8_t table_size;
104231 + struct auto_res_ndp_entry *auto_res_table;
104232 +};
104233 +
104234 +/* SNMP */
104235 +struct auto_res_snmp_entry
104236 +{
104237 + uint16_t oidSize;
104238 + uint8_t *oidVal; /* only the oid string */
104239 + uint16_t resSize;
104240 + uint8_t *resVal; /* resVal will be the entire reply,
104241 + i.e. "Type|Length|Value" */
104242 +};
104243 +
104244 +/**************************************************************************//**
104245 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
104246 + Refer to the FMan Controller spec for more details.
104247 +*//***************************************************************************/
104248 +struct auto_res_snmp_ipv4addr_tbl_entry
104249 +{
104250 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
104251 + bool is_vlan;
104252 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104253 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104254 +};
104255 +
104256 +/**************************************************************************//**
104257 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
104258 + Refer to the FMan Controller spec for more details.
104259 +*//***************************************************************************/
104260 +struct auto_res_snmp_ipv6addr_tbl_entry
104261 +{
104262 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
104263 + bool isVlan;
104264 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104265 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104266 +};
104267 +
104268 +struct auto_res_snmp_info
104269 +{
104270 + uint16_t control; /**< Control bits [0-15]. */
104271 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
104272 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
104273 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
104274 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
104275 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
104276 + char *community_read_write_string;
104277 + char *community_read_only_string;
104278 + struct auto_res_snmp_entry *oid_table;
104279 + uint32_t oid_table_size;
104280 + uint32_t *statistics;
104281 +};
104282 +
104283 +/* Filtering */
104284 +struct auto_res_port_filtering_entry
104285 +{
104286 + uint16_t src_port;
104287 + uint16_t dst_port;
104288 + uint16_t src_port_mask;
104289 + uint16_t dst_port_mask;
104290 +};
104291 +struct auto_res_filtering_info
104292 +{
104293 + /* IP protocol filtering parameters */
104294 + uint8_t ip_prot_table_size;
104295 + uint8_t *ip_prot_table_ptr;
104296 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
104297 + cause the packet to be droped, hit will pass the packet to
104298 + UDP/TCP filters if needed and if not to the classification
104299 + tree. If the classification tree will pass the packet to a
104300 + queue it will cause a wake interupt. When FALSE it the other
104301 + way around. */
104302 + /* UDP port filtering parameters */
104303 + uint8_t udp_ports_table_size;
104304 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
104305 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
104306 + cause the packet to be droped, hit will pass the packet to
104307 + classification tree. If the classification tree will pass the
104308 + packet to a queue it will cause a wake interupt. When FALSE it
104309 + the other way around. */
104310 + /* TCP port filtering parameters */
104311 + uint16_t tcp_flags_mask;
104312 + uint8_t tcp_ports_table_size;
104313 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
104314 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
104315 + cause the packet to be droped, hit will pass the packet to
104316 + classification tree. If the classification tree will pass the
104317 + packet to a queue it will cause a wake interupt. When FALSE it
104318 + the other way around. */
104319 +};
104320 +
104321 +struct auto_res_port_params
104322 +{
104323 + t_Handle h_FmPortTx;
104324 + struct auto_res_arp_info *p_auto_res_arp_info;
104325 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
104326 + struct auto_res_ndp_info *p_auto_res_ndp_info;
104327 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
104328 + struct auto_res_snmp_info *p_auto_res_snmp_info;
104329 + struct auto_res_filtering_info *p_auto_res_filtering_info;
104330 +};
104331 +
104332 +struct auto_res_port_stats
104333 +{
104334 + uint32_t arp_ar_cnt;
104335 + uint32_t echo_icmpv4_ar_cnt;
104336 + uint32_t ndp_ar_cnt;
104337 + uint32_t echo_icmpv6_ar_cnt;
104338 +};
104339 +
104340 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
104341 + struct auto_res_tables_sizes *params);
104342 +
104343 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
104344 + struct auto_res_port_params *params);
104345 +
104346 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
104347 + struct fm_port *port_tx);
104348 +
104349 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
104350 +
104351 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
104352 + struct fm_port *port);
104353 +
104354 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
104355 + *stats);
104356 +
104357 +int fm_port_resume(struct fm_port *port);
104358 +
104359 +int fm_port_suspend(struct fm_port *port);
104360 +
104361 +#ifdef CONFIG_FMAN_PFC
104362 +/**************************************************************************//**
104363 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
104364 +
104365 +@Description Associate a QMan Work Queue with a PFC priority on this
104366 + FM-port device (Tx port).
104367 +
104368 +@Param[in] port - A handle of the FM port device.
104369 +
104370 +@Param[in] prio - The PFC priority.
104371 +
104372 +@Param[in] wq - The Work Queue associated with the PFC priority.
104373 +
104374 +@Cautions Allowed only after the port is initialized.
104375 +*//***************************************************************************/
104376 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
104377 + uint8_t prio, uint8_t wq);
104378 +#endif
104379 +
104380 +/**************************************************************************//**
104381 +@Function fm_mac_set_exception
104382 +
104383 +@Description Set MAC exception state.
104384 +
104385 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
104386 +@Param[in] exception - FM MAC exception type.
104387 +@Param[in] enable - new state.
104388 +
104389 +*//***************************************************************************/
104390 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
104391 + e_FmMacExceptions exception, bool enable);
104392 +
104393 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
104394 +
104395 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
104396 +
104397 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
104398 + int len);
104399 +
104400 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
104401 +
104402 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
104403 +
104404 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
104405 +
104406 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
104407 +
104408 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
104409 +
104410 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
104411 +
104412 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
104413 +
104414 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
104415 +
104416 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
104417 + bool enable);
104418 +
104419 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104420 + t_EnetAddr *mac_addr);
104421 +
104422 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104423 + t_EnetAddr *mac_addr);
104424 +
104425 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
104426 + uint8_t *addr);
104427 +
104428 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
104429 + bool link, int speed, bool duplex);
104430 +
104431 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104432 +
104433 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104434 +
104435 +int fm_mac_set_rx_pause_frames(
104436 + struct fm_mac_dev *fm_mac_dev, bool en);
104437 +
104438 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
104439 + bool en);
104440 +
104441 +int fm_rtc_enable(struct fm *fm_dev);
104442 +
104443 +int fm_rtc_disable(struct fm *fm_dev);
104444 +
104445 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
104446 +
104447 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
104448 +
104449 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
104450 +
104451 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
104452 +
104453 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
104454 + uint64_t time);
104455 +
104456 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
104457 + uint64_t fiper);
104458 +
104459 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
104460 + bool en);
104461 +
104462 +/**************************************************************************//**
104463 +@Function fm_macsec_set_exception
104464 +
104465 +@Description Set MACSEC exception state.
104466 +
104467 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
104468 +@Param[in] exception - FM MACSEC exception type.
104469 +@Param[in] enable - new state.
104470 +
104471 +*//***************************************************************************/
104472 +
104473 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
104474 + fm_macsec_exception exception, bool enable);
104475 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
104476 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
104477 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
104478 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
104479 + *fm_macsec_dev,
104480 + fm_macsec_unknown_sci_frame_treatment treat_mode);
104481 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104482 + bool deliver_uncontrolled);
104483 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104484 + bool discard_uncontrolled);
104485 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104486 + fm_macsec_untag_frame_treatment treat_mode);
104487 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
104488 + uint32_t pnExhThr);
104489 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
104490 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
104491 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
104492 + fm_macsec_exception exception, bool enable);
104493 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
104494 + int *macsec_revision);
104495 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
104496 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
104497 +
104498 +
104499 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104500 + fm_macsec_secy_exception exception,
104501 + bool enable);
104502 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104503 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
104504 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104505 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104506 + fm_macsec_sci_insertion_mode sci_insertion_mode);
104507 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104508 + bool protect_frames);
104509 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104510 + bool replay_protect, uint32_t replay_window);
104511 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104512 + fm_macsec_valid_frame_behavior validate_frames);
104513 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104514 + bool confidentiality_enable,
104515 + uint32_t confidentiality_offset);
104516 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104517 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104518 + fm_macsec_secy_event event,
104519 + bool enable);
104520 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104521 + struct fm_macsec_secy_sc_params *params);
104522 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104523 + struct rx_sc_dev *sc);
104524 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104525 + struct rx_sc_dev *sc, macsec_an_t an,
104526 + uint32_t lowest_pn, macsec_sa_key_t key);
104527 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104528 + struct rx_sc_dev *sc, macsec_an_t an);
104529 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104530 + struct rx_sc_dev *sc,
104531 + macsec_an_t an);
104532 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104533 + struct rx_sc_dev *sc,
104534 + macsec_an_t an);
104535 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104536 + struct rx_sc_dev *sc,
104537 + macsec_an_t an, uint32_t updt_next_pn);
104538 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104539 + struct rx_sc_dev *sc,
104540 + macsec_an_t an, uint32_t updt_lowest_pn);
104541 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104542 + struct rx_sc_dev *sc,
104543 + macsec_an_t an, macsec_sa_key_t key);
104544 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104545 + macsec_an_t an, macsec_sa_key_t key);
104546 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104547 + macsec_an_t an);
104548 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104549 + macsec_an_t next_active_an,
104550 + macsec_sa_key_t key);
104551 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104552 + macsec_an_t an);
104553 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104554 + macsec_an_t *p_an);
104555 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104556 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
104557 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104558 + uint32_t *sc_phys_id);
104559 +
104560 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104561 +/** @} */ /* end of FM_LnxKern_grp group */
104562 +
104563 +/* default values for initializing PTP 1588 timer clock */
104564 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
104565 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
104566 +
104567 +#endif /* __LNXWRP_FSL_FMAN_H */
104568 --- /dev/null
104569 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
104570 @@ -0,0 +1,50 @@
104571 +/*
104572 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104573 + *
104574 + * Redistribution and use in source and binary forms, with or without
104575 + * modification, are permitted provided that the following conditions are met:
104576 + * * Redistributions of source code must retain the above copyright
104577 + * notice, this list of conditions and the following disclaimer.
104578 + * * Redistributions in binary form must reproduce the above copyright
104579 + * notice, this list of conditions and the following disclaimer in the
104580 + * documentation and/or other materials provided with the distribution.
104581 + * * Neither the name of Freescale Semiconductor nor the
104582 + * names of its contributors may be used to endorse or promote products
104583 + * derived from this software without specific prior written permission.
104584 + *
104585 + *
104586 + * ALTERNATIVELY, this software may be distributed under the terms of the
104587 + * GNU General Public License ("GPL") as published by the Free Software
104588 + * Foundation, either version 2 of that License or (at your option) any
104589 + * later version.
104590 + *
104591 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104592 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104593 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104594 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104595 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104596 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104597 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104598 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104599 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104600 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104601 + */
104602 +
104603 +#ifndef __XX_H
104604 +#define __XX_H
104605 +
104606 +#include "xx_ext.h"
104607 +
104608 +void * xx_Malloc(uint32_t n);
104609 +void xx_Free(void *p);
104610 +
104611 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
104612 +void xx_FreeSmart(void *p);
104613 +
104614 +/* never used: */
104615 +#define GetDeviceName(irq) ((char *)NULL)
104616 +
104617 +int GetDeviceIrqNum(int irq);
104618 +
104619 +
104620 +#endif /* __XX_H */
104621 --- /dev/null
104622 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
104623 @@ -0,0 +1,10 @@
104624 +#
104625 +# Makefile for the Freescale Ethernet controllers
104626 +#
104627 +ccflags-y += -DVERSION=\"\"
104628 +#
104629 +#Include netcomm SW specific definitions
104630 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104631 +#
104632 +
104633 +obj-y += sys_io.o
104634 --- /dev/null
104635 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
104636 @@ -0,0 +1,171 @@
104637 +/*
104638 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104639 + *
104640 + * Redistribution and use in source and binary forms, with or without
104641 + * modification, are permitted provided that the following conditions are met:
104642 + * * Redistributions of source code must retain the above copyright
104643 + * notice, this list of conditions and the following disclaimer.
104644 + * * Redistributions in binary form must reproduce the above copyright
104645 + * notice, this list of conditions and the following disclaimer in the
104646 + * documentation and/or other materials provided with the distribution.
104647 + * * Neither the name of Freescale Semiconductor nor the
104648 + * names of its contributors may be used to endorse or promote products
104649 + * derived from this software without specific prior written permission.
104650 + *
104651 + *
104652 + * ALTERNATIVELY, this software may be distributed under the terms of the
104653 + * GNU General Public License ("GPL") as published by the Free Software
104654 + * Foundation, either version 2 of that License or (at your option) any
104655 + * later version.
104656 + *
104657 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104658 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104659 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104660 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104661 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104662 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104663 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104664 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104665 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104666 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104667 + */
104668 +
104669 +#include <linux/version.h>
104670 +
104671 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
104672 +#define MODVERSIONS
104673 +#endif
104674 +#ifdef MODVERSIONS
104675 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
104676 +#include <linux/modversions.h>
104677 +#else
104678 +#include <config/modversions.h>
104679 +#endif /* LINUX_VERSION_CODE */
104680 +#endif /* MODVERSIONS */
104681 +
104682 +#include <linux/module.h>
104683 +#include <linux/kernel.h>
104684 +
104685 +#include <asm/io.h>
104686 +
104687 +#include "std_ext.h"
104688 +#include "error_ext.h"
104689 +#include "string_ext.h"
104690 +#include "list_ext.h"
104691 +#include "sys_io_ext.h"
104692 +
104693 +
104694 +#define __ERR_MODULE__ MODULE_UNKNOWN
104695 +
104696 +
104697 +typedef struct {
104698 + uint64_t virtAddr;
104699 + uint64_t physAddr;
104700 + uint32_t size;
104701 + t_List node;
104702 +} t_IoMap;
104703 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
104704 +
104705 +LIST(mapsList);
104706 +
104707 +
104708 +static void EnqueueIoMap(t_IoMap *p_IoMap)
104709 +{
104710 + uint32_t intFlags;
104711 +
104712 + intFlags = XX_DisableAllIntr();
104713 + LIST_AddToTail(&p_IoMap->node, &mapsList);
104714 + XX_RestoreAllIntr(intFlags);
104715 +}
104716 +
104717 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
104718 +{
104719 + t_IoMap *p_IoMap;
104720 + t_List *p_Pos;
104721 +
104722 + LIST_FOR_EACH(p_Pos, &mapsList)
104723 + {
104724 + p_IoMap = IOMAP_OBJECT(p_Pos);
104725 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
104726 + return p_IoMap;
104727 + }
104728 +
104729 + return NULL;
104730 +}
104731 +
104732 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
104733 +{
104734 + t_IoMap *p_IoMap;
104735 + t_List *p_Pos;
104736 +
104737 + LIST_FOR_EACH(p_Pos, &mapsList)
104738 + {
104739 + p_IoMap = IOMAP_OBJECT(p_Pos);
104740 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
104741 + return p_IoMap;
104742 + }
104743 +
104744 + return NULL;
104745 +}
104746 +
104747 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
104748 +{
104749 + t_IoMap *p_IoMap;
104750 +
104751 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
104752 + if (!p_IoMap)
104753 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
104754 + memset(p_IoMap, 0, sizeof(t_IoMap));
104755 +
104756 + p_IoMap->virtAddr = virtAddr;
104757 + p_IoMap->physAddr = physAddr;
104758 + p_IoMap->size = size;
104759 +
104760 + INIT_LIST(&p_IoMap->node);
104761 + EnqueueIoMap(p_IoMap);
104762 +
104763 + return E_OK;
104764 +}
104765 +
104766 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
104767 +{
104768 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
104769 + if (!p_IoMap)
104770 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
104771 +
104772 + LIST_Del(&p_IoMap->node);
104773 + XX_Free(p_IoMap);
104774 +
104775 + return E_OK;
104776 +}
104777 +
104778 +uint64_t SYS_PhysToVirt(uint64_t addr)
104779 +{
104780 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
104781 + if (p_IoMap)
104782 + {
104783 + /* This is optimization - put the latest in the list-head - like a cache */
104784 + if (mapsList.p_Next != &p_IoMap->node)
104785 + {
104786 + uint32_t intFlags = XX_DisableAllIntr();
104787 + LIST_DelAndInit(&p_IoMap->node);
104788 + LIST_Add(&p_IoMap->node, &mapsList);
104789 + XX_RestoreAllIntr(intFlags);
104790 + }
104791 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
104792 + }
104793 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
104794 +}
104795 +
104796 +uint64_t SYS_VirtToPhys(uint64_t addr)
104797 +{
104798 + t_IoMap *p_IoMap;
104799 +
104800 + if (addr == 0)
104801 + return 0;
104802 +
104803 + p_IoMap = FindIoMapByVirtAddr(addr);
104804 + if (p_IoMap)
104805 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
104806 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
104807 +}
104808 --- /dev/null
104809 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
104810 @@ -0,0 +1,19 @@
104811 +#
104812 +# Makefile for the Freescale Ethernet controllers
104813 +#
104814 +ccflags-y += -DVERSION=\"\"
104815 +#
104816 +#Include netcomm SW specific definitions
104817 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104818 +
104819 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
104820 +
104821 +ccflags-y += -I$(NCSW_FM_INC)
104822 +ccflags-y += -I$(NET_DPA)
104823 +
104824 +obj-y += fsl-ncsw-PFM.o
104825 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
104826 +
104827 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
104828 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
104829 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
104830 --- /dev/null
104831 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
104832 @@ -0,0 +1,1665 @@
104833 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
104834 + * All rights reserved.
104835 + *
104836 + * Redistribution and use in source and binary forms, with or without
104837 + * modification, are permitted provided that the following conditions are met:
104838 + * * Redistributions of source code must retain the above copyright
104839 + * notice, this list of conditions and the following disclaimer.
104840 + * * Redistributions in binary form must reproduce the above copyright
104841 + * notice, this list of conditions and the following disclaimer in the
104842 + * documentation and/or other materials provided with the distribution.
104843 + * * Neither the name of Freescale Semiconductor nor the
104844 + * names of its contributors may be used to endorse or promote products
104845 + * derived from this software without specific prior written permission.
104846 + *
104847 + *
104848 + * ALTERNATIVELY, this software may be distributed under the terms of the
104849 + * GNU General Public License ("GPL") as published by the Free Software
104850 + * Foundation, either version 2 of that License or (at your option) any
104851 + * later version.
104852 + *
104853 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104854 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104855 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104856 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104857 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104858 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104859 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104860 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104861 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104862 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104863 + */
104864 +
104865 +/*
104866 + @File fman_test.c
104867 + @Authors Pistirica Sorin Andrei
104868 + @Description FM Linux test environment
104869 +*/
104870 +
104871 +#include <linux/kernel.h>
104872 +#include <linux/module.h>
104873 +#include <linux/fs.h>
104874 +#include <linux/cdev.h>
104875 +#include <linux/device.h>
104876 +#include <linux/io.h>
104877 +#include <linux/ioport.h>
104878 +#include <linux/of_platform.h>
104879 +#include <linux/ip.h>
104880 +#include <linux/compat.h>
104881 +#include <linux/uaccess.h>
104882 +#include <linux/errno.h>
104883 +#include <linux/netdevice.h>
104884 +#include <linux/spinlock.h>
104885 +#include <linux/types.h>
104886 +#include <linux/fsl_qman.h>
104887 +#include <linux/fsl_bman.h>
104888 +
104889 +/* private headers */
104890 +#include "fm_ext.h"
104891 +#include "lnxwrp_fsl_fman.h"
104892 +#include "fm_port_ext.h"
104893 +#if (DPAA_VERSION == 11)
104894 +#include "../../Peripherals/FM/MAC/memac.h"
104895 +#endif
104896 +#include "fm_test_ioctls.h"
104897 +#include "fsl_fman_test.h"
104898 +
104899 +#include "dpaa_eth.h"
104900 +#include "dpaa_eth_common.h"
104901 +
104902 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
104903 +
104904 +struct fmt_frame_s {
104905 + ioc_fmt_buff_desc_t buff;
104906 + struct list_head list;
104907 +};
104908 +
104909 +struct fmt_fqs_s {
104910 + struct qman_fq fq_base;
104911 + bool init;
104912 + struct fmt_port_s *fmt_port_priv;
104913 +};
104914 +
104915 +struct fmt_port_pcd_s {
104916 + int num_queues;
104917 + struct fmt_fqs_s *fmt_pcd_fqs;
104918 + uint32_t fqid_base;
104919 +};
104920 +
104921 +/* char dev structure: fm test port */
104922 +struct fmt_port_s {
104923 + bool valid;
104924 + uint8_t id;
104925 + ioc_fmt_port_type port_type;
104926 + ioc_diag_mode diag;
104927 + bool compat_test_type;
104928 +
104929 + /* fm ports */
104930 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
104931 + * p_tx_port == p_rx_port */
104932 + /* t_LnxWrpFmPortDev */
104933 + struct fm_port *p_tx_port;
104934 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
104935 + void *p_tx_fm_port_dev;
104936 + /* t_LnxWrpFmPortDev */
104937 + struct fm_port *p_rx_port;
104938 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
104939 + void *p_rx_fm_port_dev;
104940 +
104941 + void *p_mac_dev;
104942 + uint64_t fm_phys_base_addr;
104943 +
104944 + /* read/write queue manipulation */
104945 + spinlock_t rx_q_lock;
104946 + struct list_head rx_q;
104947 +
104948 + /* tx queuee for injecting traffic */
104949 + int num_of_tx_fqs;
104950 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
104951 +
104952 + /* pcd private queues manipulation */
104953 + struct fmt_port_pcd_s fmt_port_pcd;
104954 +
104955 + /* debugging stuff */
104956 +
104957 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
104958 + atomic_t enqueue_to_qman_frm;
104959 + atomic_t enqueue_to_rxq;
104960 + atomic_t dequeue_from_rxq;
104961 + atomic_t not_enqueue_to_rxq_wrong_frm;
104962 +#endif
104963 +
104964 +};
104965 +
104966 +/* The devices. */
104967 +struct fmt_s {
104968 + int major;
104969 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
104970 + struct class *fmt_class;
104971 +};
104972 +
104973 +/* fm test structure */
104974 +static struct fmt_s fm_test;
104975 +
104976 +#if (DPAA_VERSION == 11)
104977 +struct mac_priv_s {
104978 + t_Handle mac;
104979 +};
104980 +#endif
104981 +
104982 +#define DTSEC_BASE_ADDR 0x000e0000
104983 +#define DTSEC_MEM_RANGE 0x00002000
104984 +#define MAC_1G_MACCFG1 0x00000100
104985 +#define MAC_1G_LOOP_MASK 0x00000100
104986 +static int set_1gmac_loopback(
104987 + struct fmt_port_s *fmt_port,
104988 + bool en)
104989 +{
104990 +#if (DPAA_VERSION <= 10)
104991 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
104992 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
104993 + phys_addr_t maccfg1_hw;
104994 + void *maccfg1_map;
104995 + uint32_t maccfg1_val;
104996 +
104997 + /* compute the maccfg1 register address */
104998 + maccfg1_hw = fmt_port->fm_phys_base_addr +
104999 + (phys_addr_t)(DTSEC_BASE_ADDR +
105000 + dtsec_idx_off +
105001 + MAC_1G_MACCFG1);
105002 +
105003 + /* map register */
105004 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
105005 +
105006 + /* set register */
105007 + maccfg1_val = in_be32(maccfg1_map);
105008 + if (en)
105009 + maccfg1_val |= MAC_1G_LOOP_MASK;
105010 + else
105011 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
105012 + out_be32(maccfg1_map, maccfg1_val);
105013 +
105014 + /* unmap register */
105015 + iounmap(maccfg1_map);
105016 +#else
105017 + struct mac_device *mac_dev;
105018 + struct mac_priv_s *priv;
105019 + t_Memac *p_memac;
105020 +
105021 + if (!fmt_port)
105022 + return -EINVAL;
105023 +
105024 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
105025 +
105026 + if (!mac_dev)
105027 + return -EINVAL;
105028 +
105029 + priv = macdev_priv(mac_dev);
105030 +
105031 + if (!priv)
105032 + return -EINVAL;
105033 +
105034 + p_memac = priv->mac;
105035 +
105036 + if (!p_memac)
105037 + return -EINVAL;
105038 +
105039 + memac_set_loopback(p_memac->p_MemMap, en);
105040 +#endif
105041 + return 0;
105042 +}
105043 +
105044 +/* TODO: re-write this function */
105045 +static int set_10gmac_int_loopback(
105046 + struct fmt_port_s *fmt_port,
105047 + bool en)
105048 +{
105049 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
105050 +#define FM_10GMAC0_OFFSET 0x000f0000
105051 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
105052 +#define CMD_CFG_LOOPBACK_EN 0x00000400
105053 +
105054 + uint64_t base_addr, reg_addr;
105055 + uint32_t tmp_val;
105056 +
105057 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
105058 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
105059 +
105060 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
105061 +
105062 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
105063 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
105064 + if (en)
105065 + tmp_val |= CMD_CFG_LOOPBACK_EN;
105066 + else
105067 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
105068 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
105069 +
105070 + iounmap(UINT_TO_PTR(base_addr));
105071 +
105072 + return 0;
105073 +#else
105074 + _fmt_err("TGEC don't have internal-loopback.\n");
105075 + return -EPERM;
105076 +#endif
105077 +}
105078 +
105079 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
105080 +{
105081 + int _err = 0;
105082 +
105083 + switch (fmt_port->port_type) {
105084 +
105085 + case e_IOC_FMT_PORT_T_RXTX:
105086 + /* 1G port */
105087 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
105088 + _err = set_1gmac_loopback(fmt_port, en);
105089 + /* 10g port */
105090 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
105091 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
105092 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
105093 +
105094 + _err = set_10gmac_int_loopback(fmt_port, en);
105095 + } else
105096 + _err = -EINVAL;
105097 + break;
105098 + /* op port does not have MAC (loopback mode) */
105099 + case e_IOC_FMT_PORT_T_OP:
105100 +
105101 + _err = 0;
105102 + break;
105103 + default:
105104 +
105105 + _err = -EPERM;
105106 + break;
105107 + }
105108 +
105109 + return _err;
105110 +}
105111 +
105112 +static void enqueue_fmt_frame(
105113 + struct fmt_port_s *fmt_port,
105114 + struct fmt_frame_s *p_fmt_frame)
105115 +{
105116 + spinlock_t *rx_q_lock = NULL;
105117 +
105118 + rx_q_lock = &fmt_port->rx_q_lock;
105119 +
105120 + spin_lock(rx_q_lock);
105121 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
105122 + spin_unlock(rx_q_lock);
105123 +
105124 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105125 + atomic_inc(&fmt_port->enqueue_to_rxq);
105126 +#endif
105127 +}
105128 +
105129 +static struct fmt_frame_s *dequeue_fmt_frame(
105130 + struct fmt_port_s *fmt_port)
105131 +{
105132 + struct fmt_frame_s *p_fmt_frame = NULL;
105133 + spinlock_t *rx_q_lock = NULL;
105134 +
105135 + rx_q_lock = &fmt_port->rx_q_lock;
105136 +
105137 + spin_lock(rx_q_lock);
105138 +
105139 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
105140 +
105141 + if (!list_empty(&fmt_port->rx_q)) {
105142 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
105143 + struct fmt_frame_s,
105144 + list);
105145 + list_del(&p_fmt_frame->list);
105146 +
105147 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105148 + atomic_inc(&fmt_port->dequeue_from_rxq);
105149 +#endif
105150 + }
105151 +
105152 + spin_unlock(rx_q_lock);
105153 +
105154 + return p_fmt_frame;
105155 +}
105156 +
105157 +/* eth-dev -to- fmt port association */
105158 +struct fmt_port_s *match_dpa_to_fmt_port(
105159 + struct dpa_priv_s *dpa_priv) {
105160 + struct mac_device *mac_dev = dpa_priv->mac_dev;
105161 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
105162 + struct fmt_port_s *fmt_port = NULL;
105163 + int i;
105164 +
105165 + _fmt_dbgr("calling...\n");
105166 +
105167 + /* find the FM-test-port object */
105168 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
105169 + if ((fm_test.ports[i].p_mac_dev &&
105170 + mac_dev == fm_test.ports[i].p_mac_dev) ||
105171 + fm_port == fm_test.ports[i].p_tx_port) {
105172 +
105173 + fmt_port = &fm_test.ports[i];
105174 + break;
105175 + }
105176 +
105177 + _fmt_dbgr("called\n");
105178 + return fmt_port;
105179 +}
105180 +
105181 +void dump_frame(
105182 + uint8_t *buffer,
105183 + uint32_t size)
105184 +{
105185 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105186 + unsigned int i;
105187 +
105188 + for (i = 0; i < size; i++) {
105189 + if (i%16 == 0)
105190 + printk(KERN_DEBUG "\n");
105191 + printk(KERN_DEBUG "%2x ", *(buffer+i));
105192 + }
105193 +#endif
105194 + return;
105195 +}
105196 +
105197 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
105198 + uint32_t fqid,
105199 + uint8_t *buffer,
105200 + uint32_t size)
105201 +{
105202 + struct fmt_frame_s *p_fmt_frame = NULL;
105203 + bool test_and_steal_frame_frame;
105204 + uint32_t data_offset;
105205 + uint32_t i;
105206 +
105207 + _fmt_dbgr("calling...\n");
105208 +
105209 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
105210 + return false;
105211 +
105212 + /* check watermark */
105213 + test_and_steal_frame_frame = false;
105214 + for (i = 0; i < size; i++) {
105215 + uint64_t temp = *((uint64_t *)(buffer + i));
105216 +
105217 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
105218 + _fmt_dbgr("watermark found!\n");
105219 + test_and_steal_frame_frame = true;
105220 + break;
105221 + }
105222 + }
105223 +
105224 + if (!test_and_steal_frame_frame) {
105225 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105226 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105227 +#endif
105228 + _fmt_dbgr("NOT watermark found!\n");
105229 + return false;
105230 + }
105231 +
105232 + /* do not enqueue the tx conf/err frames */
105233 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
105234 + goto _test_and_steal_frame_return_true;
105235 +
105236 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
105237 + data_offset = FM_PORT_GetBufferDataOffset(
105238 + fmt_port->p_rx_fm_port_dev);
105239 +
105240 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
105241 +
105242 + /* dump frame... no more space left on device */
105243 + if (p_fmt_frame == NULL) {
105244 + _fmt_err("no space left on device!\n");
105245 + goto _test_and_steal_frame_return_true;
105246 + }
105247 +
105248 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
105249 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
105250 +
105251 + /* No more space left on device*/
105252 + if (p_fmt_frame->buff.p_data == NULL) {
105253 + _fmt_err("no space left on device!\n");
105254 + kfree(p_fmt_frame);
105255 + goto _test_and_steal_frame_return_true;
105256 + }
105257 +
105258 + p_fmt_frame->buff.size = size-data_offset;
105259 + p_fmt_frame->buff.qid = fqid;
105260 +
105261 + memcpy(p_fmt_frame->buff.p_data,
105262 + (uint8_t *)PTR_MOVE(buffer, data_offset),
105263 + p_fmt_frame->buff.size);
105264 +
105265 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
105266 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
105267 + (char *)buffer),
105268 + 32);
105269 +
105270 + /* enqueue frame - this frame will go to us */
105271 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
105272 +
105273 +_test_and_steal_frame_return_true:
105274 + return true;
105275 +}
105276 +
105277 +static int fmt_fq_release(const struct qm_fd *fd)
105278 +{
105279 + struct dpa_bp *_dpa_bp;
105280 + struct bm_buffer _bmb;
105281 +
105282 + if (fd->format == qm_fd_contig) {
105283 + _dpa_bp = dpa_bpid2pool(fd->bpid);
105284 + BUG_ON(IS_ERR(_dpa_bp));
105285 +
105286 + _bmb.hi = fd->addr_hi;
105287 + _bmb.lo = fd->addr_lo;
105288 +
105289 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
105290 + cpu_relax();
105291 +
105292 + } else {
105293 + _fmt_err("frame not supported !\n");
105294 + return -1;
105295 + }
105296 +
105297 + return 0;
105298 +}
105299 +
105300 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
105301 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
105302 + fm_get_rx_extra_headroom() + \
105303 + DPA_PARSE_RESULTS_SIZE + \
105304 + DPA_HASH_RESULTS_SIZE)
105305 +#define MAC_HEADER_LENGTH 14
105306 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
105307 +
105308 +/* dpa ingress hooks definition */
105309 +enum dpaa_eth_hook_result fmt_rx_default_hook(
105310 + struct sk_buff *skb,
105311 + struct net_device *net_dev,
105312 + u32 fqid)
105313 +{
105314 + struct dpa_priv_s *dpa_priv = NULL;
105315 + struct fmt_port_s *fmt_port = NULL;
105316 + uint8_t *buffer;
105317 + uint32_t buffer_len;
105318 +
105319 + _fmt_dbgr("calling...\n");
105320 +
105321 + dpa_priv = netdev_priv(net_dev);
105322 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105323 +
105324 + /* conversion from skb to fd:
105325 + * skb cames processed for L3, so we need to go back for
105326 + * layer 2 offset */
105327 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
105328 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
105329 +
105330 + /* if is not out frame let dpa to handle it */
105331 + if (test_and_steal_frame(fmt_port,
105332 + FMT_RX_DFLT_Q,
105333 + buffer,
105334 + buffer_len))
105335 + goto _fmt_rx_default_hook_stolen;
105336 +
105337 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105338 + return DPAA_ETH_CONTINUE;
105339 +
105340 +_fmt_rx_default_hook_stolen:
105341 + dev_kfree_skb(skb);
105342 +
105343 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105344 + return DPAA_ETH_STOLEN;
105345 +}
105346 +
105347 +enum dpaa_eth_hook_result fmt_rx_error_hook(
105348 + struct net_device *net_dev,
105349 + const struct qm_fd *fd,
105350 + u32 fqid)
105351 +{
105352 + struct dpa_priv_s *dpa_priv = NULL;
105353 + struct dpa_bp *dpa_bp = NULL;
105354 + struct fmt_port_s *fmt_port = NULL;
105355 + void *fd_virt_addr = NULL;
105356 + dma_addr_t addr = qm_fd_addr(fd);
105357 +
105358 + _fmt_dbgr("calling...\n");
105359 +
105360 + dpa_priv = netdev_priv(net_dev);
105361 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105362 +
105363 + /* dpaa doesn't do this... we have to do it here */
105364 + dpa_bp = dpa_bpid2pool(fd->bpid);
105365 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105366 +
105367 + fd_virt_addr = phys_to_virt(addr);
105368 + /* if is not out frame let dpa to handle it */
105369 + if (test_and_steal_frame(fmt_port,
105370 + FMT_RX_ERR_Q,
105371 + fd_virt_addr,
105372 + fd->length20 + fd->offset)) {
105373 + goto _fmt_rx_error_hook_stolen;
105374 + }
105375 +
105376 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105377 + return DPAA_ETH_CONTINUE;
105378 +
105379 +_fmt_rx_error_hook_stolen:
105380 + /* the frame data doesn't matter,
105381 + * so, no mapping is needed */
105382 + fmt_fq_release(fd);
105383 +
105384 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105385 + return DPAA_ETH_STOLEN;
105386 +}
105387 +
105388 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
105389 + struct net_device *net_dev,
105390 + const struct qm_fd *fd,
105391 + u32 fqid)
105392 +{
105393 + struct dpa_priv_s *dpa_priv = NULL;
105394 + struct fmt_port_s *fmt_port = NULL;
105395 + dma_addr_t addr = qm_fd_addr(fd);
105396 + void *fd_virt_addr = NULL;
105397 + uint32_t fd_len = 0;
105398 +
105399 + _fmt_dbgr("calling...\n");
105400 +
105401 + dpa_priv = netdev_priv(net_dev);
105402 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105403 +
105404 + fd_virt_addr = phys_to_virt(addr);
105405 + fd_len = fd->length20 + fd->offset;
105406 +
105407 + if (fd_len > fm_get_max_frm()) {
105408 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
105409 + goto _fmt_tx_confirm_hook_continue;
105410 + }
105411 +
105412 + if (test_and_steal_frame(fmt_port,
105413 + FMT_TX_CONF_Q,
105414 + fd_virt_addr,
105415 + fd_len))
105416 + goto _fmt_tx_confirm_hook_stolen;
105417 +
105418 +_fmt_tx_confirm_hook_continue:
105419 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105420 + return DPAA_ETH_CONTINUE;
105421 +
105422 +_fmt_tx_confirm_hook_stolen:
105423 + kfree(fd_virt_addr);
105424 +
105425 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105426 + return DPAA_ETH_STOLEN;
105427 +}
105428 +
105429 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
105430 + struct net_device *net_dev,
105431 + const struct qm_fd *fd,
105432 + u32 fqid)
105433 +{
105434 + struct dpa_priv_s *dpa_priv = NULL;
105435 + struct fmt_port_s *fmt_port = NULL;
105436 + dma_addr_t addr = qm_fd_addr(fd);
105437 + void *fd_virt_addr = NULL;
105438 + uint32_t fd_len = 0;
105439 +
105440 + _fmt_dbgr("calling...\n");
105441 +
105442 + dpa_priv = netdev_priv(net_dev);
105443 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105444 +
105445 + fd_virt_addr = phys_to_virt(addr);
105446 + fd_len = fd->length20 + fd->offset;
105447 +
105448 + if (fd_len > fm_get_max_frm()) {
105449 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
105450 + goto _priv_ingress_tx_err_continue;
105451 + }
105452 +
105453 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
105454 + goto _priv_ingress_tx_err_stolen;
105455 +
105456 +_priv_ingress_tx_err_continue:
105457 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105458 + return DPAA_ETH_CONTINUE;
105459 +
105460 +_priv_ingress_tx_err_stolen:
105461 + kfree(fd_virt_addr);
105462 +
105463 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105464 + return DPAA_ETH_STOLEN;
105465 +}
105466 +
105467 +/* egress callbacks definition */
105468 +enum qman_cb_dqrr_result fmt_egress_dqrr(
105469 + struct qman_portal *portal,
105470 + struct qman_fq *fq,
105471 + const struct qm_dqrr_entry *dqrr)
105472 +{
105473 + /* this callback should never be called */
105474 + BUG();
105475 + return qman_cb_dqrr_consume;
105476 +}
105477 +
105478 +static void fmt_egress_error_dqrr(
105479 + struct qman_portal *p,
105480 + struct qman_fq *fq,
105481 + const struct qm_mr_entry *msg)
105482 +{
105483 + uint8_t *fd_virt_addr = NULL;
105484 +
105485 + /* tx failure, on the ern callback - release buffer */
105486 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
105487 + kfree(fd_virt_addr);
105488 +
105489 + return;
105490 +}
105491 +
105492 +static const struct qman_fq fmt_egress_fq = {
105493 + .cb = { .dqrr = fmt_egress_dqrr,
105494 + .ern = fmt_egress_error_dqrr,
105495 + .fqs = NULL}
105496 +};
105497 +
105498 +int fmt_fq_alloc(
105499 + struct fmt_fqs_s *fmt_fqs,
105500 + const struct qman_fq *qman_fq,
105501 + uint32_t fqid, uint32_t flags,
105502 + uint16_t channel, uint8_t wq)
105503 +{
105504 + int _errno = 0;
105505 +
105506 + _fmt_dbg("calling...\n");
105507 +
105508 + fmt_fqs->fq_base = *qman_fq;
105509 +
105510 + if (fqid == 0) {
105511 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
105512 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
105513 + } else
105514 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
105515 +
105516 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
105517 +
105518 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
105519 + if (_errno < 0) {
105520 + _fmt_err("frame queues create failed.\n");
105521 + return -EINVAL;
105522 + }
105523 +
105524 + if (fmt_fqs->init) {
105525 + struct qm_mcc_initfq initfq;
105526 +
105527 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
105528 + initfq.fqd.dest.channel = channel;
105529 + initfq.fqd.dest.wq = wq;
105530 +
105531 + _errno = qman_init_fq(&fmt_fqs->fq_base,
105532 + QMAN_INITFQ_FLAG_SCHED,
105533 + &initfq);
105534 + if (_errno < 0) {
105535 + _fmt_err("frame queues init erorr.\n");
105536 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
105537 + return -EINVAL;
105538 + }
105539 + }
105540 +
105541 + _fmt_dbg("called.\n");
105542 + return 0;
105543 +}
105544 +
105545 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
105546 +{
105547 + int _err = 0;
105548 +
105549 + _fmt_dbg("calling...\n");
105550 +
105551 + if (fmt_fq->init) {
105552 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
105553 + if (unlikely(_err < 0))
105554 + _fmt_err("qman_retire_fq(%u) = %d\n",
105555 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105556 +
105557 + _err = qman_oos_fq(&fmt_fq->fq_base);
105558 + if (unlikely(_err < 0))
105559 + _fmt_err("qman_oos_fq(%u) = %d\n",
105560 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105561 + }
105562 +
105563 + qman_destroy_fq(&fmt_fq->fq_base, 0);
105564 +
105565 + _fmt_dbg("called.\n");
105566 + return _err;
105567 +}
105568 +
105569 +/* private pcd dqrr calbacks */
105570 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
105571 + struct qman_portal *portal,
105572 + struct qman_fq *fq,
105573 + const struct qm_dqrr_entry *dq)
105574 +{
105575 + struct dpa_bp *dpa_bp = NULL;
105576 + dma_addr_t addr = qm_fd_addr(&dq->fd);
105577 + uint8_t *fd_virt_addr = NULL;
105578 + struct fmt_port_s *fmt_port;
105579 + struct fmt_port_pcd_s *fmt_port_pcd;
105580 + uint32_t relative_fqid = 0;
105581 + uint32_t fd_len = 0;
105582 +
105583 + _fmt_dbgr("calling...\n");
105584 +
105585 + /* upcast - from pcd_alloc_fq */
105586 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
105587 + if (!fmt_port) {
105588 + _fmt_err(" wrong fmt port -to- fq match.\n");
105589 + goto _fmt_pcd_dqrr_return;
105590 + }
105591 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105592 +
105593 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
105594 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
105595 + relative_fqid, fmt_port_pcd->fqid_base);
105596 +
105597 + fd_len = dq->fd.length20 + dq->fd.offset;
105598 +
105599 + if (fd_len > fm_get_max_frm()) {
105600 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
105601 + fd_len, dq->fd.length20, dq->fd.offset);
105602 + goto _fmt_pcd_dqrr_return;
105603 + }
105604 +
105605 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
105606 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105607 +
105608 + fd_virt_addr = phys_to_virt(addr);
105609 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
105610 + fd_len)) {
105611 +
105612 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105613 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105614 +#endif
105615 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
105616 + " frame len: %u (dropped).\n",
105617 + dq->fqid, dq->fd.length20);
105618 + dump_frame(fd_virt_addr, fd_len);
105619 + }
105620 +
105621 +_fmt_pcd_dqrr_return:
105622 + /* no need to map again here */
105623 + fmt_fq_release(&dq->fd);
105624 +
105625 + _fmt_dbgr("calle.\n");
105626 + return qman_cb_dqrr_consume;
105627 +}
105628 +
105629 +static void fmt_pcd_err_dqrr(
105630 + struct qman_portal *qm,
105631 + struct qman_fq *fq,
105632 + const struct qm_mr_entry *msg)
105633 +{
105634 + _fmt_err("this callback should never be called.\n");
105635 + BUG();
105636 + return;
105637 +}
105638 +
105639 +static void fmt_pcd_fqs_dqrr(
105640 + struct qman_portal *qm,
105641 + struct qman_fq *fq,
105642 + const struct qm_mr_entry *msg)
105643 +{
105644 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
105645 + return;
105646 +}
105647 +
105648 +/* private pcd queue template */
105649 +static const struct qman_fq pcd_fq = {
105650 + .cb = { .dqrr = fmt_pcd_dqrr,
105651 + .ern = fmt_pcd_err_dqrr,
105652 + .fqs = fmt_pcd_fqs_dqrr}
105653 +};
105654 +
105655 +/* defined as weak in dpaa driver. */
105656 +/* ! parameters come from IOCTL call - US */
105657 +int dpa_alloc_pcd_fqids(
105658 + struct device *dev,
105659 + uint32_t num, uint8_t alignment,
105660 + uint32_t *base_fqid)
105661 +{
105662 + int _err = 0, i;
105663 + struct net_device *net_dev = NULL;
105664 + struct dpa_priv_s *dpa_priv = NULL;
105665 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
105666 + struct fmt_fqs_s *fmt_fqs = NULL;
105667 + struct fmt_port_s *fmt_port = NULL;
105668 + int num_allocated = 0;
105669 +
105670 + _fmt_dbg("calling...\n");
105671 +
105672 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
105673 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
105674 +
105675 + if (!netif_msg_probe(dpa_priv)) {
105676 + _fmt_err("dpa not probe.\n");
105677 + _err = -ENODEV;
105678 + goto _pcd_alloc_fqs_err;
105679 + }
105680 +
105681 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105682 + if (!fmt_port) {
105683 + _fmt_err("fmt port not found.");
105684 + _err = -EINVAL;
105685 + goto _pcd_alloc_fqs_err;
105686 + }
105687 +
105688 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105689 +
105690 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
105691 +
105692 + if ((num_allocated <= 0) ||
105693 + (num_allocated < num) ||
105694 + (alignment && (*base_fqid) % alignment)) {
105695 + *base_fqid = 0;
105696 + _fmt_err("Failed to alloc pcd fqs rang.\n");
105697 + _err = -EINVAL;
105698 + goto _pcd_alloc_fqs_err;
105699 + }
105700 +
105701 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
105702 + num, alignment, num_allocated, *base_fqid);
105703 +
105704 + /* alloc pcd queues */
105705 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
105706 + sizeof(struct fmt_fqs_s),
105707 + GFP_KERNEL);
105708 + fmt_port_pcd->num_queues = num_allocated;
105709 + fmt_port_pcd->fqid_base = *base_fqid;
105710 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
105711 +
105712 + /* alloc the pcd queues */
105713 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
105714 + _err = fmt_fq_alloc(
105715 + fmt_fqs,
105716 + &pcd_fq,
105717 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
105718 + dpa_priv->channel, 7);
105719 +
105720 + if (_err < 0)
105721 + goto _pcd_alloc_fqs_err;
105722 +
105723 + /* upcast to identify from where the frames came from */
105724 + fmt_fqs->fmt_port_priv = fmt_port;
105725 + }
105726 +
105727 + _fmt_dbg("called.\n");
105728 + return _err;
105729 +_pcd_alloc_fqs_err:
105730 + if (num_allocated > 0)
105731 + qman_release_fqid_range(*base_fqid, num_allocated);
105732 + /*TODO: free fmt_pcd_fqs if are any */
105733 +
105734 + _fmt_dbg("called(_err:%d).\n", _err);
105735 + return _err;
105736 +}
105737 +
105738 +/* defined as weak in dpaa driver. */
105739 +int dpa_free_pcd_fqids(
105740 + struct device *dev,
105741 + uint32_t base_fqid)
105742 +{
105743 +
105744 + int _err = 0, i;
105745 + struct net_device *net_dev = NULL;
105746 + struct dpa_priv_s *dpa_priv = NULL;
105747 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
105748 + struct fmt_fqs_s *fmt_fqs = NULL;
105749 + struct fmt_port_s *fmt_port = NULL;
105750 + int num_allocated = 0;
105751 +
105752 + _fmt_dbg("calling...\n");
105753 +
105754 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
105755 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
105756 +
105757 + if (!netif_msg_probe(dpa_priv)) {
105758 + _fmt_err("dpa not probe.\n");
105759 + _err = -ENODEV;
105760 + goto _pcd_free_fqs_err;
105761 + }
105762 +
105763 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105764 + if (!fmt_port) {
105765 + _fmt_err("fmt port not found.");
105766 + _err = -EINVAL;
105767 + goto _pcd_free_fqs_err;
105768 + }
105769 +
105770 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105771 + num_allocated = fmt_port_pcd->num_queues;
105772 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
105773 +
105774 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
105775 + fmt_fq_free(fmt_fqs);
105776 +
105777 + qman_release_fqid_range(base_fqid,num_allocated);
105778 +
105779 + kfree(fmt_port_pcd->fmt_pcd_fqs);
105780 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
105781 +
105782 + /* debugging stuff */
105783 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105784 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
105785 + _fmt_dbg(" frames enqueue to qman: %u.\n",
105786 + atomic_read(&fmt_port->enqueue_to_qman_frm));
105787 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
105788 + atomic_read(&fmt_port->enqueue_to_rxq));
105789 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
105790 + atomic_read(&fmt_port->dequeue_from_rxq));
105791 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
105792 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
105793 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
105794 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
105795 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
105796 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
105797 +#endif
105798 + return 0;
105799 +
105800 +_pcd_free_fqs_err:
105801 + return _err;
105802 +}
105803 +
105804 +static int fmt_port_init(
105805 + struct fmt_port_s *fmt_port,
105806 + ioc_fmt_port_param_t *p_Params)
105807 +{
105808 + struct device_node *fm_node, *fm_port_node;
105809 + const uint32_t *uint32_prop;
105810 + int _errno = 0, lenp = 0, i;
105811 + static struct of_device_id fm_node_of_match[] = {
105812 + { .compatible = "fsl,fman", },
105813 + { /* end of list */ },
105814 + };
105815 +
105816 + _fmt_dbg("calling...\n");
105817 +
105818 + /* init send/receive tu US list */
105819 + INIT_LIST_HEAD(&fmt_port->rx_q);
105820 +
105821 + /* check parameters */
105822 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
105823 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
105824 + _fmt_dbg("wrong test parameters.\n");
105825 + return -EINVAL;
105826 + }
105827 +
105828 + /* set port parameters */
105829 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
105830 + fmt_port->id = p_Params->fm_port_id;
105831 + fmt_port->port_type = p_Params->fm_port_type;
105832 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
105833 +
105834 + /* init debugging stuff */
105835 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105836 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
105837 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
105838 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
105839 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
105840 +#endif
105841 +
105842 + /* TODO: This should be done at probe time not at runtime
105843 + * very ugly function */
105844 + /* fill fmt port properties from dts */
105845 + for_each_matching_node(fm_node, fm_node_of_match) {
105846 +
105847 + uint32_prop = (uint32_t *)of_get_property(fm_node,
105848 + "cell-index", &lenp);
105849 + if (unlikely(uint32_prop == NULL)) {
105850 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
105851 + fm_node->full_name);
105852 + return -EINVAL;
105853 + }
105854 + if (WARN_ON(lenp != sizeof(uint32_t))) {
105855 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
105856 + fm_node->full_name);
105857 + return -EINVAL;
105858 + }
105859 +
105860 + if (*uint32_prop == p_Params->fm_id) {
105861 + struct resource res;
105862 +
105863 + /* Get the FM address */
105864 + _errno = of_address_to_resource(fm_node, 0, &res);
105865 + if (unlikely(_errno < 0)) {
105866 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
105867 + return -EINVAL;
105868 + }
105869 +
105870 + fmt_port->fm_phys_base_addr = res.start;
105871 +
105872 + for_each_child_of_node(fm_node, fm_port_node) {
105873 + struct platform_device *of_dev;
105874 +
105875 + if (!of_device_is_available(fm_port_node))
105876 + continue;
105877 +
105878 + uint32_prop = (uint32_t *)of_get_property(
105879 + fm_port_node,
105880 + "cell-index",
105881 + &lenp);
105882 + if (uint32_prop == NULL)
105883 + continue;
105884 +
105885 + if (of_device_is_compatible(fm_port_node,
105886 + "fsl,fman-port-oh") &&
105887 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
105888 +
105889 + if (*uint32_prop == fmt_port->id) {
105890 + of_dev = of_find_device_by_node(fm_port_node);
105891 + if (unlikely(of_dev == NULL)) {
105892 + _fmt_wrn("fm id invalid\n");
105893 + return -EINVAL;
105894 + }
105895 +
105896 + fmt_port->p_tx_port =
105897 + fm_port_bind(&of_dev->dev);
105898 + fmt_port->p_tx_fm_port_dev =
105899 + (void *)fm_port_get_handle(
105900 + fmt_port->p_tx_port);
105901 + fmt_port->p_rx_port =
105902 + fmt_port->p_tx_port;
105903 + fmt_port->p_rx_fm_port_dev =
105904 + fmt_port->p_tx_fm_port_dev;
105905 + fmt_port->p_mac_dev = NULL;
105906 + break;
105907 + }
105908 + } else if ((*uint32_prop == fmt_port->id) &&
105909 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
105910 +
105911 + of_dev = of_find_device_by_node(fm_port_node);
105912 + if (unlikely(of_dev == NULL)) {
105913 + _fmt_wrn("dtb fm id invalid value");
105914 + return -EINVAL;
105915 + }
105916 +
105917 + if (of_device_is_compatible(fm_port_node,
105918 + "fsl,fman-port-1g-tx")) {
105919 + fmt_port->p_tx_port =
105920 + fm_port_bind(&of_dev->dev);
105921 + fmt_port->p_tx_fm_port_dev = (void *)
105922 + fm_port_get_handle(
105923 + fmt_port->p_tx_port);
105924 + } else if (of_device_is_compatible(fm_port_node,
105925 + "fsl,fman-port-1g-rx")) {
105926 + fmt_port->p_rx_port =
105927 + fm_port_bind(&of_dev->dev);
105928 + fmt_port->p_rx_fm_port_dev = (void *)
105929 + fm_port_get_handle(
105930 + fmt_port->p_rx_port);
105931 + } else if (of_device_is_compatible(fm_port_node,
105932 + "fsl,fman-1g-mac") ||
105933 + of_device_is_compatible(fm_port_node,
105934 + "fsl,fman-memac"))
105935 + fmt_port->p_mac_dev =
105936 + (typeof(fmt_port->p_mac_dev))
105937 + dev_get_drvdata(&of_dev->dev);
105938 + else
105939 + continue;
105940 +
105941 + if (fmt_port->p_tx_fm_port_dev &&
105942 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
105943 + break;
105944 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
105945 + fmt_port->id) &&
105946 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
105947 +
105948 + of_dev = of_find_device_by_node(fm_port_node);
105949 + if (unlikely(of_dev == NULL)) {
105950 + _fmt_wrn("dtb fm id invalid value\n");
105951 + return -EINVAL;
105952 + }
105953 +
105954 + if (of_device_is_compatible(fm_port_node,
105955 + "fsl,fman-port-10g-tx")) {
105956 + fmt_port->p_tx_port =
105957 + fm_port_bind(&of_dev->dev);
105958 + fmt_port->p_tx_fm_port_dev = (void *)
105959 + fm_port_get_handle(
105960 + fmt_port->p_tx_port);
105961 + } else if (of_device_is_compatible(fm_port_node,
105962 + "fsl,fman-port-10g-rx")) {
105963 + fmt_port->p_rx_port =
105964 + fm_port_bind(&of_dev->dev);
105965 + fmt_port->p_rx_fm_port_dev = (void *)
105966 + fm_port_get_handle(
105967 + fmt_port->p_rx_port);
105968 + } else if (of_device_is_compatible(fm_port_node,
105969 + "fsl,fman-10g-mac") ||
105970 + of_device_is_compatible(fm_port_node,
105971 + "fsl,fman-memac"))
105972 + fmt_port->p_mac_dev =
105973 + (typeof(fmt_port->p_mac_dev))
105974 + dev_get_drvdata(&of_dev->dev);
105975 + else
105976 + continue;
105977 +
105978 + if (fmt_port->p_tx_fm_port_dev &&
105979 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
105980 + break;
105981 + }
105982 + } /* for_each_child */
105983 + }
105984 + } /* for each matching node */
105985 +
105986 + if (fmt_port->p_tx_fm_port_dev == 0 ||
105987 + fmt_port->p_rx_fm_port_dev == 0) {
105988 +
105989 + _fmt_err("bad fm port pointers.\n");
105990 + return -EINVAL;
105991 + }
105992 +
105993 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
105994 +
105995 + /* init fman test egress dynamic frame queues */
105996 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
105997 + int _errno;
105998 + _errno = fmt_fq_alloc(
105999 + &fmt_port->p_tx_fqs[i],
106000 + &fmt_egress_fq,
106001 + 0,
106002 + QMAN_FQ_FLAG_TO_DCPORTAL,
106003 + fm_get_tx_port_channel(fmt_port->p_tx_port),
106004 + i);
106005 +
106006 + if (_errno < 0) {
106007 + _fmt_err("tx queues allocation failed.\n");
106008 + /* TODO: memory leak here if 1 queue is allocated and
106009 + * next queues are failing ... */
106010 + return -EINVAL;
106011 + }
106012 + }
106013 +
106014 + /* port is valid and ready to use. */
106015 + fmt_port->valid = TRUE;
106016 +
106017 + _fmt_dbg("called.\n");
106018 + return 0;
106019 +}
106020 +
106021 +/* fm test chardev functions */
106022 +static int fmt_open(struct inode *inode, struct file *file)
106023 +{
106024 + unsigned int minor = iminor(inode);
106025 +
106026 + _fmt_dbg("calling...\n");
106027 +
106028 + if (file->private_data != NULL)
106029 + return 0;
106030 +
106031 + /* The minor represent the port number.
106032 + * Set the port structure accordingly, thus all the operations
106033 + * will be done on this port. */
106034 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
106035 + (minor < DEV_FM_TEST_MAX_MINORS))
106036 + file->private_data = &fm_test.ports[minor];
106037 + else
106038 + return -ENXIO;
106039 +
106040 + _fmt_dbg("called.\n");
106041 + return 0;
106042 +}
106043 +
106044 +static int fmt_close(struct inode *inode, struct file *file)
106045 +{
106046 + struct fmt_port_s *fmt_port = NULL;
106047 + struct fmt_frame_s *fmt_frame = NULL;
106048 +
106049 + int err = 0;
106050 +
106051 + _fmt_dbg("calling...\n");
106052 +
106053 + fmt_port = file->private_data;
106054 + if (!fmt_port)
106055 + return -ENODEV;
106056 +
106057 + /* Close the current test port by invalidating it. */
106058 + fmt_port->valid = FALSE;
106059 +
106060 + /* clean the fmt port queue */
106061 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
106062 + if (fmt_frame && fmt_frame->buff.p_data){
106063 + kfree(fmt_frame->buff.p_data);
106064 + kfree(fmt_frame);
106065 + }
106066 + }
106067 +
106068 + /* !!! the qman queues are cleaning from fm_ioctl...
106069 + * - very ugly */
106070 +
106071 + _fmt_dbg("called.\n");
106072 + return err;
106073 +}
106074 +
106075 +static int fmt_ioctls(unsigned int minor,
106076 + struct file *file,
106077 + unsigned int cmd,
106078 + unsigned long arg,
106079 + bool compat)
106080 +{
106081 + struct fmt_port_s *fmt_port = NULL;
106082 +
106083 + _fmt_dbg("IOCTL minor:%u "
106084 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
106085 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106086 +
106087 + fmt_port = file->private_data;
106088 + if (!fmt_port) {
106089 + _fmt_err("invalid fmt port.\n");
106090 + return -ENODEV;
106091 + }
106092 +
106093 + /* set test type properly */
106094 + if (compat)
106095 + fmt_port->compat_test_type = true;
106096 + else
106097 + fmt_port->compat_test_type = false;
106098 +
106099 + switch (cmd) {
106100 + case FMT_PORT_IOC_INIT:
106101 + {
106102 + ioc_fmt_port_param_t param;
106103 +
106104 + if (fmt_port->valid) {
106105 + _fmt_wrn("port is already initialized.\n");
106106 + return -EFAULT;
106107 + }
106108 +#if defined(CONFIG_COMPAT)
106109 + if (compat) {
106110 + if (copy_from_user(&param,
106111 + (ioc_fmt_port_param_t *)compat_ptr(arg),
106112 + sizeof(ioc_fmt_port_param_t)))
106113 +
106114 + return -EFAULT;
106115 + } else
106116 +#endif
106117 + {
106118 + if (copy_from_user(&param,
106119 + (ioc_fmt_port_param_t *) arg,
106120 + sizeof(ioc_fmt_port_param_t)))
106121 +
106122 + return -EFAULT;
106123 + }
106124 +
106125 + return fmt_port_init(fmt_port, &param);
106126 + }
106127 +
106128 + case FMT_PORT_IOC_SET_DIAG_MODE:
106129 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
106130 + return -EFAULT;
106131 +
106132 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
106133 + return set_mac_int_loopback(fmt_port, TRUE);
106134 + else
106135 + return set_mac_int_loopback(fmt_port, FALSE);
106136 + break;
106137 +
106138 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
106139 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
106140 + default:
106141 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
106142 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
106143 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106144 + return -EFAULT;
106145 + }
106146 +
106147 + return 0;
106148 +}
106149 +
106150 +#ifdef CONFIG_COMPAT
106151 +static long fmt_compat_ioctl(
106152 + struct file *file,
106153 + unsigned int cmd,
106154 + unsigned long arg)
106155 +{
106156 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106157 +
106158 + _fmt_dbg("calling...\n");
106159 + return fmt_ioctls(minor, file, cmd, arg, true);
106160 +}
106161 +#endif
106162 +
106163 +static long fmt_ioctl(
106164 + struct file *file,
106165 + unsigned int cmd,
106166 + unsigned long arg)
106167 +{
106168 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106169 + unsigned int res;
106170 +
106171 + _fmt_dbg("calling...\n");
106172 +
106173 + fm_mutex_lock();
106174 + res = fmt_ioctls(minor, file, cmd, arg, false);
106175 + fm_mutex_unlock();
106176 +
106177 + _fmt_dbg("called.\n");
106178 +
106179 + return res;
106180 +}
106181 +
106182 +#ifdef CONFIG_COMPAT
106183 +void copy_compat_test_frame_buffer(
106184 + ioc_fmt_buff_desc_t *buff,
106185 + ioc_fmt_compat_buff_desc_t *compat_buff)
106186 +{
106187 + compat_buff->qid = buff->qid;
106188 + compat_buff->p_data = ptr_to_compat(buff->p_data);
106189 + compat_buff->size = buff->size;
106190 + compat_buff->status = buff->status;
106191 +
106192 + compat_buff->buff_context.p_user_priv =
106193 + ptr_to_compat(buff->buff_context.p_user_priv);
106194 + memcpy(compat_buff->buff_context.fm_prs_res,
106195 + buff->buff_context.fm_prs_res,
106196 + FM_PRS_MAX * sizeof(uint8_t));
106197 + memcpy(compat_buff->buff_context.fm_time_stamp,
106198 + buff->buff_context.fm_time_stamp,
106199 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106200 +}
106201 +#endif
106202 +
106203 +ssize_t fmt_read(
106204 + struct file *file,
106205 + char __user *buf,
106206 + size_t size,
106207 + loff_t *ppos)
106208 +{
106209 + struct fmt_port_s *fmt_port = NULL;
106210 + struct fmt_frame_s *p_fmt_frame = NULL;
106211 + ssize_t cnt = 0;
106212 +
106213 + fmt_port = file->private_data;
106214 + if (!fmt_port || !fmt_port->valid) {
106215 + _fmt_err("fmt port not valid!\n");
106216 + return -ENODEV;
106217 + }
106218 +
106219 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
106220 + if (p_fmt_frame == NULL)
106221 + return 0;
106222 +
106223 + _fmt_dbgr("calling...\n");
106224 +
106225 +#ifdef CONFIG_COMPAT
106226 + if (fmt_port->compat_test_type){
106227 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
106228 + }
106229 + else
106230 +#endif
106231 + {
106232 + cnt = sizeof(ioc_fmt_buff_desc_t);
106233 + }
106234 +
106235 + if (size < cnt) {
106236 + _fmt_err("illegal buffer-size!\n");
106237 + cnt = 0;
106238 + goto _fmt_read_return;
106239 + }
106240 +
106241 + /* Copy structure */
106242 +#ifdef CONFIG_COMPAT
106243 + if (fmt_port->compat_test_type) {
106244 + {
106245 + ioc_fmt_compat_buff_desc_t compat_buff;
106246 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
106247 + &compat_buff);
106248 +
106249 + if (copy_to_user(buf, &compat_buff, cnt)) {
106250 + _fmt_err("copy_to_user failed!\n");
106251 + goto _fmt_read_return;
106252 + }
106253 + }
106254 +
106255 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
106256 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
106257 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106258 + } else
106259 +#endif
106260 + {
106261 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
106262 + _fmt_err("copy_to_user failed!\n");
106263 + goto _fmt_read_return;
106264 + }
106265 +
106266 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
106267 + buf + sizeof(ioc_fmt_buff_desc_t);
106268 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106269 + }
106270 +
106271 + if (size < cnt) {
106272 + _fmt_err("illegal buffer-size!\n");
106273 + goto _fmt_read_return;
106274 + }
106275 +
106276 + /* copy frame */
106277 +#ifdef CONFIG_COMPAT
106278 + if (fmt_port->compat_test_type) {
106279 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
106280 + p_fmt_frame->buff.p_data, cnt)) {
106281 + _fmt_err("copy_to_user failed!\n");
106282 + goto _fmt_read_return;
106283 + }
106284 + } else
106285 +#endif
106286 + {
106287 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
106288 + p_fmt_frame->buff.p_data, cnt)) {
106289 + _fmt_err("copy_to_user failed!\n");
106290 + goto _fmt_read_return;
106291 + }
106292 + }
106293 +
106294 +_fmt_read_return:
106295 + kfree(p_fmt_frame->buff.p_data);
106296 + kfree(p_fmt_frame);
106297 +
106298 + _fmt_dbgr("called.\n");
106299 + return cnt;
106300 +}
106301 +
106302 +ssize_t fmt_write(
106303 + struct file *file,
106304 + const char __user *buf,
106305 + size_t size,
106306 + loff_t *ppos)
106307 +{
106308 + struct fmt_port_s *fmt_port = NULL;
106309 + ioc_fmt_buff_desc_t buff_desc;
106310 +#ifdef CONFIG_COMPAT
106311 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
106312 +#endif
106313 + uint8_t *p_data = NULL;
106314 + uint32_t data_offset;
106315 + int _errno;
106316 + t_DpaaFD fd;
106317 +
106318 + _fmt_dbgr("calling...\n");
106319 +
106320 + fmt_port = file->private_data;
106321 + if (!fmt_port || !fmt_port->valid) {
106322 + _fmt_err("fmt port not valid.\n");
106323 + return -EINVAL;
106324 + }
106325 +
106326 + /* If Compat (32B UserSpace - 64B KernelSpace) */
106327 +#ifdef CONFIG_COMPAT
106328 + if (fmt_port->compat_test_type) {
106329 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
106330 + _fmt_err("invalid buff_desc size.\n");
106331 + return -EFAULT;
106332 + }
106333 +
106334 + if (copy_from_user(&buff_desc_compat, buf,
106335 + sizeof(ioc_fmt_compat_buff_desc_t)))
106336 + return -EFAULT;
106337 +
106338 + buff_desc.qid = buff_desc_compat.qid;
106339 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
106340 + buff_desc.size = buff_desc_compat.size;
106341 + buff_desc.status = buff_desc_compat.status;
106342 +
106343 + buff_desc.buff_context.p_user_priv =
106344 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
106345 + memcpy(buff_desc.buff_context.fm_prs_res,
106346 + buff_desc_compat.buff_context.fm_prs_res,
106347 + FM_PRS_MAX * sizeof(uint8_t));
106348 + memcpy(buff_desc.buff_context.fm_time_stamp,
106349 + buff_desc_compat.buff_context.fm_time_stamp,
106350 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106351 + } else
106352 +#endif
106353 + {
106354 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
106355 + _fmt_err("invalid buff_desc size.\n");
106356 + return -EFAULT;
106357 + }
106358 +
106359 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
106360 + sizeof(ioc_fmt_buff_desc_t)))
106361 + return -EFAULT;
106362 + }
106363 +
106364 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
106365 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
106366 + if (!p_data)
106367 + return -ENOMEM;
106368 +
106369 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
106370 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
106371 + buff_desc.p_data,
106372 + buff_desc.size)) {
106373 + kfree(p_data);
106374 + return -EFAULT;
106375 + }
106376 +
106377 + /* TODO: dma_map_single here (cannot access the bpool struct) */
106378 +
106379 + /* prepare fd */
106380 + memset(&fd, 0, sizeof(fd));
106381 + DPAA_FD_SET_ADDR(&fd, p_data);
106382 + DPAA_FD_SET_OFFSET(&fd, data_offset);
106383 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
106384 +
106385 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
106386 + (struct qm_fd *)&fd, 0);
106387 + if (_errno) {
106388 + buff_desc.status = (uint32_t)_errno;
106389 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
106390 + sizeof(ioc_fmt_buff_desc_t))) {
106391 + kfree(p_data);
106392 + return -EFAULT;
106393 + }
106394 + }
106395 +
106396 + /* for debugging */
106397 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106398 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
106399 +#endif
106400 + _fmt_dbgr("called.\n");
106401 + return buff_desc.size;
106402 +}
106403 +
106404 +/* fm test character device definition */
106405 +static const struct file_operations fmt_fops =
106406 +{
106407 + .owner = THIS_MODULE,
106408 +#ifdef CONFIG_COMPAT
106409 + .compat_ioctl = fmt_compat_ioctl,
106410 +#endif
106411 + .unlocked_ioctl = fmt_ioctl,
106412 + .open = fmt_open,
106413 + .release = fmt_close,
106414 + .read = fmt_read,
106415 + .write = fmt_write,
106416 +};
106417 +
106418 +static int fmt_init(void)
106419 +{
106420 + int id;
106421 +
106422 + _fmt_dbg("calling...\n");
106423 +
106424 + /* Register to the /dev for IOCTL API */
106425 + /* Register dynamically a new major number for the character device: */
106426 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
106427 + if (fm_test.major <= 0) {
106428 + _fmt_wrn("Failed to allocate major number for device %s.\n",
106429 + DEV_FM_TEST_NAME);
106430 + return -ENODEV;
106431 + }
106432 +
106433 + /* Creating class for FMan_test */
106434 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
106435 + if (IS_ERR(fm_test.fmt_class)) {
106436 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
106437 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
106438 + return -ENODEV;
106439 + }
106440 +
106441 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106442 + if (NULL == device_create(fm_test.fmt_class, NULL,
106443 + MKDEV(fm_test.major,
106444 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
106445 + DEV_FM_TEST_NAME "%d", id)) {
106446 +
106447 + _fmt_err("Error creating %s device.\n",
106448 + DEV_FM_TEST_NAME);
106449 + return -ENODEV;
106450 + }
106451 +
106452 + return 0;
106453 +}
106454 +
106455 +static void fmt_free(void)
106456 +{
106457 + int id;
106458 +
106459 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106460 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
106461 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
106462 + class_destroy(fm_test.fmt_class);
106463 +}
106464 +
106465 +static int __init __cold fmt_load(void)
106466 +{
106467 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
106468 +
106469 + /* set dpaa hooks for default queues */
106470 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
106471 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
106472 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
106473 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
106474 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
106475 +
106476 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
106477 +
106478 + /* initialize the fman test environment */
106479 + if (fmt_init() < 0) {
106480 + _fmt_err("Failed to init FM-test modul.\n");
106481 + fmt_free();
106482 + return -ENODEV;
106483 + }
106484 +
106485 + _fmt_inf("FSL FM test module loaded.\n");
106486 +
106487 + return 0;
106488 +}
106489 +
106490 +static void __exit __cold fmt_unload(void)
106491 +{
106492 + fmt_free();
106493 + _fmt_inf("FSL FM test module unloaded.\n");
106494 +}
106495 +
106496 +module_init(fmt_load);
106497 +module_exit(fmt_unload);
106498 --- /dev/null
106499 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
106500 @@ -0,0 +1,2908 @@
106501 +/*
106502 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106503 + *
106504 + * Redistribution and use in source and binary forms, with or without
106505 + * modification, are permitted provided that the following conditions are met:
106506 + * * Redistributions of source code must retain the above copyright
106507 + * notice, this list of conditions and the following disclaimer.
106508 + * * Redistributions in binary form must reproduce the above copyright
106509 + * notice, this list of conditions and the following disclaimer in the
106510 + * documentation and/or other materials provided with the distribution.
106511 + * * Neither the name of Freescale Semiconductor nor the
106512 + * names of its contributors may be used to endorse or promote products
106513 + * derived from this software without specific prior written permission.
106514 + *
106515 + *
106516 + * ALTERNATIVELY, this software may be distributed under the terms of the
106517 + * GNU General Public License ("GPL") as published by the Free Software
106518 + * Foundation, either version 2 of that License or (at your option) any
106519 + * later version.
106520 + *
106521 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106522 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106523 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106524 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106525 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106526 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106527 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106528 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106529 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106530 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106531 + */
106532 +
106533 +/*
106534 + @File lnxwrp_fm.c
106535 + @Author Shlomi Gridish
106536 + @Description FM Linux wrapper functions.
106537 +*/
106538 +
106539 +#include <linux/version.h>
106540 +#include <linux/slab.h>
106541 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
106542 +#define MODVERSIONS
106543 +#endif
106544 +#ifdef MODVERSIONS
106545 +#include <config/modversions.h>
106546 +#endif /* MODVERSIONS */
106547 +#include <linux/kernel.h>
106548 +#include <linux/module.h>
106549 +#include <linux/fs.h>
106550 +#include <linux/cdev.h>
106551 +#include <linux/device.h>
106552 +#include <linux/irq.h>
106553 +#include <linux/interrupt.h>
106554 +#include <linux/io.h>
106555 +#include <linux/ioport.h>
106556 +#include <linux/of_platform.h>
106557 +#include <linux/of_address.h>
106558 +#include <linux/of_irq.h>
106559 +#include <linux/clk.h>
106560 +#include <asm/uaccess.h>
106561 +#include <asm/errno.h>
106562 +#ifndef CONFIG_FMAN_ARM
106563 +#include <sysdev/fsl_soc.h>
106564 +#include <linux/fsl/guts.h>
106565 +#include <linux/fsl/svr.h>
106566 +#endif
106567 +#include <linux/stat.h> /* For file access mask */
106568 +#include <linux/skbuff.h>
106569 +#include <linux/proc_fs.h>
106570 +
106571 +/* NetCommSw Headers --------------- */
106572 +#include "std_ext.h"
106573 +#include "error_ext.h"
106574 +#include "sprint_ext.h"
106575 +#include "debug_ext.h"
106576 +#include "sys_io_ext.h"
106577 +
106578 +#include "fm_ioctls.h"
106579 +
106580 +#include "lnxwrp_fm.h"
106581 +#include "lnxwrp_resources.h"
106582 +#include "lnxwrp_sysfs_fm.h"
106583 +#include "lnxwrp_sysfs_fm_port.h"
106584 +#include "lnxwrp_exp_sym.h"
106585 +#include "fm_common.h"
106586 +#include "../../sdk_fman/Peripherals/FM/fm.h"
106587 +#define __ERR_MODULE__ MODULE_FM
106588 +
106589 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
106590 + e_FmPortType portType,
106591 + uint8_t portId);
106592 +
106593 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
106594 +
106595 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
106596 + do { \
106597 + if (i<max){ \
106598 + p_Entry = &p_Entrys[i]; \
106599 + p_Entry->p_Function = _func; \
106600 + _param \
106601 + i++; \
106602 + } \
106603 + else \
106604 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
106605 + ("Number of advanced-configuration entries exceeded"));\
106606 + } while (0)
106607 +
106608 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
106609 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
106610 +
106611 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
106612 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
106613 +
106614 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
106615 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
106616 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
106617 +
106618 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
106619 +#define FSL_FM_PAUSE_TIME_DISABLE 0
106620 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
106621 +
106622 +/*
106623 + * Max frame size, across all interfaces.
106624 + * Configurable from Kconfig or bootargs, to avoid allocating
106625 + * oversized (socket) buffers when not using jumbo frames.
106626 + * Must be large enough to accommodate the network MTU, but small enough
106627 + * to avoid wasting skb memory.
106628 + *
106629 + * Could be overridden once, at boot-time, via the
106630 + * fm_set_max_frm() callback.
106631 + */
106632 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106633 +
106634 +/*
106635 + * Extra headroom for Rx buffers.
106636 + * FMan is instructed to allocate, on the Rx path, this amount of
106637 + * space at the beginning of a data buffer, beside the DPA private
106638 + * data area and the IC fields.
106639 + * Does not impact Tx buffer layout.
106640 + *
106641 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
106642 + * on particular forwarding scenarios that add extra headers to the
106643 + * forwarded frame.
106644 + */
106645 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106646 +
106647 +#ifdef CONFIG_FMAN_PFC
106648 +static int fsl_fm_pfc_quanta[] = {
106649 + CONFIG_FMAN_PFC_QUANTA_0,
106650 + CONFIG_FMAN_PFC_QUANTA_1,
106651 + CONFIG_FMAN_PFC_QUANTA_2,
106652 + CONFIG_FMAN_PFC_QUANTA_3
106653 +};
106654 +#endif
106655 +
106656 +static t_LnxWrpFm lnxWrpFm;
106657 +
106658 +int fm_get_max_frm()
106659 +{
106660 + return fsl_fm_max_frm;
106661 +}
106662 +EXPORT_SYMBOL(fm_get_max_frm);
106663 +
106664 +int fm_get_rx_extra_headroom()
106665 +{
106666 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
106667 +}
106668 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
106669 +
106670 +static int __init fm_set_max_frm(char *str)
106671 +{
106672 + int ret = 0;
106673 +
106674 + ret = get_option(&str, &fsl_fm_max_frm);
106675 + if (ret != 1) {
106676 + /*
106677 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
106678 + * and something like "earlyprintk=serial,uart0,115200" is
106679 + * specified in the bootargs
106680 + */
106681 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
106682 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
106683 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
106684 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
106685 +
106686 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106687 + return 1;
106688 + }
106689 +
106690 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
106691 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
106692 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
106693 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
106694 + "from Kconfig.\n",
106695 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
106696 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
106697 +
106698 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
106699 + return 1;
106700 + }
106701 +
106702 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
106703 + fsl_fm_max_frm);
106704 + return 0;
106705 +}
106706 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
106707 +
106708 +static int __init fm_set_rx_extra_headroom(char *str)
106709 +{
106710 + int ret;
106711 +
106712 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
106713 +
106714 + if (ret != 1) {
106715 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
106716 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
106717 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
106718 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
106719 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106720 +
106721 + return 1;
106722 + }
106723 +
106724 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
106725 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
106726 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
106727 + "bootargs; will use the default "
106728 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
106729 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
106730 + fsl_fm_rx_extra_headroom,
106731 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
106732 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
106733 + }
106734 +
106735 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
106736 + fsl_fm_rx_extra_headroom);
106737 +
106738 + return 0;
106739 +}
106740 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
106741 +
106742 +static irqreturn_t fm_irq(int irq, void *_dev)
106743 +{
106744 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
106745 +#ifdef CONFIG_PM_SLEEP
106746 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
106747 +#endif
106748 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
106749 + return IRQ_NONE;
106750 +
106751 +#ifdef CONFIG_PM_SLEEP
106752 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
106753 + {
106754 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
106755 + }
106756 +#endif
106757 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
106758 + return IRQ_HANDLED;
106759 +}
106760 +
106761 +static irqreturn_t fm_err_irq(int irq, void *_dev)
106762 +{
106763 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
106764 +
106765 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
106766 + return IRQ_NONE;
106767 +
106768 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
106769 + return IRQ_HANDLED;
106770 +
106771 + return IRQ_NONE;
106772 +}
106773 +
106774 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
106775 +static struct mutex lnxwrp_mutex;
106776 +
106777 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
106778 +{
106779 + t_LnxWrpFmDev *p_LnxWrpFmDev;
106780 + int j;
106781 +
106782 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
106783 + if (!p_LnxWrpFmDev)
106784 + {
106785 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
106786 + return NULL;
106787 + }
106788 +
106789 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
106790 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106791 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106792 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106793 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106794 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106795 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106796 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
106797 + {
106798 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106799 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106800 + }
106801 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
106802 + {
106803 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106804 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106805 + }
106806 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
106807 + {
106808 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
106809 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
106810 + }
106811 +
106812 + return p_LnxWrpFmDev;
106813 +}
106814 +
106815 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
106816 +{
106817 + int j;
106818 +
106819 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
106820 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
106821 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
106822 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
106823 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
106824 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
106825 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
106826 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
106827 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
106828 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
106829 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
106830 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
106831 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
106832 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
106833 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
106834 +
106835 + XX_Free(p_LnxWrpFmDev);
106836 +}
106837 +
106838 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
106839 +{
106840 +#define FM_BMI_PPIDS_OFFSET 0x00080304
106841 +#define FM_DMA_PLR_OFFSET 0x000c2060
106842 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
106843 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
106844 +#define DMA_LOW_LIODN_MASK 0x00000FFF
106845 +#define DMA_LIODN_SHIFT 16
106846 +
106847 +typedef _Packed struct {
106848 + uint32_t plr[32];
106849 +} _PackedType t_Plr;
106850 +
106851 +typedef _Packed struct {
106852 + volatile uint32_t fmbm_ppid[63];
106853 +} _PackedType t_Ppids;
106854 +
106855 + t_Plr *p_Plr;
106856 + t_Ppids *p_Ppids;
106857 + int i,j;
106858 + uint32_t fmRev;
106859 +
106860 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
106861 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
106862 +#if (DPAA_VERSION >= 11)
106863 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
106864 +#else
106865 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
106866 +#endif
106867 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
106868 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
106869 +
106870 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
106871 + fmRev &= 0xffff;
106872 +
106873 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
106874 +#ifdef MODULE
106875 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
106876 + p_Plr->plr[i] = 0;
106877 +#endif /* MODULE */
106878 +
106879 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
106880 + {
106881 + uint16_t liodnBase = (uint16_t)((i%2) ?
106882 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
106883 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
106884 +#ifdef FM_PARTITION_ARRAY
106885 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
106886 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
106887 +#endif /* FM_PARTITION_ARRAY */
106888 +
106889 + if ((i >= phys1GRxPortId[0]) &&
106890 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
106891 + {
106892 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
106893 + if (phys1GRxPortId[j] == i)
106894 + break;
106895 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
106896 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
106897 + }
106898 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
106899 + (i >= phys10GRxPortId[0]) &&
106900 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
106901 + {
106902 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
106903 + if (phys10GRxPortId[j] == i)
106904 + break;
106905 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
106906 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
106907 + }
106908 + else if ((i >= physOhPortId[0]) &&
106909 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
106910 + {
106911 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
106912 + if (physOhPortId[j] == i)
106913 + break;
106914 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
106915 + if (j == 0)
106916 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
106917 + else
106918 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
106919 + }
106920 + else if ((i >= phys1GTxPortId[0]) &&
106921 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
106922 + {
106923 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
106924 + if (phys1GTxPortId[j] == i)
106925 + break;
106926 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
106927 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
106928 + }
106929 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
106930 + (i >= phys10GTxPortId[0]) &&
106931 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
106932 + {
106933 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
106934 + if (phys10GTxPortId[j] == i)
106935 + break;
106936 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
106937 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
106938 + }
106939 + }
106940 +
106941 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
106942 +
106943 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
106944 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
106945 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
106946 +
106947 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
106948 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
106949 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
106950 +
106951 + return E_OK;
106952 +}
106953 +
106954 +/* Structure that defines QE firmware binary files.
106955 + *
106956 + * See Documentation/powerpc/qe_firmware.txt for a description of these
106957 + * fields.
106958 + */
106959 +struct qe_firmware {
106960 + struct qe_header {
106961 + __be32 length; /* Length of the entire structure, in bytes */
106962 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
106963 + u8 version; /* Version of this layout. First ver is '1' */
106964 + } header;
106965 + u8 id[62]; /* Null-terminated identifier string */
106966 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
106967 + u8 count; /* Number of microcode[] structures */
106968 + struct {
106969 + __be16 model; /* The SOC model */
106970 + u8 major; /* The SOC revision major */
106971 + u8 minor; /* The SOC revision minor */
106972 + } __attribute__ ((packed)) soc;
106973 + u8 padding[4]; /* Reserved, for alignment */
106974 + __be64 extended_modes; /* Extended modes */
106975 + __be32 vtraps[8]; /* Virtual trap addresses */
106976 + u8 reserved[4]; /* Reserved, for future expansion */
106977 + struct qe_microcode {
106978 + u8 id[32]; /* Null-terminated identifier */
106979 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
106980 + __be32 eccr; /* The value for the ECCR register */
106981 + __be32 iram_offset; /* Offset into I-RAM for the code */
106982 + __be32 count; /* Number of 32-bit words of the code */
106983 + __be32 code_offset; /* Offset of the actual microcode */
106984 + u8 major; /* The microcode version major */
106985 + u8 minor; /* The microcode version minor */
106986 + u8 revision; /* The microcode version revision */
106987 + u8 padding; /* Reserved, for alignment */
106988 + u8 reserved[4]; /* Reserved, for future expansion */
106989 + } __attribute__ ((packed)) microcode[1];
106990 + /* All microcode binaries should be located here */
106991 + /* CRC32 should be located here, after the microcode binaries */
106992 +} __attribute__ ((packed));
106993 +
106994 +
106995 +/**
106996 + * FindFmanMicrocode - find the Fman microcode
106997 + *
106998 + * This function returns a pointer to the QE Firmware blob that holds
106999 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
107000 + * is similar to QE microcode, so there's no point in defining a new layout.
107001 + *
107002 + * Current versions of U-Boot embed the Fman firmware into the device tree,
107003 + * so we check for that first. Each Fman node in the device tree contains a
107004 + * node or a pointer to node that holds the firmware. Technically, we should
107005 + * be fetching the firmware node for the current Fman, but we don't have that
107006 + * information any more, so we assume that there is only one firmware node in
107007 + * the device tree, and that all Fmen use the same firmware.
107008 + */
107009 +static const struct qe_firmware *FindFmanMicrocode(void)
107010 +{
107011 + static const struct qe_firmware *P4080_UCPatch;
107012 + struct device_node *np;
107013 +
107014 + if (P4080_UCPatch)
107015 + return P4080_UCPatch;
107016 +
107017 + /* The firmware should be inside the device tree. */
107018 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
107019 + if (np) {
107020 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
107021 + of_node_put(np);
107022 + if (P4080_UCPatch)
107023 + return P4080_UCPatch;
107024 + else
107025 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
107026 + }
107027 +
107028 + /* Returning NULL here forces the reuse of the IRAM content */
107029 + return NULL;
107030 +}
107031 +#define SVR_SECURITY_MASK 0x00080000
107032 +#define SVR_PERSONALITY_MASK 0x0000FF00
107033 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
107034 +#define SVR_B4860_REV1_VALUE 0x86800010
107035 +#define SVR_B4860_REV2_VALUE 0x86800020
107036 +#define SVR_T4240_VALUE 0x82400000
107037 +#define SVR_T4120_VALUE 0x82400100
107038 +#define SVR_T4160_VALUE 0x82410000
107039 +#define SVR_T4080_VALUE 0x82410200
107040 +#define SVR_T4_DEVICE_ID 0x82400000
107041 +#define SVR_DEVICE_ID_MASK 0xFFF00000
107042 +
107043 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
107044 +
107045 +/* searches for a subnode with the given name/compatible */
107046 +static bool HasFmPcdOfNode(struct device_node *fm_node,
107047 + struct of_device_id *ids,
107048 + const char *name,
107049 + const char *compatible)
107050 +{
107051 + struct device_node *dev_node;
107052 + bool ret = false;
107053 +
107054 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
107055 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
107056 + return false;
107057 + strcpy(ids[0].name, name);
107058 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
107059 + return false;
107060 + strcpy(ids[0].compatible, compatible);
107061 + for_each_child_of_node(fm_node, dev_node)
107062 + if (of_match_node(ids, dev_node) != NULL)
107063 + ret = true;
107064 + return ret;
107065 +}
107066 +
107067 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
107068 +{
107069 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107070 + struct device_node *fm_node, *dev_node;
107071 + struct of_device_id ids[OF_DEV_ID_NUM];
107072 + struct resource res;
107073 + struct clk *clk;
107074 + u32 clk_rate;
107075 + const uint32_t *uint32_prop;
107076 + int _errno=0, lenp;
107077 + uint32_t tmp_prop;
107078 +
107079 + fm_node = of_node_get(of_dev->dev.of_node);
107080 +
107081 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
107082 + if (unlikely(uint32_prop == NULL)) {
107083 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
107084 + return NULL;
107085 + }
107086 + tmp_prop = be32_to_cpu(*uint32_prop);
107087 +
107088 + if (WARN_ON(lenp != sizeof(uint32_t)))
107089 + return NULL;
107090 +
107091 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107092 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107093 + return NULL;
107094 + }
107095 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
107096 + if (!p_LnxWrpFmDev) {
107097 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
107098 + return NULL;
107099 + }
107100 + p_LnxWrpFmDev->dev = &of_dev->dev;
107101 + p_LnxWrpFmDev->id = tmp_prop;
107102 +
107103 + /* Get the FM interrupt */
107104 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
107105 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
107106 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107107 + DestroyFmDev(p_LnxWrpFmDev);
107108 + return NULL;
107109 + }
107110 +
107111 + /* Get the FM error interrupt */
107112 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
107113 +
107114 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
107115 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107116 + DestroyFmDev(p_LnxWrpFmDev);
107117 + return NULL;
107118 + }
107119 +
107120 + /* Get the FM address */
107121 + _errno = of_address_to_resource(fm_node, 0, &res);
107122 + if (unlikely(_errno < 0)) {
107123 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107124 + DestroyFmDev(p_LnxWrpFmDev);
107125 + return NULL;
107126 + }
107127 +
107128 +
107129 + p_LnxWrpFmDev->fmBaseAddr = 0;
107130 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
107131 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
107132 +
107133 + clk = of_clk_get(fm_node, 0);
107134 + if (IS_ERR(clk)) {
107135 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
107136 + __func__);
107137 + of_node_put(fm_node);
107138 + DestroyFmDev(p_LnxWrpFmDev);
107139 + return NULL;
107140 + }
107141 +
107142 + clk_rate = clk_get_rate(clk);
107143 + if (!clk_rate) {
107144 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
107145 + __func__);
107146 + of_node_put(fm_node);
107147 + DestroyFmDev(p_LnxWrpFmDev);
107148 + return NULL;
107149 + }
107150 +
107151 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
107152 + /* Get the MURAM base address and size */
107153 + memset(ids, 0, sizeof(ids));
107154 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
107155 + return NULL;
107156 + strcpy(ids[0].name, "muram");
107157 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
107158 + return NULL;
107159 + strcpy(ids[0].compatible, "fsl,fman-muram");
107160 + for_each_child_of_node(fm_node, dev_node) {
107161 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107162 + _errno = of_address_to_resource(dev_node, 0, &res);
107163 + if (unlikely(_errno < 0)) {
107164 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107165 + DestroyFmDev(p_LnxWrpFmDev);
107166 + return NULL;
107167 + }
107168 +
107169 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
107170 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
107171 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
107172 +
107173 +#ifndef CONFIG_FMAN_ARM
107174 + {
107175 + uint32_t svr;
107176 + svr = mfspr(SPRN_SVR);
107177 +
107178 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
107179 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
107180 + }
107181 +#endif
107182 + }
107183 + }
107184 +
107185 + /* Get the RTC base address and size */
107186 + memset(ids, 0, sizeof(ids));
107187 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
107188 + return NULL;
107189 + strcpy(ids[0].name, "ptp-timer");
107190 + if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
107191 + return NULL;
107192 + strcpy(ids[0].compatible, "fsl,fman-rtc");
107193 + for_each_child_of_node(fm_node, dev_node) {
107194 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107195 + _errno = of_address_to_resource(dev_node, 0, &res);
107196 + if (unlikely(_errno < 0)) {
107197 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107198 + DestroyFmDev(p_LnxWrpFmDev);
107199 + return NULL;
107200 + }
107201 +
107202 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
107203 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
107204 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
107205 + }
107206 + }
107207 +
107208 +#if (DPAA_VERSION >= 11)
107209 + /* Get the VSP base address */
107210 + for_each_child_of_node(fm_node, dev_node) {
107211 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
107212 + _errno = of_address_to_resource(dev_node, 0, &res);
107213 + if (unlikely(_errno < 0)) {
107214 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107215 + DestroyFmDev(p_LnxWrpFmDev);
107216 + return NULL;
107217 + }
107218 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
107219 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
107220 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
107221 + }
107222 + }
107223 +#endif
107224 +
107225 + /* Get all PCD nodes */
107226 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
107227 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
107228 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
107229 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
107230 +
107231 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
107232 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
107233 + p_LnxWrpFmDev->pcdActive = TRUE;
107234 +
107235 + if (p_LnxWrpFmDev->pcdActive)
107236 + {
107237 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
107238 + if (str_prop) {
107239 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
107240 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
107241 + }
107242 + else
107243 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
107244 + }
107245 +
107246 + of_node_put(fm_node);
107247 +
107248 + p_LnxWrpFmDev->hcCh =
107249 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
107250 +
107251 + p_LnxWrpFmDev->active = TRUE;
107252 +
107253 + return p_LnxWrpFmDev;
107254 +}
107255 +
107256 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
107257 +{
107258 + struct device_node *dev_node;
107259 + const uint32_t *uint32_prop;
107260 + int lenp;
107261 + uint32_t tmp_prop;
107262 +
107263 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
107264 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
107265 + if (unlikely(uint32_prop == NULL)) {
107266 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
107267 + ("of_get_property(%s, cell-index) failed",
107268 + dev_node->full_name));
107269 + return NULL;
107270 + }
107271 + tmp_prop = be32_to_cpu(*uint32_prop);
107272 + if (WARN_ON(lenp != sizeof(uint32_t)))
107273 + return NULL;
107274 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107275 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107276 + return NULL;
107277 + }
107278 + if (fmIndx == tmp_prop)
107279 + return dev_node;
107280 + }
107281 +
107282 + return NULL;
107283 +}
107284 +
107285 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
107286 +{
107287 + struct device_node *dev_node;
107288 + t_Error err = E_INVALID_VALUE;
107289 + const uint32_t *uint32_prop;
107290 + const char *str_prop;
107291 + int lenp;
107292 + uint32_t tmp_prop;
107293 +
107294 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
107295 + if (!dev_node) /* no advance parameters for FMan */
107296 + return E_OK;
107297 +
107298 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
107299 + if (str_prop) {
107300 + if (strcmp(str_prop, "port") == 0)
107301 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
107302 + else if (strcmp(str_prop, "tnum") == 0)
107303 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
107304 +
107305 + if (err != E_OK)
107306 + RETURN_ERROR(MINOR, err, NO_MSG);
107307 + }
107308 +
107309 + uint32_prop = (uint32_t *)of_get_property(dev_node,
107310 + "total-fifo-size", &lenp);
107311 + if (uint32_prop) {
107312 + tmp_prop = be32_to_cpu(*uint32_prop);
107313 + if (WARN_ON(lenp != sizeof(uint32_t)))
107314 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107315 +
107316 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
107317 + tmp_prop) != E_OK)
107318 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107319 + }
107320 +
107321 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
107322 + &lenp);
107323 + if (uint32_prop) {
107324 + tmp_prop = be32_to_cpu(*uint32_prop);
107325 + if (WARN_ON(lenp != sizeof(uint32_t)))
107326 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107327 +
107328 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
107329 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
107330 +
107331 + if (err != E_OK)
107332 + RETURN_ERROR(MINOR, err, NO_MSG);
107333 + }
107334 +
107335 + of_node_put(dev_node);
107336 +
107337 + return E_OK;
107338 +}
107339 +
107340 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
107341 +{
107342 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107343 +
107344 + ASSERT_COND(p_LnxWrpFmDev);
107345 +
107346 + DBG(INFO, ("got fm exception %d", exception));
107347 +
107348 + /* do nothing */
107349 + UNUSED(exception);
107350 +}
107351 +
107352 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
107353 + e_FmPortType portType,
107354 + uint8_t portId,
107355 + uint64_t addr,
107356 + uint8_t tnum,
107357 + uint16_t liodn)
107358 +{
107359 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107360 +
107361 + ASSERT_COND(p_LnxWrpFmDev);
107362 +
107363 + /* do nothing */
107364 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
107365 +}
107366 +
107367 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107368 +{
107369 + struct resource *dev_res;
107370 + int _errno;
107371 +
107372 + if (!p_LnxWrpFmDev->active)
107373 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107374 +
107375 +#ifndef MODULE
107376 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
107377 + if (unlikely(_errno < 0))
107378 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107379 +#endif
107380 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
107381 + if (unlikely(_errno < 0))
107382 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
107383 +
107384 + enable_irq_wake(p_LnxWrpFmDev->irq);
107385 +
107386 + if (p_LnxWrpFmDev->err_irq != 0) {
107387 +#ifndef MODULE
107388 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
107389 + if (unlikely(_errno < 0))
107390 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107391 +#endif
107392 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
107393 + if (unlikely(_errno < 0))
107394 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
107395 +
107396 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
107397 + }
107398 +
107399 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
107400 + if (unlikely(p_LnxWrpFmDev->res == NULL))
107401 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
107402 +
107403 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
107404 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
107405 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107406 +
107407 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
107408 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
107409 +
107410 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
107411 + if (unlikely(dev_res == NULL))
107412 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107413 +
107414 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
107415 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
107416 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107417 +
107418 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
107419 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
107420 +
107421 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
107422 + {
107423 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
107424 + if (unlikely(dev_res == NULL))
107425 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107426 +
107427 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
107428 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
107429 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107430 +
107431 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
107432 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
107433 + }
107434 +
107435 +#if (DPAA_VERSION >= 11)
107436 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
107437 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
107438 + if (unlikely(dev_res == NULL))
107439 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107440 +
107441 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
107442 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
107443 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107444 + }
107445 +#endif
107446 +
107447 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
107448 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
107449 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
107450 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
107451 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
107452 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
107453 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
107454 +
107455 + return FillRestFmInfo(p_LnxWrpFmDev);
107456 +}
107457 +
107458 +#ifndef CONFIG_FMAN_ARM
107459 +/*
107460 + * Table for matching compatible strings, for device tree
107461 + * guts node, for QorIQ SOCs.
107462 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
107463 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
107464 + * string would be used.
107465 +*/
107466 +static const struct of_device_id guts_device_ids[] = {
107467 + { .compatible = "fsl,qoriq-device-config-1.0", },
107468 + { .compatible = "fsl,qoriq-device-config-2.0", },
107469 + {}
107470 +};
107471 +
107472 +static unsigned int get_rcwsr(int regnum)
107473 +{
107474 + struct ccsr_guts __iomem *guts_regs = NULL;
107475 + struct device_node *guts_node;
107476 +
107477 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107478 + if (!guts_node) {
107479 + pr_err("could not find GUTS node\n");
107480 + return 0;
107481 + }
107482 + guts_regs = of_iomap(guts_node, 0);
107483 + of_node_put(guts_node);
107484 + if (!guts_regs) {
107485 + pr_err("ioremap of GUTS node failed\n");
107486 + return 0;
107487 + }
107488 +
107489 + return ioread32be(&guts_regs->rcwsr[regnum]);
107490 +}
107491 +
107492 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
107493 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
107494 +
107495 +/**
107496 + * @Function ResetOnInitErrata_A007273
107497 + *
107498 + * @Description Workaround for Errata A-007273
107499 + * This workaround is required to avoid a FMan hang during reset on initialization.
107500 + * Enable all MACs in guts.devdisr2 register,
107501 + * then perform a regular FMan reset and then restore MACs to their original state.
107502 + *
107503 + * @Param[in] h_Fm - FM module descriptor
107504 + *
107505 + * @Return None.
107506 + */
107507 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
107508 +{
107509 + struct ccsr_guts __iomem *guts_regs = NULL;
107510 + struct device_node *guts_node;
107511 + u32 devdisr2, enableMacs;
107512 +
107513 + /* Get guts registers */
107514 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107515 + if (!guts_node) {
107516 + pr_err("could not find GUTS node\n");
107517 + return;
107518 + }
107519 + guts_regs = of_iomap(guts_node, 0);
107520 + of_node_put(guts_node);
107521 + if (!guts_regs) {
107522 + pr_err("ioremap of GUTS node failed\n");
107523 + return;
107524 + }
107525 +
107526 + /* Read current state */
107527 + devdisr2 = ioread32be(&guts_regs->devdisr2);
107528 +
107529 + if (FmGetId(h_Fm) == 0)
107530 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
107531 + else
107532 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
107533 +
107534 + /* Enable all MACs */
107535 + iowrite32be(enableMacs, &guts_regs->devdisr2);
107536 +
107537 + /* Perform standard FMan reset */
107538 + FmReset(h_Fm);
107539 +
107540 + /* Restore devdisr2 value */
107541 + iowrite32be(devdisr2, &guts_regs->devdisr2);
107542 +
107543 + iounmap(guts_regs);
107544 +}
107545 +#endif
107546 +
107547 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107548 +{
107549 + const struct qe_firmware *fw;
107550 +
107551 + if (!p_LnxWrpFmDev->active)
107552 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107553 +
107554 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
107555 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
107556 +
107557 + /* Loading the fman-controller code */
107558 + fw = FindFmanMicrocode();
107559 +
107560 + if (!fw) {
107561 + /* this forces the reuse of the current IRAM content */
107562 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
107563 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
107564 + } else {
107565 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
107566 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
107567 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
107568 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
107569 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
107570 + fw->microcode[0].major,
107571 + fw->microcode[0].minor,
107572 + fw->microcode[0].revision));
107573 + }
107574 +
107575 +#ifdef CONFIG_FMAN_ARM
107576 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
107577 + int i;
107578 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
107579 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
107580 + u32 *dest = kzalloc(usz, GFP_KERNEL);
107581 +
107582 + if (p_Code && dest)
107583 + for(i=0; i < usz / 4; ++i)
107584 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
107585 +
107586 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
107587 + }
107588 +#endif
107589 +
107590 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
107591 +
107592 +#if (DPAA_VERSION >= 11)
107593 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
107594 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
107595 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
107596 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
107597 + }
107598 +#endif
107599 +
107600 +#ifdef CONFIG_FMAN_ARM
107601 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107602 +#else
107603 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
107604 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107605 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
107606 + else
107607 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107608 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
107609 +
107610 + {
107611 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
107612 + uint32_t svr;
107613 + svr = mfspr(SPRN_SVR);
107614 +
107615 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
107616 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107617 + }
107618 +#endif /* CONFIG_FMAN_ARM */
107619 +
107620 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
107621 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
107622 +
107623 +
107624 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
107625 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107626 +
107627 +#ifndef CONFIG_FMAN_ARM
107628 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
107629 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
107630 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107631 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
107632 +#endif /* CONFIG_FMAN_ARM */
107633 +
107634 +#ifdef CONFIG_FMAN_P1023
107635 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
107636 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107637 +#endif
107638 +
107639 +
107640 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
107641 +
107642 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
107643 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
107644 +
107645 + /* TODO: Why we mask these interrupts? */
107646 + if (p_LnxWrpFmDev->err_irq == 0) {
107647 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
107648 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
107649 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
107650 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
107651 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
107652 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
107653 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
107654 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
107655 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
107656 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
107657 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
107658 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
107659 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
107660 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
107661 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
107662 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
107663 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
107664 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
107665 + }
107666 +
107667 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
107668 + {
107669 + t_FmRtcParams fmRtcParam;
107670 +
107671 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
107672 + fmRtcParam.h_App = p_LnxWrpFmDev;
107673 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
107674 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
107675 +
107676 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
107677 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
107678 +
107679 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
107680 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
107681 +
107682 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
107683 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
107684 + }
107685 +
107686 + return E_OK;
107687 +}
107688 +
107689 +/* TODO: to be moved back here */
107690 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
107691 +
107692 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107693 +{
107694 + if (!p_LnxWrpFmDev->active)
107695 + return;
107696 +
107697 + FreeFmPcdDev(p_LnxWrpFmDev);
107698 +
107699 + if (p_LnxWrpFmDev->h_RtcDev)
107700 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
107701 +
107702 + if (p_LnxWrpFmDev->h_Dev)
107703 + FM_Free(p_LnxWrpFmDev->h_Dev);
107704 +
107705 + if (p_LnxWrpFmDev->h_MuramDev)
107706 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
107707 +
107708 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
107709 + {
107710 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
107711 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
107712 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
107713 + }
107714 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
107715 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
107716 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
107717 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
107718 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
107719 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
107720 + if (p_LnxWrpFmDev->err_irq != 0) {
107721 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
107722 + }
107723 +
107724 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
107725 +}
107726 +
107727 +/* FMan character device file operations */
107728 +extern struct file_operations fm_fops;
107729 +
107730 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
107731 +{
107732 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107733 +
107734 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
107735 + return -EIO;
107736 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
107737 + return -EIO;
107738 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
107739 + return -EIO;
107740 +
107741 + /* IOCTL ABI checking */
107742 + LnxWrpPCDIOCTLEnumChecking();
107743 + LnxWrpPCDIOCTLTypeChecking();
107744 +
107745 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
107746 +
107747 + /* Register to the /dev for IOCTL API */
107748 + /* Register dynamically a new major number for the character device: */
107749 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
107750 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
107751 + return -EIO;
107752 + }
107753 +
107754 + /* Creating classes for FM */
107755 + DBG(TRACE ,("class_create fm_class"));
107756 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
107757 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
107758 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
107759 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
107760 + return -EIO;
107761 + }
107762 +
107763 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
107764 + "fm%d", p_LnxWrpFmDev->id);
107765 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
107766 + "fm%d-pcd", p_LnxWrpFmDev->id);
107767 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
107768 +
107769 + /* create sysfs entries for stats and regs */
107770 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
107771 + {
107772 + FreeFmDev(p_LnxWrpFmDev);
107773 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
107774 + return -EIO;
107775 + }
107776 +
107777 +#ifdef CONFIG_PM
107778 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
107779 +#endif
107780 +
107781 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
107782 +
107783 + return 0;
107784 +}
107785 +
107786 +static int fm_remove(struct platform_device *of_dev)
107787 +{
107788 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107789 + struct device *dev;
107790 +
107791 + dev = &of_dev->dev;
107792 + p_LnxWrpFmDev = dev_get_drvdata(dev);
107793 +
107794 + fm_sysfs_destroy(dev);
107795 +
107796 + DBG(TRACE, ("destroy fm_class"));
107797 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
107798 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
107799 + class_destroy(p_LnxWrpFmDev->fm_class);
107800 +
107801 + /* Destroy chardev */
107802 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
107803 +
107804 + FreeFmDev(p_LnxWrpFmDev);
107805 +
107806 + DestroyFmDev(p_LnxWrpFmDev);
107807 +
107808 + dev_set_drvdata(dev, NULL);
107809 +
107810 + return 0;
107811 +}
107812 +
107813 +static const struct of_device_id fm_match[] = {
107814 + {
107815 + .compatible = "fsl,fman"
107816 + },
107817 + {}
107818 +};
107819 +#ifndef MODULE
107820 +MODULE_DEVICE_TABLE(of, fm_match);
107821 +#endif /* !MODULE */
107822 +
107823 +#ifdef CONFIG_PM
107824 +
107825 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
107826 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
107827 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
107828 +
107829 +struct device *g_fm_dev;
107830 +
107831 +static int fm_soc_suspend(struct device *dev)
107832 +{
107833 + int err = 0;
107834 + uint32_t *fmclk;
107835 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
107836 + g_fm_dev = dev;
107837 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
107838 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
107839 + if (p_LnxWrpFmDev->h_DsarRxPort)
107840 + {
107841 +#ifdef CONFIG_FSL_QORIQ_PM
107842 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
107843 +#endif
107844 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
107845 + p_LnxWrpFmDev->h_DsarTxPort);
107846 + }
107847 + return err;
107848 +}
107849 +
107850 +static int fm_soc_resume(struct device *dev)
107851 +{
107852 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
107853 + uint32_t *fmclk;
107854 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
107855 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
107856 + if (p_LnxWrpFmDev->h_DsarRxPort)
107857 + {
107858 +#ifdef CONFIG_FSL_QORIQ_PM
107859 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
107860 +#endif
107861 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
107862 + p_LnxWrpFmDev->h_DsarTxPort);
107863 + p_LnxWrpFmDev->h_DsarRxPort = 0;
107864 + p_LnxWrpFmDev->h_DsarTxPort = 0;
107865 + }
107866 + return 0;
107867 +}
107868 +
107869 +static const struct dev_pm_ops fm_pm_ops = {
107870 + .suspend = fm_soc_suspend,
107871 + .resume = fm_soc_resume,
107872 +};
107873 +
107874 +#define FM_PM_OPS (&fm_pm_ops)
107875 +
107876 +#else /* CONFIG_PM */
107877 +
107878 +#define FM_PM_OPS NULL
107879 +
107880 +#endif /* CONFIG_PM */
107881 +
107882 +static struct platform_driver fm_driver = {
107883 + .driver = {
107884 + .name = "fsl-fman",
107885 + .of_match_table = fm_match,
107886 + .owner = THIS_MODULE,
107887 + .pm = FM_PM_OPS,
107888 + },
107889 + .probe = fm_probe,
107890 + .remove = fm_remove
107891 +};
107892 +
107893 +t_Handle LNXWRP_FM_Init(void)
107894 +{
107895 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
107896 + mutex_init(&lnxwrp_mutex);
107897 +
107898 + /* Register to the DTB for basic FM API */
107899 + platform_driver_register(&fm_driver);
107900 +
107901 + return &lnxWrpFm;
107902 +}
107903 +
107904 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
107905 +{
107906 + platform_driver_unregister(&fm_driver);
107907 + mutex_destroy(&lnxwrp_mutex);
107908 +
107909 + return E_OK;
107910 +}
107911 +
107912 +
107913 +struct fm * fm_bind(struct device *fm_dev)
107914 +{
107915 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
107916 +}
107917 +EXPORT_SYMBOL(fm_bind);
107918 +
107919 +void fm_unbind(struct fm *fm)
107920 +{
107921 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
107922 +
107923 + put_device(p_LnxWrpFmDev->dev);
107924 +}
107925 +EXPORT_SYMBOL(fm_unbind);
107926 +
107927 +struct resource * fm_get_mem_region(struct fm *fm)
107928 +{
107929 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
107930 +
107931 + return p_LnxWrpFmDev->res;
107932 +}
107933 +EXPORT_SYMBOL(fm_get_mem_region);
107934 +
107935 +void * fm_get_handle(struct fm *fm)
107936 +{
107937 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
107938 +
107939 + return (void *)p_LnxWrpFmDev->h_Dev;
107940 +}
107941 +EXPORT_SYMBOL(fm_get_handle);
107942 +
107943 +void * fm_get_rtc_handle(struct fm *fm)
107944 +{
107945 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
107946 +
107947 + return (void *)p_LnxWrpFmDev->h_RtcDev;
107948 +}
107949 +EXPORT_SYMBOL(fm_get_rtc_handle);
107950 +
107951 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
107952 +{
107953 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
107954 +}
107955 +EXPORT_SYMBOL(fm_port_bind);
107956 +
107957 +void fm_port_unbind(struct fm_port *port)
107958 +{
107959 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
107960 +
107961 + put_device(p_LnxWrpFmPortDev->dev);
107962 +}
107963 +EXPORT_SYMBOL(fm_port_unbind);
107964 +
107965 +void *fm_port_get_handle(const struct fm_port *port)
107966 +{
107967 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
107968 +
107969 + return (void *)p_LnxWrpFmPortDev->h_Dev;
107970 +}
107971 +EXPORT_SYMBOL(fm_port_get_handle);
107972 +
107973 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
107974 + const void *data)
107975 +{
107976 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
107977 + (void *)data);
107978 +}
107979 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
107980 +
107981 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
107982 +{
107983 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
107984 +
107985 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
107986 +}
107987 +EXPORT_SYMBOL(fm_port_get_base_addr);
107988 +
107989 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
107990 +{
107991 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
107992 +
107993 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
107994 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
107995 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
107996 +}
107997 +EXPORT_SYMBOL(fm_port_pcd_bind);
107998 +
107999 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
108000 +{
108001 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108002 + struct device_node *fm_node, *port_node;
108003 + const uint32_t *uint32_prop;
108004 + int lenp;
108005 +
108006 + params->data_align = 0;
108007 + params->manip_extra_space = 0;
108008 +
108009 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
108010 + if (!fm_node) /* no advance parameters for FMan */
108011 + return;
108012 +
108013 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
108014 + p_LnxWrpFmPortDev->settings.param.portType,
108015 + p_LnxWrpFmPortDev->settings.param.portId);
108016 + if (!port_node) /* no advance parameters for FMan-Port */
108017 + return;
108018 +
108019 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
108020 + if (uint32_prop) {
108021 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
108022 + return;
108023 +
108024 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
108025 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
108026 + }
108027 +
108028 + of_node_put(port_node);
108029 + of_node_put(fm_node);
108030 +}
108031 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
108032 +
108033 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
108034 +{
108035 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108036 +
108037 + return p_LnxWrpFmPortDev->txCh;
108038 +}
108039 +EXPORT_SYMBOL(fm_get_tx_port_channel);
108040 +
108041 +int fm_port_enable (struct fm_port *port)
108042 +{
108043 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108044 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108045 +
108046 + return GET_ERROR_TYPE(err);
108047 +}
108048 +EXPORT_SYMBOL(fm_port_enable);
108049 +
108050 +int fm_port_disable(struct fm_port *port)
108051 +{
108052 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108053 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108054 +
108055 + return GET_ERROR_TYPE(err);
108056 +}
108057 +EXPORT_SYMBOL(fm_port_disable);
108058 +
108059 +int fm_port_set_rate_limit(struct fm_port *port,
108060 + uint16_t max_burst_size,
108061 + uint32_t rate_limit)
108062 +{
108063 + t_FmPortRateLimit param;
108064 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108065 + int err = 0;
108066 +
108067 + param.maxBurstSize = max_burst_size;
108068 + param.rateLimit = rate_limit;
108069 + param.rateLimitDivider = 0;
108070 +
108071 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
108072 + return err;
108073 +}
108074 +EXPORT_SYMBOL(fm_port_set_rate_limit);
108075 +
108076 +int fm_port_del_rate_limit(struct fm_port *port)
108077 +{
108078 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108079 +
108080 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
108081 + return 0;
108082 +}
108083 +EXPORT_SYMBOL(fm_port_del_rate_limit);
108084 +
108085 +void FM_PORT_Dsar_DumpRegs(void);
108086 +int ar_showmem(struct file *file, const char __user *buffer,
108087 + unsigned long count, void *data)
108088 +{
108089 + FM_PORT_Dsar_DumpRegs();
108090 + return 2;
108091 +}
108092 +
108093 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
108094 + struct fm_port *port)
108095 +{
108096 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108097 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
108098 +}
108099 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
108100 +
108101 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
108102 + struct auto_res_port_params *params)
108103 +{
108104 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108105 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
108106 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
108107 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
108108 +
108109 + /*Register other under /proc/autoresponse */
108110 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
108111 + return -EFAULT;
108112 +
108113 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
108114 + return 0;
108115 +}
108116 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
108117 +
108118 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
108119 + struct fm_port *port_tx)
108120 +{
108121 +}
108122 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
108123 +
108124 +int fm_port_get_autores_stats(struct fm_port *port,
108125 + struct auto_res_port_stats *stats)
108126 +{
108127 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108128 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
108129 + return -EFAULT;
108130 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
108131 +}
108132 +EXPORT_SYMBOL(fm_port_get_autores_stats);
108133 +
108134 +int fm_port_suspend(struct fm_port *port)
108135 +{
108136 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108137 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108138 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108139 + else
108140 + return 0;
108141 +}
108142 +EXPORT_SYMBOL(fm_port_suspend);
108143 +
108144 +int fm_port_resume(struct fm_port *port)
108145 +{
108146 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108147 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108148 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108149 + else
108150 + return 0;
108151 +}
108152 +EXPORT_SYMBOL(fm_port_resume);
108153 +
108154 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
108155 +{
108156 + return FM_PORT_IsInDsar(port);
108157 +}
108158 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
108159 +
108160 +#ifdef CONFIG_FMAN_PFC
108161 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
108162 + uint8_t prio, uint8_t wq)
108163 +{
108164 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108165 + int err;
108166 + int _errno;
108167 +
108168 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
108169 + prio, wq);
108170 + _errno = -GET_ERROR_TYPE(err);
108171 + if (unlikely(_errno < 0))
108172 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
108173 +
108174 + return _errno;
108175 +}
108176 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
108177 +#endif
108178 +
108179 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
108180 + e_FmMacExceptions exception, bool enable)
108181 +{
108182 + int err;
108183 + int _errno;
108184 +
108185 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
108186 +
108187 + _errno = -GET_ERROR_TYPE(err);
108188 + if (unlikely(_errno < 0))
108189 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
108190 +
108191 + return _errno;
108192 +}
108193 +EXPORT_SYMBOL(fm_mac_set_exception);
108194 +
108195 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
108196 +{
108197 + int err;
108198 + int _error;
108199 +
108200 + err = FM_MAC_Free(fm_mac_dev);
108201 + _error = -GET_ERROR_TYPE(err);
108202 +
108203 + if (unlikely(_error < 0))
108204 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
108205 +
108206 + return _error;
108207 +}
108208 +EXPORT_SYMBOL(fm_mac_free);
108209 +
108210 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
108211 +{
108212 + struct fm_mac_dev *fm_mac_dev;
108213 +
108214 + fm_mac_dev = FM_MAC_Config(params);
108215 + if (unlikely(fm_mac_dev == NULL))
108216 + pr_err("FM_MAC_Config() failed\n");
108217 +
108218 + return fm_mac_dev;
108219 +}
108220 +EXPORT_SYMBOL(fm_mac_config);
108221 +
108222 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
108223 + int len)
108224 +{
108225 + int err;
108226 + int _errno;
108227 +
108228 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
108229 + _errno = -GET_ERROR_TYPE(err);
108230 + if (unlikely(_errno < 0))
108231 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108232 +
108233 + return _errno;
108234 +}
108235 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
108236 +
108237 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
108238 +{
108239 + int err;
108240 + int _errno;
108241 +
108242 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
108243 + _errno = -GET_ERROR_TYPE(err);
108244 + if (unlikely(_errno < 0))
108245 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
108246 +
108247 + return _errno;
108248 +}
108249 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
108250 +
108251 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
108252 +{
108253 + int err;
108254 + int _errno;
108255 +
108256 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
108257 + _errno = -GET_ERROR_TYPE(err);
108258 + if (unlikely(_errno < 0))
108259 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
108260 +
108261 + return _errno;
108262 +}
108263 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
108264 +
108265 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
108266 +{
108267 + int err;
108268 + int _errno;
108269 +
108270 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
108271 + _errno = -GET_ERROR_TYPE(err);
108272 + if (unlikely(_errno < 0))
108273 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
108274 +
108275 + return _errno;
108276 +}
108277 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
108278 +
108279 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
108280 +{
108281 + int err;
108282 + int _errno;
108283 +
108284 + err = FM_MAC_Init(fm_mac_dev);
108285 + _errno = -GET_ERROR_TYPE(err);
108286 + if (unlikely(_errno < 0))
108287 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
108288 +
108289 + return _errno;
108290 +}
108291 +EXPORT_SYMBOL(fm_mac_init);
108292 +
108293 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
108294 +{
108295 + int err;
108296 + int _errno;
108297 +
108298 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
108299 + _errno = -GET_ERROR_TYPE(err);
108300 + if (unlikely(_errno < 0))
108301 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
108302 +
108303 + return _errno;
108304 +}
108305 +EXPORT_SYMBOL(fm_mac_get_version);
108306 +
108307 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
108308 +{
108309 + int _errno;
108310 + t_Error err;
108311 +
108312 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108313 + _errno = -GET_ERROR_TYPE(err);
108314 + if (unlikely(_errno < 0))
108315 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
108316 +
108317 + return _errno;
108318 +}
108319 +EXPORT_SYMBOL(fm_mac_enable);
108320 +
108321 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
108322 +{
108323 + int _errno;
108324 + t_Error err;
108325 +
108326 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108327 + _errno = -GET_ERROR_TYPE(err);
108328 + if (unlikely(_errno < 0))
108329 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
108330 +
108331 + return _errno;
108332 +}
108333 +EXPORT_SYMBOL(fm_mac_disable);
108334 +
108335 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
108336 +{
108337 + int _errno;
108338 + t_Error err;
108339 +
108340 + err = FM_MAC_Resume(fm_mac_dev);
108341 + _errno = -GET_ERROR_TYPE(err);
108342 + if (unlikely(_errno < 0))
108343 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
108344 +
108345 + return _errno;
108346 +}
108347 +EXPORT_SYMBOL(fm_mac_resume);
108348 +
108349 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
108350 + bool enable)
108351 +{
108352 + int _errno;
108353 + t_Error err;
108354 +
108355 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
108356 + _errno = -GET_ERROR_TYPE(err);
108357 + if (unlikely(_errno < 0))
108358 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
108359 +
108360 + return _errno;
108361 +}
108362 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
108363 +
108364 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108365 + t_EnetAddr *mac_addr)
108366 +{
108367 + int _errno;
108368 + t_Error err;
108369 +
108370 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
108371 + _errno = -GET_ERROR_TYPE(err);
108372 + if (_errno < 0) {
108373 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
108374 + return _errno;
108375 + }
108376 +
108377 + return 0;
108378 +}
108379 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
108380 +
108381 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108382 + t_EnetAddr *mac_addr)
108383 +{
108384 + int _errno;
108385 + t_Error err;
108386 +
108387 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
108388 + _errno = -GET_ERROR_TYPE(err);
108389 + if (_errno < 0) {
108390 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
108391 + return _errno;
108392 + }
108393 +
108394 + return 0;
108395 +}
108396 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
108397 +
108398 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
108399 + uint8_t *addr)
108400 +{
108401 + int _errno;
108402 + t_Error err;
108403 +
108404 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
108405 + _errno = -GET_ERROR_TYPE(err);
108406 + if (_errno < 0)
108407 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
108408 +
108409 + return _errno;
108410 +}
108411 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
108412 +
108413 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
108414 + bool link, int speed, bool duplex)
108415 +{
108416 + int _errno;
108417 + t_Error err;
108418 +
108419 + if (!link) {
108420 +#if (DPAA_VERSION < 11)
108421 + FM_MAC_RestartAutoneg(fm_mac_dev);
108422 +#endif
108423 + return 0;
108424 + }
108425 +
108426 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
108427 + _errno = -GET_ERROR_TYPE(err);
108428 + if (unlikely(_errno < 0))
108429 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
108430 +
108431 + return _errno;
108432 +}
108433 +EXPORT_SYMBOL(fm_mac_adjust_link);
108434 +
108435 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108436 +{
108437 + int _errno;
108438 + t_Error err;
108439 +
108440 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
108441 + _errno = -GET_ERROR_TYPE(err);
108442 + if (unlikely(_errno < 0))
108443 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
108444 + return _errno;
108445 +}
108446 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
108447 +
108448 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108449 +{
108450 + int _errno;
108451 + t_Error err;
108452 +
108453 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
108454 + _errno = -GET_ERROR_TYPE(err);
108455 + if (unlikely(_errno < 0))
108456 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
108457 + return _errno;
108458 +}
108459 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
108460 +
108461 +int fm_mac_set_rx_pause_frames(
108462 + struct fm_mac_dev *fm_mac_dev, bool en)
108463 +{
108464 + int _errno;
108465 + t_Error err;
108466 +
108467 + /* if rx pause is enabled, do NOT ignore pause frames */
108468 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
108469 +
108470 + _errno = -GET_ERROR_TYPE(err);
108471 + if (_errno < 0)
108472 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
108473 +
108474 + return _errno;
108475 +}
108476 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
108477 +
108478 +#ifdef CONFIG_FMAN_PFC
108479 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108480 + bool en)
108481 +{
108482 + int _errno, i;
108483 + t_Error err;
108484 +
108485 + if (en)
108486 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108487 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108488 + i, fsl_fm_pfc_quanta[i],
108489 + FSL_FM_PAUSE_THRESH_DEFAULT);
108490 + _errno = -GET_ERROR_TYPE(err);
108491 + if (_errno < 0) {
108492 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108493 + return _errno;
108494 + }
108495 + }
108496 + else
108497 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108498 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108499 + i, FSL_FM_PAUSE_TIME_DISABLE,
108500 + FSL_FM_PAUSE_THRESH_DEFAULT);
108501 + _errno = -GET_ERROR_TYPE(err);
108502 + if (_errno < 0) {
108503 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108504 + return _errno;
108505 + }
108506 + }
108507 +
108508 + return _errno;
108509 +}
108510 +#else
108511 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108512 + bool en)
108513 +{
108514 + int _errno;
108515 + t_Error err;
108516 +
108517 + if (en)
108518 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108519 + FSL_FM_PAUSE_TIME_ENABLE);
108520 + else
108521 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108522 + FSL_FM_PAUSE_TIME_DISABLE);
108523 +
108524 + _errno = -GET_ERROR_TYPE(err);
108525 + if (_errno < 0)
108526 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
108527 +
108528 + return _errno;
108529 +}
108530 +#endif
108531 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
108532 +
108533 +int fm_rtc_enable(struct fm *fm_dev)
108534 +{
108535 + int _errno;
108536 + t_Error err;
108537 +
108538 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
108539 + _errno = -GET_ERROR_TYPE(err);
108540 + if (unlikely(_errno < 0))
108541 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
108542 +
108543 + return _errno;
108544 +}
108545 +EXPORT_SYMBOL(fm_rtc_enable);
108546 +
108547 +int fm_rtc_disable(struct fm *fm_dev)
108548 +{
108549 + int _errno;
108550 + t_Error err;
108551 +
108552 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
108553 + _errno = -GET_ERROR_TYPE(err);
108554 + if (unlikely(_errno < 0))
108555 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
108556 +
108557 + return _errno;
108558 +}
108559 +EXPORT_SYMBOL(fm_rtc_disable);
108560 +
108561 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
108562 +{
108563 + int _errno;
108564 + t_Error err;
108565 +
108566 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108567 + _errno = -GET_ERROR_TYPE(err);
108568 + if (unlikely(_errno < 0))
108569 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
108570 +
108571 + return _errno;
108572 +}
108573 +EXPORT_SYMBOL(fm_rtc_get_cnt);
108574 +
108575 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
108576 +{
108577 + int _errno;
108578 + t_Error err;
108579 +
108580 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108581 + _errno = -GET_ERROR_TYPE(err);
108582 + if (unlikely(_errno < 0))
108583 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
108584 +
108585 + return _errno;
108586 +}
108587 +EXPORT_SYMBOL(fm_rtc_set_cnt);
108588 +
108589 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
108590 +{
108591 + int _errno;
108592 + t_Error err;
108593 +
108594 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
108595 + drift);
108596 + _errno = -GET_ERROR_TYPE(err);
108597 + if (unlikely(_errno < 0))
108598 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
108599 +
108600 + return _errno;
108601 +}
108602 +EXPORT_SYMBOL(fm_rtc_get_drift);
108603 +
108604 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
108605 +{
108606 + int _errno;
108607 + t_Error err;
108608 +
108609 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
108610 + drift);
108611 + _errno = -GET_ERROR_TYPE(err);
108612 + if (unlikely(_errno < 0))
108613 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
108614 +
108615 + return _errno;
108616 +}
108617 +EXPORT_SYMBOL(fm_rtc_set_drift);
108618 +
108619 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
108620 + uint64_t time)
108621 +{
108622 + t_FmRtcAlarmParams alarm;
108623 + int _errno;
108624 + t_Error err;
108625 +
108626 + alarm.alarmId = id;
108627 + alarm.alarmTime = time;
108628 + alarm.f_AlarmCallback = NULL;
108629 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
108630 + &alarm);
108631 + _errno = -GET_ERROR_TYPE(err);
108632 + if (unlikely(_errno < 0))
108633 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
108634 +
108635 + return _errno;
108636 +}
108637 +EXPORT_SYMBOL(fm_rtc_set_alarm);
108638 +
108639 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
108640 + uint64_t fiper)
108641 +{
108642 + t_FmRtcPeriodicPulseParams pp;
108643 + int _errno;
108644 + t_Error err;
108645 +
108646 + pp.periodicPulseId = id;
108647 + pp.periodicPulsePeriod = fiper;
108648 + pp.f_PeriodicPulseCallback = NULL;
108649 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
108650 + _errno = -GET_ERROR_TYPE(err);
108651 + if (unlikely(_errno < 0))
108652 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
108653 +
108654 + return _errno;
108655 +}
108656 +EXPORT_SYMBOL(fm_rtc_set_fiper);
108657 +
108658 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
108659 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
108660 +{
108661 + int _errno;
108662 + t_Error err;
108663 +
108664 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
108665 + events);
108666 + _errno = -GET_ERROR_TYPE(err);
108667 + if (unlikely(_errno < 0))
108668 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
108669 +
108670 + return _errno;
108671 +}
108672 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
108673 +
108674 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
108675 +{
108676 + int _errno;
108677 + t_Error err;
108678 +
108679 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
108680 + events);
108681 + _errno = -GET_ERROR_TYPE(err);
108682 + if (unlikely(_errno < 0))
108683 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
108684 +
108685 + return _errno;
108686 +}
108687 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
108688 +#endif
108689 +
108690 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
108691 +{
108692 + int _errno;
108693 + t_Error err;
108694 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108695 +
108696 + /* Do not set WoL on AR ports */
108697 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
108698 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
108699 + return 0;
108700 + }
108701 +
108702 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
108703 +
108704 + _errno = -GET_ERROR_TYPE(err);
108705 + if (_errno < 0)
108706 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
108707 +
108708 + return _errno;
108709 +}
108710 +EXPORT_SYMBOL(fm_mac_set_wol);
108711 +
108712 +void fm_mutex_lock(void)
108713 +{
108714 + mutex_lock(&lnxwrp_mutex);
108715 +}
108716 +EXPORT_SYMBOL(fm_mutex_lock);
108717 +
108718 +void fm_mutex_unlock(void)
108719 +{
108720 + mutex_unlock(&lnxwrp_mutex);
108721 +}
108722 +EXPORT_SYMBOL(fm_mutex_unlock);
108723 +
108724 +/*Macsec wrapper functions*/
108725 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
108726 +{
108727 + struct fm_macsec_dev *fm_macsec_dev;
108728 +
108729 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
108730 + if (unlikely(fm_macsec_dev == NULL))
108731 + pr_err("FM_MACSEC_Config() failed\n");
108732 +
108733 + return fm_macsec_dev;
108734 +}
108735 +EXPORT_SYMBOL(fm_macsec_config);
108736 +
108737 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
108738 +{
108739 + int err;
108740 + int _errno;
108741 +
108742 + err = FM_MACSEC_Init(fm_macsec_dev);
108743 + _errno = -GET_ERROR_TYPE(err);
108744 + if (unlikely(_errno < 0))
108745 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
108746 +
108747 + return _errno;
108748 +}
108749 +EXPORT_SYMBOL(fm_macsec_init);
108750 +
108751 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
108752 +{
108753 + int err;
108754 + int _error;
108755 +
108756 + err = FM_MACSEC_Free(fm_macsec_dev);
108757 + _error = -GET_ERROR_TYPE(err);
108758 +
108759 + if (unlikely(_error < 0))
108760 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
108761 +
108762 + return _error;
108763 +}
108764 +EXPORT_SYMBOL(fm_macsec_free);
108765 +
108766 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
108767 + *fm_macsec_dev,
108768 + fm_macsec_unknown_sci_frame_treatment treat_mode)
108769 +{
108770 + int err;
108771 + int _errno;
108772 +
108773 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
108774 + treat_mode);
108775 + _errno = -GET_ERROR_TYPE(err);
108776 + if (unlikely(_errno < 0))
108777 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
108778 +
108779 + return _errno;
108780 +}
108781 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
108782 +
108783 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108784 + bool deliver_uncontrolled)
108785 +{
108786 + int err;
108787 + int _errno;
108788 +
108789 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
108790 + deliver_uncontrolled);
108791 + _errno = -GET_ERROR_TYPE(err);
108792 + if (unlikely(_errno < 0))
108793 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108794 +
108795 + return _errno;
108796 +}
108797 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
108798 +
108799 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108800 + bool discard_uncontrolled)
108801 +{
108802 + int err;
108803 + int _errno;
108804 +
108805 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
108806 + discard_uncontrolled);
108807 + _errno = -GET_ERROR_TYPE(err);
108808 + if (unlikely(_errno < 0))
108809 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
108810 +
108811 + return _errno;
108812 +}
108813 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
108814 +
108815 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
108816 + fm_macsec_untag_frame_treatment treat_mode)
108817 +{
108818 + int err;
108819 + int _errno;
108820 +
108821 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
108822 + _errno = -GET_ERROR_TYPE(err);
108823 + if (unlikely(_errno < 0))
108824 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
108825 +
108826 + return _errno;
108827 +}
108828 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
108829 +
108830 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
108831 + uint32_t pn_exh_thr)
108832 +{
108833 + int err;
108834 + int _errno;
108835 +
108836 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
108837 + _errno = -GET_ERROR_TYPE(err);
108838 + if (unlikely(_errno < 0))
108839 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
108840 +
108841 + return _errno;
108842 +}
108843 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
108844 +
108845 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
108846 +{
108847 + int err;
108848 + int _errno;
108849 +
108850 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
108851 + _errno = -GET_ERROR_TYPE(err);
108852 + if (unlikely(_errno < 0))
108853 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
108854 +
108855 + return _errno;
108856 +}
108857 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
108858 +
108859 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
108860 +{
108861 + int err;
108862 + int _errno;
108863 +
108864 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
108865 + _errno = -GET_ERROR_TYPE(err);
108866 + if (unlikely(_errno < 0))
108867 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
108868 +
108869 + return _errno;
108870 +}
108871 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
108872 +
108873 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
108874 + fm_macsec_exception exception, bool enable)
108875 +{
108876 + int err;
108877 + int _errno;
108878 +
108879 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
108880 + _errno = -GET_ERROR_TYPE(err);
108881 + if (unlikely(_errno < 0))
108882 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
108883 +
108884 + return _errno;
108885 +}
108886 +EXPORT_SYMBOL(fm_macsec_config_exception);
108887 +
108888 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
108889 + int *macsec_revision)
108890 +{
108891 + int err;
108892 + int _errno;
108893 +
108894 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
108895 + _errno = -GET_ERROR_TYPE(err);
108896 + if (unlikely(_errno < 0))
108897 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
108898 +
108899 + return _errno;
108900 +}
108901 +EXPORT_SYMBOL(fm_macsec_get_revision);
108902 +
108903 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
108904 +{
108905 + int err;
108906 + int _errno;
108907 +
108908 + err = FM_MACSEC_Enable(fm_macsec_dev);
108909 + _errno = -GET_ERROR_TYPE(err);
108910 + if (unlikely(_errno < 0))
108911 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
108912 +
108913 + return _errno;
108914 +}
108915 +EXPORT_SYMBOL(fm_macsec_enable);
108916 +
108917 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
108918 +{
108919 + int err;
108920 + int _errno;
108921 +
108922 + err = FM_MACSEC_Disable(fm_macsec_dev);
108923 + _errno = -GET_ERROR_TYPE(err);
108924 + if (unlikely(_errno < 0))
108925 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
108926 +
108927 + return _errno;
108928 +}
108929 +EXPORT_SYMBOL(fm_macsec_disable);
108930 +
108931 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
108932 + fm_macsec_exception exception, bool enable)
108933 +{
108934 + int err;
108935 + int _errno;
108936 +
108937 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
108938 + _errno = -GET_ERROR_TYPE(err);
108939 + if (unlikely(_errno < 0))
108940 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
108941 +
108942 + return _errno;
108943 +}
108944 +EXPORT_SYMBOL(fm_macsec_set_exception);
108945 +
108946 +/* Macsec SECY wrapper API */
108947 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
108948 +{
108949 + struct fm_macsec_secy_dev *fm_macsec_secy;
108950 +
108951 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
108952 + if (unlikely(fm_macsec_secy < 0))
108953 + pr_err("FM_MACSEC_SECY_Config() failed\n");
108954 +
108955 + return fm_macsec_secy;
108956 +}
108957 +EXPORT_SYMBOL(fm_macsec_secy_config);
108958 +
108959 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
108960 +{
108961 + int err;
108962 + int _errno;
108963 +
108964 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
108965 + _errno = -GET_ERROR_TYPE(err);
108966 + if (unlikely(_errno < 0))
108967 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
108968 +
108969 + return _errno;
108970 +}
108971 +EXPORT_SYMBOL(fm_macsec_secy_init);
108972 +
108973 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
108974 +{
108975 + int err;
108976 + int _errno;
108977 +
108978 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
108979 + _errno = -GET_ERROR_TYPE(err);
108980 + if (unlikely(_errno < 0))
108981 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
108982 +
108983 + return _errno;
108984 +}
108985 +EXPORT_SYMBOL(fm_macsec_secy_free);
108986 +
108987 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
108988 + fm_macsec_sci_insertion_mode sci_insertion_mode)
108989 +{
108990 + int err;
108991 + int _errno;
108992 +
108993 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
108994 + sci_insertion_mode);
108995 + _errno = -GET_ERROR_TYPE(err);
108996 + if (unlikely(_errno < 0))
108997 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
108998 +
108999 + return _errno;
109000 +}
109001 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
109002 +
109003 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109004 + bool protect_frames)
109005 +{
109006 + int err;
109007 + int _errno;
109008 +
109009 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
109010 + protect_frames);
109011 + _errno = -GET_ERROR_TYPE(err);
109012 + if (unlikely(_errno < 0))
109013 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
109014 +
109015 + return _errno;
109016 +}
109017 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
109018 +
109019 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109020 + bool replay_protect, uint32_t replay_window)
109021 +{
109022 + int err;
109023 + int _errno;
109024 +
109025 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
109026 + replay_protect, replay_window);
109027 + _errno = -GET_ERROR_TYPE(err);
109028 + if (unlikely(_errno < 0))
109029 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
109030 +
109031 + return _errno;
109032 +}
109033 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
109034 +
109035 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109036 + fm_macsec_valid_frame_behavior validate_frames)
109037 +{
109038 + int err;
109039 + int _errno;
109040 +
109041 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
109042 + validate_frames);
109043 + _errno = -GET_ERROR_TYPE(err);
109044 + if (unlikely(_errno < 0))
109045 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
109046 +
109047 + return _errno;
109048 +}
109049 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
109050 +
109051 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109052 + bool confidentiality_enable,
109053 + uint32_t confidentiality_offset)
109054 +{
109055 + int err;
109056 + int _errno;
109057 +
109058 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
109059 + confidentiality_enable,
109060 + confidentiality_offset);
109061 + _errno = -GET_ERROR_TYPE(err);
109062 + if (unlikely(_errno < 0))
109063 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
109064 + err);
109065 +
109066 + return _errno;
109067 +}
109068 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
109069 +
109070 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109071 +{
109072 + int err;
109073 + int _errno;
109074 +
109075 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
109076 + _errno = -GET_ERROR_TYPE(err);
109077 + if (unlikely(_errno < 0))
109078 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
109079 + err);
109080 +
109081 + return _errno;
109082 +}
109083 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
109084 +
109085 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109086 + fm_macsec_secy_exception exception,
109087 + bool enable)
109088 +{
109089 + int err;
109090 + int _errno;
109091 +
109092 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
109093 + enable);
109094 + _errno = -GET_ERROR_TYPE(err);
109095 + if (unlikely(_errno < 0))
109096 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
109097 + err);
109098 +
109099 + return _errno;
109100 +}
109101 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
109102 +
109103 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109104 + fm_macsec_secy_event event,
109105 + bool enable)
109106 +{
109107 + int err;
109108 + int _errno;
109109 +
109110 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
109111 + _errno = -GET_ERROR_TYPE(err);
109112 + if (unlikely(_errno < 0))
109113 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
109114 + err);
109115 +
109116 + return _errno;
109117 +}
109118 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
109119 +
109120 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109121 + struct fm_macsec_secy_sc_params *params)
109122 +{
109123 + struct rx_sc_dev *rx_sc_dev;
109124 +
109125 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
109126 + if (unlikely(rx_sc_dev == NULL))
109127 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
109128 +
109129 + return rx_sc_dev;
109130 +}
109131 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
109132 +
109133 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109134 + struct rx_sc_dev *sc)
109135 +{
109136 + int err;
109137 + int _errno;
109138 +
109139 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
109140 + _errno = -GET_ERROR_TYPE(err);
109141 + if (unlikely(_errno < 0))
109142 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
109143 + err);
109144 +
109145 + return _errno;
109146 +}
109147 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
109148 +
109149 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109150 + struct rx_sc_dev *sc, macsec_an_t an,
109151 + uint32_t lowest_pn, macsec_sa_key_t key)
109152 +{
109153 + int err;
109154 + int _errno;
109155 +
109156 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
109157 + lowest_pn, key);
109158 + _errno = -GET_ERROR_TYPE(err);
109159 + if (unlikely(_errno < 0))
109160 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
109161 + err);
109162 +
109163 + return _errno;
109164 +}
109165 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
109166 +
109167 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109168 + struct rx_sc_dev *sc, macsec_an_t an)
109169 +{
109170 + int err;
109171 + int _errno;
109172 +
109173 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
109174 + _errno = -GET_ERROR_TYPE(err);
109175 + if (unlikely(_errno < 0))
109176 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
109177 + err);
109178 +
109179 + return _errno;
109180 +}
109181 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
109182 +
109183 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109184 + struct rx_sc_dev *sc,
109185 + macsec_an_t an)
109186 +{
109187 + int err;
109188 + int _errno;
109189 +
109190 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
109191 + _errno = -GET_ERROR_TYPE(err);
109192 + if (unlikely(_errno < 0))
109193 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
109194 + err);
109195 +
109196 + return _errno;
109197 +}
109198 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
109199 +
109200 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109201 + struct rx_sc_dev *sc,
109202 + macsec_an_t an)
109203 +{
109204 + int err;
109205 + int _errno;
109206 +
109207 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
109208 + _errno = -GET_ERROR_TYPE(err);
109209 + if (unlikely(_errno < 0))
109210 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
109211 + err);
109212 +
109213 + return _errno;
109214 +}
109215 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
109216 +
109217 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109218 + struct rx_sc_dev *sc,
109219 + macsec_an_t an, uint32_t updt_next_pn)
109220 +{
109221 + int err;
109222 + int _errno;
109223 +
109224 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
109225 + updt_next_pn);
109226 + _errno = -GET_ERROR_TYPE(err);
109227 + if (unlikely(_errno < 0))
109228 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
109229 +
109230 + return _errno;
109231 +}
109232 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
109233 +
109234 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109235 + struct rx_sc_dev *sc,
109236 + macsec_an_t an, uint32_t updt_lowest_pn)
109237 +{
109238 + int err;
109239 + int _errno;
109240 +
109241 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
109242 + updt_lowest_pn);
109243 + _errno = -GET_ERROR_TYPE(err);
109244 + if (unlikely(_errno < 0))
109245 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
109246 + err);
109247 +
109248 + return _errno;
109249 +}
109250 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
109251 +
109252 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109253 + struct rx_sc_dev *sc,
109254 + macsec_an_t an, macsec_sa_key_t key)
109255 +{
109256 + int err;
109257 + int _errno;
109258 +
109259 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
109260 + _errno = -GET_ERROR_TYPE(err);
109261 + if (unlikely(_errno < 0))
109262 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
109263 + err);
109264 +
109265 + return _errno;
109266 +}
109267 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
109268 +
109269 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109270 + macsec_an_t an, macsec_sa_key_t key)
109271 +{
109272 + int err;
109273 + int _errno;
109274 +
109275 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
109276 + _errno = -GET_ERROR_TYPE(err);
109277 + if (unlikely(_errno < 0))
109278 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
109279 + err);
109280 +
109281 + return _errno;
109282 +}
109283 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
109284 +
109285 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109286 + macsec_an_t an)
109287 +{
109288 + int err;
109289 + int _errno;
109290 +
109291 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
109292 + _errno = -GET_ERROR_TYPE(err);
109293 + if (unlikely(_errno < 0))
109294 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
109295 + err);
109296 +
109297 + return _errno;
109298 +}
109299 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
109300 +
109301 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109302 + macsec_an_t next_active_an,
109303 + macsec_sa_key_t key)
109304 +{
109305 + int err;
109306 + int _errno;
109307 +
109308 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
109309 + key);
109310 + _errno = -GET_ERROR_TYPE(err);
109311 + if (unlikely(_errno < 0))
109312 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
109313 + err);
109314 +
109315 + return _errno;
109316 +}
109317 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
109318 +
109319 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109320 + macsec_an_t an)
109321 +{
109322 + int err;
109323 + int _errno;
109324 +
109325 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
109326 + _errno = -GET_ERROR_TYPE(err);
109327 + if (unlikely(_errno < 0))
109328 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
109329 + err);
109330 +
109331 + return _errno;
109332 +}
109333 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
109334 +
109335 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109336 + macsec_an_t *p_an)
109337 +{
109338 + int err;
109339 + int _errno;
109340 +
109341 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
109342 + _errno = -GET_ERROR_TYPE(err);
109343 + if (unlikely(_errno < 0))
109344 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
109345 + err);
109346 +
109347 + return _errno;
109348 +}
109349 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
109350 +
109351 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109352 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
109353 +{
109354 + int err;
109355 + int _errno;
109356 +
109357 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
109358 + _errno = -GET_ERROR_TYPE(err);
109359 + if (unlikely(_errno < 0))
109360 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
109361 + err);
109362 +
109363 + return _errno;
109364 +}
109365 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
109366 +
109367 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109368 + uint32_t *sc_phys_id)
109369 +{
109370 + int err;
109371 + int _errno;
109372 +
109373 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
109374 + _errno = -GET_ERROR_TYPE(err);
109375 + if (unlikely(_errno < 0))
109376 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
109377 + err);
109378 +
109379 + return _errno;
109380 +}
109381 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
109382 +
109383 +static t_Handle h_FmLnxWrp;
109384 +
109385 +static int __init __cold fm_load (void)
109386 +{
109387 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
109388 + {
109389 + printk("Failed to init FM wrapper!\n");
109390 + return -ENODEV;
109391 + }
109392 +
109393 + printk(KERN_CRIT "Freescale FM module," \
109394 + " FMD API version %d.%d.%d\n",
109395 + FMD_API_VERSION_MAJOR,
109396 + FMD_API_VERSION_MINOR,
109397 + FMD_API_VERSION_RESPIN);
109398 + return 0;
109399 +}
109400 +
109401 +static void __exit __cold fm_unload (void)
109402 +{
109403 + if (h_FmLnxWrp)
109404 + LNXWRP_FM_Free(h_FmLnxWrp);
109405 +}
109406 +
109407 +module_init (fm_load);
109408 +module_exit (fm_unload);
109409 --- /dev/null
109410 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
109411 @@ -0,0 +1,294 @@
109412 +/*
109413 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109414 + *
109415 + * Redistribution and use in source and binary forms, with or without
109416 + * modification, are permitted provided that the following conditions are met:
109417 + * * Redistributions of source code must retain the above copyright
109418 + * notice, this list of conditions and the following disclaimer.
109419 + * * Redistributions in binary form must reproduce the above copyright
109420 + * notice, this list of conditions and the following disclaimer in the
109421 + * documentation and/or other materials provided with the distribution.
109422 + * * Neither the name of Freescale Semiconductor nor the
109423 + * names of its contributors may be used to endorse or promote products
109424 + * derived from this software without specific prior written permission.
109425 + *
109426 + *
109427 + * ALTERNATIVELY, this software may be distributed under the terms of the
109428 + * GNU General Public License ("GPL") as published by the Free Software
109429 + * Foundation, either version 2 of that License or (at your option) any
109430 + * later version.
109431 + *
109432 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109433 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109434 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109435 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109436 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109437 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109438 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109439 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109440 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109441 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109442 + */
109443 +
109444 +/*
109445 + @File lnxwrp_fm.h
109446 +
109447 + @Author Shlomi Gridish
109448 +
109449 + @Description FM Linux wrapper functions.
109450 +
109451 +*/
109452 +
109453 +#ifndef __LNXWRP_FM_H__
109454 +#define __LNXWRP_FM_H__
109455 +
109456 +#include <linux/fsl_qman.h> /* struct qman_fq */
109457 +
109458 +#include "std_ext.h"
109459 +#include "error_ext.h"
109460 +#include "list_ext.h"
109461 +
109462 +#include "lnxwrp_fm_ext.h"
109463 +
109464 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
109465 +
109466 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
109467 +
109468 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
109469 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
109470 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
109471 +#else
109472 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
109473 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
109474 +#endif
109475 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
109476 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
109477 +
109478 +#define FRAG_MANIP_SPACE 128
109479 +#define FRAG_DATA_ALIGN 64
109480 +
109481 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
109482 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
109483 +#endif
109484 +
109485 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
109486 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
109487 +#endif
109488 +
109489 +typedef enum {
109490 + e_NO_PCD = 0,
109491 + e_FM_PCD_3_TUPLE
109492 +} e_LnxWrpFmPortPcdDefUseCase;
109493 +
109494 +
109495 +typedef struct t_FmTestFq {
109496 + struct qman_fq fq_base;
109497 + t_Handle h_Arg;
109498 +} t_FmTestFq;
109499 +
109500 +typedef struct {
109501 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
109502 + int minor;
109503 + char name[20];
109504 + bool active;
109505 + uint64_t phys_baseAddr;
109506 + uint64_t baseAddr; /* Port's *virtual* address */
109507 + uint32_t memSize;
109508 + t_WrpFmPortDevSettings settings;
109509 + t_FmExtPools opExtPools;
109510 + uint8_t totalNumOfSchemes;
109511 + uint8_t schemesBase;
109512 + uint8_t numOfSchemesUsed;
109513 + uint32_t pcdBaseQ;
109514 + uint16_t pcdNumOfQs;
109515 + struct fm_port_pcd_param pcd_owner_params;
109516 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109517 + t_Handle h_DefNetEnv;
109518 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
109519 + t_FmBufferPrefixContent buffPrefixContent;
109520 + t_Handle h_Dev;
109521 + t_Handle h_DfltVsp;
109522 + t_Handle h_LnxWrpFmDev;
109523 + uint16_t txCh;
109524 + struct device *dev;
109525 + struct device_attribute *dev_attr_stats;
109526 + struct device_attribute *dev_attr_regs;
109527 + struct device_attribute *dev_attr_bmi_regs;
109528 + struct device_attribute *dev_attr_qmi_regs;
109529 +#if (DPAA_VERSION >= 11)
109530 + struct device_attribute *dev_attr_ipv4_opt;
109531 +#endif
109532 + struct device_attribute *dev_attr_dsar_regs;
109533 + struct device_attribute *dev_attr_dsar_mem;
109534 + struct auto_res_tables_sizes dsar_table_sizes;
109535 +} t_LnxWrpFmPortDev;
109536 +
109537 +typedef struct {
109538 + uint8_t id;
109539 + bool active;
109540 + uint64_t baseAddr;
109541 + uint32_t memSize;
109542 + t_WrpFmMacDevSettings settings;
109543 + t_Handle h_Dev;
109544 + t_Handle h_LnxWrpFmDev;
109545 +} t_LnxWrpFmMacDev;
109546 +
109547 +/* information about all active ports for an FMan.
109548 + * !Some ports may be disabled by u-boot, thus will not be available */
109549 +struct fm_active_ports {
109550 + uint32_t num_oh_ports;
109551 + uint32_t num_tx_ports;
109552 + uint32_t num_rx_ports;
109553 + uint32_t num_tx25_ports;
109554 + uint32_t num_rx25_ports;
109555 + uint32_t num_tx10_ports;
109556 + uint32_t num_rx10_ports;
109557 +};
109558 +
109559 +/* FMan resources precalculated at fm probe based
109560 + * on available FMan port. */
109561 +struct fm_resource_settings {
109562 + /* buffers - fifo sizes */
109563 + uint32_t tx1g_num_buffers;
109564 + uint32_t rx1g_num_buffers;
109565 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
109566 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
109567 + uint32_t tx10g_num_buffers;
109568 + uint32_t rx10g_num_buffers;
109569 + uint32_t oh_num_buffers;
109570 + uint32_t shared_ext_buffers;
109571 +
109572 + /* open DMAs */
109573 + uint32_t tx_1g_dmas;
109574 + uint32_t rx_1g_dmas;
109575 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
109576 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
109577 + uint32_t tx_10g_dmas;
109578 + uint32_t rx_10g_dmas;
109579 + uint32_t oh_dmas;
109580 + uint32_t shared_ext_open_dma;
109581 +
109582 + /* Tnums */
109583 + uint32_t tx_1g_tnums;
109584 + uint32_t rx_1g_tnums;
109585 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
109586 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
109587 + uint32_t tx_10g_tnums;
109588 + uint32_t rx_10g_tnums;
109589 + uint32_t oh_tnums;
109590 + uint32_t shared_ext_tnums;
109591 +};
109592 +
109593 +typedef struct {
109594 + uint8_t id;
109595 + char name[10];
109596 + bool active;
109597 + bool pcdActive;
109598 + bool prsActive;
109599 + bool kgActive;
109600 + bool ccActive;
109601 + bool plcrActive;
109602 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109603 + uint32_t usedSchemes;
109604 + uint8_t totalNumOfSharedSchemes;
109605 + uint8_t sharedSchemesBase;
109606 + uint8_t numOfSchemesUsed;
109607 + uint8_t defNetEnvId;
109608 + uint64_t fmPhysBaseAddr;
109609 + uint64_t fmBaseAddr;
109610 + uint32_t fmMemSize;
109611 + uint64_t fmMuramPhysBaseAddr;
109612 + uint64_t fmMuramBaseAddr;
109613 + uint32_t fmMuramMemSize;
109614 + uint64_t fmRtcPhysBaseAddr;
109615 + uint64_t fmRtcBaseAddr;
109616 + uint32_t fmRtcMemSize;
109617 + uint64_t fmVspPhysBaseAddr;
109618 + uint64_t fmVspBaseAddr;
109619 + uint32_t fmVspMemSize;
109620 + int irq;
109621 + int err_irq;
109622 + t_WrpFmDevSettings fmDevSettings;
109623 + t_WrpFmPcdDevSettings fmPcdDevSettings;
109624 + t_Handle h_Dev;
109625 + uint16_t hcCh;
109626 +
109627 + t_Handle h_MuramDev;
109628 + t_Handle h_PcdDev;
109629 + t_Handle h_RtcDev;
109630 +
109631 + t_Handle h_DsarRxPort;
109632 + t_Handle h_DsarTxPort;
109633 +
109634 + t_LnxWrpFmPortDev hcPort;
109635 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
109636 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
109637 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
109638 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
109639 + struct fm_active_ports fm_active_ports_info;
109640 + struct fm_resource_settings fm_resource_settings_info;
109641 +
109642 + struct device *dev;
109643 + struct resource *res;
109644 + int major;
109645 + struct class *fm_class;
109646 + struct device_attribute *dev_attr_stats;
109647 + struct device_attribute *dev_attr_regs;
109648 + struct device_attribute *dev_attr_risc_load;
109649 +
109650 + struct device_attribute *dev_pcd_attr_stats;
109651 + struct device_attribute *dev_plcr_attr_regs;
109652 + struct device_attribute *dev_prs_attr_regs;
109653 + struct device_attribute *dev_fm_fpm_attr_regs;
109654 + struct device_attribute *dev_fm_kg_attr_regs;
109655 + struct device_attribute *dev_fm_kg_pe_attr_regs;
109656 + struct device_attribute *dev_attr_muram_free_size;
109657 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
109658 +
109659 +
109660 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
109661 +} t_LnxWrpFmDev;
109662 +
109663 +typedef struct {
109664 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
109665 +} t_LnxWrpFm;
109666 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
109667 +
109668 +
109669 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
109670 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
109671 +
109672 +
109673 +#if 0
109674 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
109675 +{
109676 + uint32_t schemeMask;
109677 + uint8_t i;
109678 +
109679 + if (!numSchemes)
109680 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109681 +
109682 + schemeMask = 0x80000000;
109683 + *p_BaseSchemeNum = 0xff;
109684 +
109685 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
109686 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
109687 + {
109688 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
109689 + numSchemes--;
109690 + if (*p_BaseSchemeNum==0xff)
109691 + *p_BaseSchemeNum = i;
109692 + }
109693 + else if (*p_BaseSchemeNum!=0xff)
109694 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
109695 +
109696 + if (numSchemes)
109697 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
109698 + return E_OK;
109699 +}
109700 +#endif
109701 +
109702 +void LnxWrpPCDIOCTLTypeChecking(void);
109703 +void LnxWrpPCDIOCTLEnumChecking(void);
109704 +
109705 +#endif /* __LNXWRP_FM_H__ */
109706 --- /dev/null
109707 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
109708 @@ -0,0 +1,1480 @@
109709 +/*
109710 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109711 + *
109712 + * Redistribution and use in source and binary forms, with or without
109713 + * modification, are permitted provided that the following conditions are met:
109714 + * * Redistributions of source code must retain the above copyright
109715 + * notice, this list of conditions and the following disclaimer.
109716 + * * Redistributions in binary form must reproduce the above copyright
109717 + * notice, this list of conditions and the following disclaimer in the
109718 + * documentation and/or other materials provided with the distribution.
109719 + * * Neither the name of Freescale Semiconductor nor the
109720 + * names of its contributors may be used to endorse or promote products
109721 + * derived from this software without specific prior written permission.
109722 + *
109723 + *
109724 + * ALTERNATIVELY, this software may be distributed under the terms of the
109725 + * GNU General Public License ("GPL") as published by the Free Software
109726 + * Foundation, either version 2 of that License or (at your option) any
109727 + * later version.
109728 + *
109729 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109730 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109731 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109732 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109733 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109734 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109735 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109736 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109737 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109738 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109739 + */
109740 +
109741 +/*
109742 + @File lnxwrp_fm_port.c
109743 +
109744 + @Description FMD wrapper - FMan port functions.
109745 +
109746 +*/
109747 +
109748 +#include <linux/version.h>
109749 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
109750 +#define MODVERSIONS
109751 +#endif
109752 +#ifdef MODVERSIONS
109753 +#include <config/modversions.h>
109754 +#endif /* MODVERSIONS */
109755 +#include <linux/kernel.h>
109756 +#include <linux/module.h>
109757 +#include <linux/of_platform.h>
109758 +#include <linux/of_address.h>
109759 +#include <linux/cdev.h>
109760 +#include <linux/slab.h>
109761 +#include <linux/spinlock.h>
109762 +#ifndef CONFIG_FMAN_ARM
109763 +#include <linux/fsl/svr.h>
109764 +#endif
109765 +#include <linux/io.h>
109766 +
109767 +#include "sprint_ext.h"
109768 +#include "fm_common.h"
109769 +#include "lnxwrp_fsl_fman.h"
109770 +#include "fm_port_ext.h"
109771 +#if (DPAA_VERSION >= 11)
109772 +#include "fm_vsp_ext.h"
109773 +#endif /* DPAA_VERSION >= 11 */
109774 +#include "fm_ioctls.h"
109775 +#include "lnxwrp_resources.h"
109776 +#include "lnxwrp_sysfs_fm_port.h"
109777 +
109778 +#define __ERR_MODULE__ MODULE_FM
109779 +
109780 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
109781 +
109782 +/* TODO: duplicated, see lnxwrp_fm.c */
109783 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
109784 +do {\
109785 + if (i < max) {\
109786 + p_Entry = &p_Entrys[i];\
109787 + p_Entry->p_Function = _func;\
109788 + _param\
109789 + i++;\
109790 + } else {\
109791 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
109792 + ("Number of advanced-configuration entries exceeded"));\
109793 + } \
109794 +} while (0)
109795 +
109796 +#ifndef CONFIG_FMAN_ARM
109797 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
109798 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
109799 +#endif
109800 +
109801 +static volatile int hcFrmRcv/* = 0 */;
109802 +static spinlock_t lock;
109803 +
109804 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
109805 + struct qman_fq *fq,
109806 + const struct qm_dqrr_entry
109807 + *dq)
109808 +{
109809 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
109810 + unsigned long flags;
109811 +
109812 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
109813 +{
109814 + /* extract the HC frame address */
109815 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
109816 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
109817 + int i;
109818 +
109819 + /* 32b byteswap of all data in the HC Frame */
109820 + for(i = 0; i < hcf_l / 4; ++i)
109821 + hcf_va[i] =
109822 + ___constant_swab32(hcf_va[i]);
109823 +}
109824 +#endif
109825 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
109826 + spin_lock_irqsave(&lock, flags);
109827 + hcFrmRcv--;
109828 + spin_unlock_irqrestore(&lock, flags);
109829 +
109830 + return qman_cb_dqrr_consume;
109831 +}
109832 +
109833 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
109834 + struct qman_fq *fq,
109835 + const struct qm_dqrr_entry *dq)
109836 +{
109837 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
109838 + __func__);
109839 + return qman_cb_dqrr_consume;
109840 +}
109841 +
109842 +static void qm_err_cb(struct qman_portal *portal,
109843 + struct qman_fq *fq, const struct qm_mr_entry *msg)
109844 +{
109845 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
109846 + __func__);
109847 +}
109848 +
109849 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
109850 + uint32_t fqid,
109851 + uint32_t flags, uint16_t channel, uint8_t wq)
109852 +{
109853 + int _errno;
109854 + struct qman_fq *fq = NULL;
109855 + t_FmTestFq *p_FmtFq;
109856 + struct qm_mcc_initfq initfq;
109857 +
109858 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
109859 + if (!p_FmtFq) {
109860 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
109861 + return NULL;
109862 + }
109863 +
109864 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
109865 + ? qm_tx_conf_dqrr_cb
109866 + : qm_tx_dqrr_cb);
109867 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
109868 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
109869 + /* qm_err_cb wrongly called when the FQ is parked */
109870 + p_FmtFq->fq_base.cb.fqs = NULL;
109871 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
109872 + if (fqid == 0) {
109873 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
109874 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
109875 + } else {
109876 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
109877 + }
109878 +
109879 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
109880 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
109881 + XX_Free(p_FmtFq);
109882 + return NULL;
109883 + }
109884 + fq = &p_FmtFq->fq_base;
109885 +
109886 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
109887 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
109888 + initfq.fqd.dest.channel = channel;
109889 + initfq.fqd.dest.wq = wq;
109890 +
109891 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
109892 + if (unlikely(_errno < 0)) {
109893 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
109894 + ("FQ obj - qman_init_fq!!!"));
109895 + qman_destroy_fq(fq, 0);
109896 + XX_Free(p_FmtFq);
109897 + return NULL;
109898 + }
109899 + }
109900 +
109901 + DBG(TRACE,
109902 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
109903 + flags, channel, wq));
109904 +
109905 + return fq;
109906 +}
109907 +
109908 +static void FqFree(struct qman_fq *fq)
109909 +{
109910 + int _errno;
109911 +
109912 + _errno = qman_retire_fq(fq, NULL);
109913 + if (unlikely(_errno < 0))
109914 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
109915 +
109916 + _errno = qman_oos_fq(fq);
109917 + if (unlikely(_errno < 0))
109918 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
109919 +
109920 + qman_destroy_fq(fq, 0);
109921 + XX_Free((t_FmTestFq *) fq);
109922 +}
109923 +
109924 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
109925 +{
109926 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
109927 + int _errno, timeout = 1000000;
109928 + unsigned long flags;
109929 +
109930 + ASSERT_COND(p_LnxWrpFmDev);
109931 +
109932 + spin_lock_irqsave(&lock, flags);
109933 + hcFrmRcv++;
109934 + spin_unlock_irqrestore(&lock, flags);
109935 +
109936 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
109937 +{
109938 + /* extract the HC frame address */
109939 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
109940 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
109941 + int i;
109942 +
109943 + /* 32b byteswap of all data in the HC Frame */
109944 + for(i = 0; i < hcf_l / 4; ++i)
109945 + hcf_va[i] =
109946 + ___constant_swab32(hcf_va[i]);
109947 +}
109948 +#endif
109949 +
109950 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
109951 + 0);
109952 + if (_errno)
109953 + RETURN_ERROR(MINOR, E_INVALID_STATE,
109954 + ("qman_enqueue() failed"));
109955 +
109956 + while (hcFrmRcv && --timeout) {
109957 + udelay(1);
109958 + cpu_relax();
109959 + }
109960 + if (timeout == 0) {
109961 + dump_stack();
109962 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
109963 + ("timeout waiting for Tx confirmation"));
109964 + return E_WRITE_FAILED;
109965 + }
109966 +
109967 + return E_OK;
109968 +}
109969 +
109970 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
109971 + *of_dev)
109972 +{
109973 + t_LnxWrpFmDev *p_LnxWrpFmDev;
109974 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
109975 + struct device_node *fm_node, *port_node;
109976 + struct resource res;
109977 + const uint32_t *uint32_prop;
109978 + int _errno = 0, lenp;
109979 + uint32_t tmp_prop;
109980 +
109981 +#ifdef CONFIG_FMAN_P1023
109982 + static unsigned char have_oh_port/* = 0 */;
109983 +#endif
109984 +
109985 + port_node = of_node_get(of_dev->dev.of_node);
109986 +
109987 + /* Get the FM node */
109988 + fm_node = of_get_parent(port_node);
109989 + if (unlikely(fm_node == NULL)) {
109990 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
109991 + ("of_get_parent() = %d", _errno));
109992 + return NULL;
109993 + }
109994 +
109995 + p_LnxWrpFmDev =
109996 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
109997 + of_node_put(fm_node);
109998 +
109999 + /* if fm_probe() failed, no point in going further with port probing */
110000 + if (p_LnxWrpFmDev == NULL)
110001 + return NULL;
110002 +
110003 + uint32_prop =
110004 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
110005 + if (unlikely(uint32_prop == NULL)) {
110006 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110007 + ("of_get_property(%s, cell-index) failed",
110008 + port_node->full_name));
110009 + return NULL;
110010 + }
110011 + tmp_prop = be32_to_cpu(*uint32_prop);
110012 + if (WARN_ON(lenp != sizeof(uint32_t)))
110013 + return NULL;
110014 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) {
110015 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
110016 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110017 + ("of_get_property(%s, cell-index) failed",
110018 + port_node->full_name));
110019 + return NULL;
110020 + }
110021 +
110022 +#ifdef CONFIG_FMAN_P1023
110023 + /* Beware, this can be done when there is only
110024 + one FMan to be initialized */
110025 + if (!have_oh_port) {
110026 + have_oh_port = 1; /* first OP/HC port
110027 + is used for host command */
110028 +#else
110029 + /* Here it is hardcoded the use of the OH port 1
110030 + (with cell-index 0) */
110031 + if (tmp_prop == 0) {
110032 +#endif
110033 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110034 + p_LnxWrpFmPortDev->id = 0;
110035 + /*
110036 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
110037 + p_LnxWrpFmPortDev->id = *uint32_prop;
110038 + */
110039 + p_LnxWrpFmPortDev->settings.param.portType =
110040 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
110041 + } else {
110042 + p_LnxWrpFmPortDev =
110043 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
110044 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
110045 + p_LnxWrpFmPortDev->settings.param.portType =
110046 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
110047 + }
110048 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
110049 +
110050 + uint32_prop =
110051 + (uint32_t *) of_get_property(port_node,
110052 + "fsl,qman-channel-id",
110053 + &lenp);
110054 + if (uint32_prop == NULL) {
110055 + /*
110056 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
110057 + */
110058 + XX_Print("FM warning: missing fsl,qman-channel-id"
110059 + " for OH port.\n");
110060 + return NULL;
110061 + }
110062 + tmp_prop = be32_to_cpu(*uint32_prop);
110063 + if (WARN_ON(lenp != sizeof(uint32_t)))
110064 + return NULL;
110065 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110066 +
110067 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110068 + qmChannel = p_LnxWrpFmPortDev->txCh;
110069 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
110070 + tmp_prop -= 0x28;
110071 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
110072 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110073 + ("of_get_property(%s, cell-index) failed",
110074 + port_node->full_name));
110075 + return NULL;
110076 + }
110077 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110078 +
110079 + p_LnxWrpFmPortDev->id = tmp_prop;
110080 + p_LnxWrpFmPortDev->settings.param.portId =
110081 + p_LnxWrpFmPortDev->id;
110082 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
110083 +
110084 + uint32_prop = (uint32_t *) of_get_property(port_node,
110085 + "fsl,qman-channel-id", &lenp);
110086 + if (uint32_prop == NULL) {
110087 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110088 + ("missing fsl,qman-channel-id"));
110089 + return NULL;
110090 + }
110091 + tmp_prop = be32_to_cpu(*uint32_prop);
110092 + if (WARN_ON(lenp != sizeof(uint32_t)))
110093 + return NULL;
110094 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110095 + p_LnxWrpFmPortDev->
110096 + settings.param.specificParams.nonRxParams.qmChannel =
110097 + p_LnxWrpFmPortDev->txCh;
110098 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
110099 + tmp_prop -= 0x30;
110100 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
110101 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110102 + ("of_get_property(%s, cell-index) failed",
110103 + port_node->full_name));
110104 + return NULL;
110105 + }
110106 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
110107 + FM_MAX_NUM_OF_1G_TX_PORTS];
110108 +#ifndef CONFIG_FMAN_ARM
110109 + if (IS_T1023_T1024)
110110 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop];
110111 +#endif
110112 +
110113 + p_LnxWrpFmPortDev->id = tmp_prop;
110114 + p_LnxWrpFmPortDev->settings.param.portId =
110115 + p_LnxWrpFmPortDev->id;
110116 + p_LnxWrpFmPortDev->settings.param.portType =
110117 + e_FM_PORT_TYPE_TX_10G;
110118 + uint32_prop = (uint32_t *) of_get_property(port_node,
110119 + "fsl,qman-channel-id", &lenp);
110120 + if (uint32_prop == NULL) {
110121 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110122 + ("missing fsl,qman-channel-id"));
110123 + return NULL;
110124 + }
110125 + tmp_prop = be32_to_cpu(*uint32_prop);
110126 + if (WARN_ON(lenp != sizeof(uint32_t)))
110127 + return NULL;
110128 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110129 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110130 + qmChannel = p_LnxWrpFmPortDev->txCh;
110131 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
110132 + tmp_prop -= 0x08;
110133 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
110134 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110135 + ("of_get_property(%s, cell-index) failed",
110136 + port_node->full_name));
110137 + return NULL;
110138 + }
110139 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110140 +
110141 + p_LnxWrpFmPortDev->id = tmp_prop;
110142 + p_LnxWrpFmPortDev->settings.param.portId =
110143 + p_LnxWrpFmPortDev->id;
110144 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
110145 + if (p_LnxWrpFmDev->pcdActive)
110146 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110147 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
110148 + tmp_prop -= 0x10;
110149 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
110150 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110151 + ("of_get_property(%s, cell-index) failed",
110152 + port_node->full_name));
110153 + return NULL;
110154 + }
110155 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
110156 + FM_MAX_NUM_OF_1G_RX_PORTS];
110157 +
110158 +#ifndef CONFIG_FMAN_ARM
110159 + if (IS_T1023_T1024)
110160 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop];
110161 +#endif
110162 +
110163 + p_LnxWrpFmPortDev->id = tmp_prop;
110164 + p_LnxWrpFmPortDev->settings.param.portId =
110165 + p_LnxWrpFmPortDev->id;
110166 + p_LnxWrpFmPortDev->settings.param.portType =
110167 + e_FM_PORT_TYPE_RX_10G;
110168 + if (p_LnxWrpFmDev->pcdActive)
110169 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110170 + } else {
110171 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
110172 + return NULL;
110173 + }
110174 +
110175 + _errno = of_address_to_resource(port_node, 0, &res);
110176 + if (unlikely(_errno < 0)) {
110177 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110178 + ("of_address_to_resource() = %d", _errno));
110179 + return NULL;
110180 + }
110181 +
110182 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
110183 + p_LnxWrpFmPortDev->baseAddr = 0;
110184 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
110185 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
110186 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
110187 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
110188 +
110189 + of_node_put(port_node);
110190 +
110191 + p_LnxWrpFmPortDev->active = TRUE;
110192 +
110193 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110194 + /* for performance mode no OH port available. */
110195 + if (p_LnxWrpFmPortDev->settings.param.portType ==
110196 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110197 + p_LnxWrpFmPortDev->active = FALSE;
110198 +#endif
110199 +
110200 + return p_LnxWrpFmPortDev;
110201 +}
110202 +
110203 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
110204 + e_FmPortType portType,
110205 + uint8_t portId)
110206 +{
110207 + struct device_node *port_node;
110208 + const uint32_t *uint32_prop;
110209 + int lenp;
110210 + char *portTypeString;
110211 + uint32_t tmp_prop;
110212 +
110213 + switch(portType) {
110214 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
110215 + portTypeString = "fsl,fman-port-op-extended-args";
110216 + break;
110217 + case e_FM_PORT_TYPE_TX:
110218 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
110219 + break;
110220 + case e_FM_PORT_TYPE_TX_10G:
110221 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
110222 + break;
110223 + case e_FM_PORT_TYPE_RX:
110224 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
110225 + break;
110226 + case e_FM_PORT_TYPE_RX_10G:
110227 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
110228 + break;
110229 + default:
110230 + return NULL;
110231 + }
110232 +
110233 + for_each_child_of_node(fm_node, port_node) {
110234 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
110235 + if (unlikely(uint32_prop == NULL)) {
110236 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110237 + ("of_get_property(%s, cell-index) failed",
110238 + port_node->full_name));
110239 + return NULL;
110240 + }
110241 + tmp_prop = be32_to_cpu(*uint32_prop);
110242 + if (WARN_ON(lenp != sizeof(uint32_t)))
110243 + return NULL;
110244 + if ((portId == tmp_prop) &&
110245 + (of_device_is_compatible(port_node, portTypeString))) {
110246 + return port_node;
110247 + }
110248 + }
110249 +
110250 + return NULL;
110251 +}
110252 +
110253 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110254 +{
110255 + struct device_node *fm_node, *port_node;
110256 + t_Error err;
110257 + t_FmPortRsrc portRsrc;
110258 + const uint32_t *uint32_prop;
110259 + /*const char *str_prop;*/
110260 + int lenp;
110261 +#ifdef CONFIG_FMAN_PFC
110262 + uint8_t i, id, num_pools;
110263 + t_FmBufPoolDepletion poolDepletion;
110264 +
110265 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
110266 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
110267 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
110268 + poolDepletion.singlePoolModeEnable = true;
110269 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110270 + extBufPools.numOfPoolsUsed;
110271 + for (i = 0; i < num_pools; i++) {
110272 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110273 + extBufPools.extBufPool[i].id;
110274 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
110275 + }
110276 +
110277 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
110278 + poolDepletion.pfcPrioritiesEn[i] = true;
110279 +
110280 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
110281 + &poolDepletion);
110282 + if (err != E_OK)
110283 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
110284 + }
110285 +#endif
110286 +
110287 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110288 + if (!fm_node) /* no advance parameters for FMan */
110289 + return E_OK;
110290 +
110291 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110292 + p_LnxWrpFmPortDev->settings.param.portType,
110293 + p_LnxWrpFmPortDev->settings.param.portId);
110294 + if (!port_node) /* no advance parameters for FMan-Port */
110295 + return E_OK;
110296 +
110297 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
110298 + if (uint32_prop) {
110299 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110300 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110301 +
110302 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110303 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110304 +
110305 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
110306 + &portRsrc)) != E_OK)
110307 + RETURN_ERROR(MINOR, err, NO_MSG);
110308 + }
110309 +
110310 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
110311 + if (uint32_prop) {
110312 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110313 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110314 +
110315 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110316 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110317 +
110318 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
110319 + &portRsrc)) != E_OK)
110320 + RETURN_ERROR(MINOR, err, NO_MSG);
110321 + }
110322 +
110323 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
110324 + if (uint32_prop) {
110325 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110326 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110327 +
110328 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110329 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110330 +
110331 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
110332 + &portRsrc)) != E_OK)
110333 + RETURN_ERROR(MINOR, err, NO_MSG);
110334 + }
110335 +
110336 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
110337 + if (uint32_prop) {
110338 + if (WARN_ON(lenp != sizeof(uint32_t)))
110339 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110340 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
110341 + be32_to_cpu(uint32_prop[0]))) != E_OK)
110342 + RETURN_ERROR(MINOR, err, NO_MSG);
110343 + }
110344 +
110345 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
110346 + &lenp);
110347 + if (uint32_prop) {
110348 +
110349 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
110350 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110351 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
110352 + e_FM_PORT_TYPE_RX) &&
110353 + (p_LnxWrpFmPortDev->settings.param.portType !=
110354 + e_FM_PORT_TYPE_RX_10G))
110355 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
110356 + ("Auto Response is an Rx port atribute."));
110357 +
110358 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
110359 +
110360 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
110361 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110362 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
110363 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110364 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
110365 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110366 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
110367 + (uint16_t)be32_to_cpu(uint32_prop[3]);
110368 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
110369 + (uint16_t)be32_to_cpu(uint32_prop[4]);
110370 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
110371 + (uint16_t)be32_to_cpu(uint32_prop[5]);
110372 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
110373 + (uint16_t)be32_to_cpu(uint32_prop[6]);
110374 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
110375 + (uint16_t)be32_to_cpu(uint32_prop[7]);
110376 +
110377 + uint32_prop = (uint32_t *)of_get_property(port_node,
110378 + "ar-filters-sizes", &lenp);
110379 + if (uint32_prop) {
110380 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
110381 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110382 +
110383 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
110384 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110385 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
110386 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110387 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
110388 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110389 + }
110390 +
110391 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
110392 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
110393 + RETURN_ERROR(MINOR, err, NO_MSG);
110394 + }
110395 +
110396 + of_node_put(port_node);
110397 + of_node_put(fm_node);
110398 +
110399 + return E_OK;
110400 +}
110401 +
110402 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110403 +{
110404 + struct device_node *fm_node, *port_node;
110405 + t_Error err;
110406 + const uint32_t *uint32_prop;
110407 + /*const char *str_prop;*/
110408 + int lenp;
110409 +
110410 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110411 + if (!fm_node) /* no advance parameters for FMan */
110412 + return E_OK;
110413 +
110414 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110415 + p_LnxWrpFmPortDev->settings.param.portType,
110416 + p_LnxWrpFmPortDev->settings.param.portId);
110417 + if (!port_node) /* no advance parameters for FMan-Port */
110418 + return E_OK;
110419 +
110420 +#if (DPAA_VERSION >= 11)
110421 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
110422 + if (uint32_prop) {
110423 + t_FmPortVSPAllocParams portVSPAllocParams;
110424 + t_FmVspParams fmVspParams;
110425 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110426 + uint8_t portId;
110427 +
110428 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
110429 +
110430 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110431 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110432 +
110433 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
110434 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
110435 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110436 + p_LnxWrpFmPortDev->settings.frag_enabled))
110437 + return E_OK;
110438 +
110439 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
110440 + memset(&fmVspParams, 0, sizeof(fmVspParams));
110441 +
110442 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
110443 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
110444 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
110445 +
110446 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
110447 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
110448 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
110449 +
110450 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110451 + {
110452 + portId = fmVspParams.portParams.portId;
110453 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
110454 +#ifndef CONFIG_FMAN_ARM
110455 + if (!(IS_T1023_T1024))
110456 +#endif
110457 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
110458 + }
110459 + portVSPAllocParams.h_FmTxPort =
110460 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
110461 + fmVspParams.liodnOffset =
110462 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
110463 + memcpy(&fmVspParams.extBufPools,
110464 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
110465 + sizeof(t_FmExtPools));
110466 + }
110467 + else
110468 + {
110469 + memcpy(&fmVspParams.extBufPools,
110470 + &p_LnxWrpFmPortDev->opExtPools,
110471 + sizeof(t_FmExtPools));
110472 + }
110473 +
110474 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
110475 + &portVSPAllocParams)) != E_OK)
110476 + RETURN_ERROR(MINOR, err, NO_MSG);
110477 +
110478 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
110479 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110480 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
110481 + return E_OK;
110482 +
110483 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
110484 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
110485 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
110486 +
110487 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
110488 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
110489 + RETURN_ERROR(MINOR, err, NO_MSG);
110490 +
110491 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
110492 + RETURN_ERROR(MINOR, err, NO_MSG);
110493 + }
110494 +#else
110495 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
110496 +#endif /* (DPAA_VERSION >= 11) */
110497 +
110498 + of_node_put(port_node);
110499 + of_node_put(fm_node);
110500 +
110501 + return E_OK;
110502 +}
110503 +
110504 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110505 +{
110506 + t_LnxWrpFmDev *p_LnxWrpFmDev =
110507 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
110508 + struct resource *dev_res;
110509 +
110510 + if (!p_LnxWrpFmPortDev->active)
110511 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110512 + ("FM port not configured!!!"));
110513 +
110514 + dev_res =
110515 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
110516 + p_LnxWrpFmPortDev->phys_baseAddr,
110517 + p_LnxWrpFmPortDev->memSize,
110518 + "fman-port-hc");
110519 + if (unlikely(dev_res == NULL))
110520 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110521 + ("__devm_request_region() failed"));
110522 + p_LnxWrpFmPortDev->baseAddr =
110523 + PTR_TO_UINT(devm_ioremap
110524 + (p_LnxWrpFmDev->dev,
110525 + p_LnxWrpFmPortDev->phys_baseAddr,
110526 + p_LnxWrpFmPortDev->memSize));
110527 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
110528 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
110529 + ("devm_ioremap() failed"));
110530 +
110531 + p_LnxWrpFmPortDev->settings.param.baseAddr =
110532 + p_LnxWrpFmPortDev->baseAddr;
110533 +
110534 + return E_OK;
110535 +}
110536 +
110537 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110538 +{
110539 +#define MY_ADV_CONFIG_CHECK_END \
110540 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
110541 + ("Advanced configuration routine"));\
110542 + if (errCode != E_OK)\
110543 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
110544 + }
110545 +
110546 + int i = 0;
110547 +
110548 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
110549 + return E_INVALID_STATE;
110550 +
110551 + p_LnxWrpFmPortDev->h_Dev =
110552 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
110553 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
110554 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
110555 +
110556 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
110557 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110558 + e_FM_PORT_TYPE_TX_10G)
110559 + || (p_LnxWrpFmPortDev->settings.param.portType ==
110560 + e_FM_PORT_TYPE_TX)) {
110561 + t_Error errCode = E_OK;
110562 + errCode =
110563 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
110564 + TRUE);
110565 + if (errCode != E_OK)
110566 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110567 + errCode =
110568 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
110569 + e_FM_PORT_DEQ_FULL_PREFETCH);
110570 + if (errCode
110571 + != E_OK)
110572 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110573 + }
110574 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
110575 +
110576 +#ifndef CONFIG_FMAN_ARM
110577 +#ifdef FM_BCB_ERRATA_BMI_SW001
110578 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
110579 +#define SVR_SECURITY_MASK 0x00080000
110580 +#define SVR_PERSONALITY_MASK 0x0000FF00
110581 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
110582 +#define SVR_B4860_REV1_VALUE 0x86800010
110583 +
110584 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110585 + e_FM_PORT_TYPE_RX_10G) ||
110586 + (p_LnxWrpFmPortDev->settings.param.portType ==
110587 + e_FM_PORT_TYPE_RX)) {
110588 + unsigned int svr;
110589 +
110590 + svr = mfspr(SPRN_SVR);
110591 +
110592 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
110593 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
110594 + }
110595 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
110596 +#endif /* CONFIG_FMAN_ARM */
110597 +/* Call the driver's advanced configuration routines, if requested:
110598 + Compare the function pointer of each entry to the available routines,
110599 + and invoke the matching routine with proper casting of arguments. */
110600 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
110601 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
110602 +
110603 +/* TODO: Change this MACRO */
110604 + ADV_CONFIG_CHECK_START(
110605 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
110606 +
110607 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
110608 + FM_PORT_ConfigBufferPrefixContent,
110609 + NCSW_PARAMS(1,
110610 + (t_FmBufferPrefixContent *)))
110611 +
110612 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110613 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110614 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
110615 +
110616 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
110617 + FM_PORT_ConfigExtBufPools,
110618 + NCSW_PARAMS(1, (t_FmExtPools *)))
110619 +
110620 + /* this define contains an else */
110621 + MY_ADV_CONFIG_CHECK_END
110622 + }
110623 +
110624 + /* Advance to next advanced configuration entry */
110625 + i++;
110626 + }
110627 +
110628 +
110629 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
110630 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
110631 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
110632 + FM_PORT_FRM_ERR_IPR_NCSP |
110633 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
110634 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110635 + }
110636 +
110637 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
110638 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110639 +
110640 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
110641 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110642 +
110643 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
110644 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110645 +
110646 +/* FMan Fifo sizes behind the scene":
110647 + * Using the following formulae (*), under a set of simplifying assumptions (.):
110648 + * . all ports are configured in Normal Mode (rather than Independent Mode)
110649 + * . the DPAA Eth driver allocates buffers of size:
110650 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
110651 + * + DPA_HASH_RESULTS_SIZE, i.e.:
110652 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
110653 + * MAXFRM + 66
110654 + * . excessive buffer pools not accounted for
110655 + *
110656 + * * for Rx ports on P4080:
110657 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
110658 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
110659 + * add up to 256 to the above
110660 + *
110661 + * * for Rx ports on P1023:
110662 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
110663 + * if at least 2 bpools are configured
110664 + * . IFSZ = 8 * 256, if only a single bpool is configured
110665 + *
110666 + * * for Tx ports:
110667 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
110668 + * + FMBM_TFP[DPDE] * 256, i.e.:
110669 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
110670 + *
110671 + * * for OH ports on P4080:
110672 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
110673 + * * for OH ports on P1023:
110674 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
110675 + * * for both P4080 and P1023:
110676 + * . (conservative decisions, assuming that BMI must bring the entire
110677 + * frame, not only the frame header)
110678 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
110679 + * add up to 256 to the above
110680 + *
110681 + * . for P4080/P5020/P3041/P2040, DPDE is:
110682 + * > 0 or 1, for 1Gb ports, HW default: 0
110683 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
110684 + * . for P1023, DPDE should be 1
110685 + *
110686 + * . for P1023, MXT is in range (0..31)
110687 + * . for P4080, MXT is in range (0..63)
110688 + *
110689 + */
110690 +#if 0
110691 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
110692 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
110693 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
110694 +#endif
110695 + return E_OK;
110696 +}
110697 +
110698 +void fm_set_rx_port_params(struct fm_port *port,
110699 + struct fm_port_params *params)
110700 +{
110701 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
110702 + int i;
110703 +
110704 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
110705 + params->errq;
110706 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
110707 + params->defq;
110708 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
110709 + numOfPoolsUsed = params->num_pools;
110710 + for (i = 0; i < params->num_pools; i++) {
110711 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110712 + extBufPools.extBufPool[i].id =
110713 + params->pool_param[i].id;
110714 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110715 + extBufPools.extBufPool[i].size =
110716 + params->pool_param[i].size;
110717 + }
110718 +
110719 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
110720 + params->priv_data_size;
110721 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
110722 + params->parse_results;
110723 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
110724 + params->hash_results;
110725 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
110726 + params->time_stamp;
110727 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
110728 + params->data_align;
110729 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
110730 + params->manip_extra_space;
110731 +
110732 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
110733 + FM_MAX_NUM_OF_ADV_SETTINGS)
110734 +
110735 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
110736 + ARGS(1,
110737 + (&p_LnxWrpFmPortDev->
110738 + buffPrefixContent)));
110739 +
110740 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
110741 +}
110742 +EXPORT_SYMBOL(fm_set_rx_port_params);
110743 +
110744 +/* this function is called from oh_probe as well, thus it contains oh port
110745 + * specific parameters (make sure everything is checked) */
110746 +void fm_set_tx_port_params(struct fm_port *port,
110747 + struct fm_port_params *params)
110748 +{
110749 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
110750 +
110751 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
110752 + params->errq;
110753 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110754 + dfltFqid = params->defq;
110755 +
110756 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
110757 + params->priv_data_size;
110758 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
110759 + params->parse_results;
110760 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
110761 + params->hash_results;
110762 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
110763 + params->time_stamp;
110764 + p_LnxWrpFmPortDev->settings.frag_enabled =
110765 + params->frag_enable;
110766 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
110767 + params->data_align;
110768 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
110769 + params->manip_extra_space;
110770 +
110771 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
110772 + FM_MAX_NUM_OF_ADV_SETTINGS)
110773 +
110774 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
110775 + ARGS(1,
110776 + (&p_LnxWrpFmPortDev->
110777 + buffPrefixContent)));
110778 +
110779 + /* oh port specific parameter (for fragmentation only) */
110780 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110781 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110782 + params->num_pools) {
110783 + int i;
110784 +
110785 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
110786 + for (i = 0; i < params->num_pools; i++) {
110787 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
110788 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
110789 + }
110790 +
110791 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
110792 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
110793 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
110794 + }
110795 +
110796 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
110797 +}
110798 +EXPORT_SYMBOL(fm_set_tx_port_params);
110799 +
110800 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
110801 + t_Handle h_fm_mac,
110802 + int mac_id)
110803 +{
110804 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
110805 +
110806 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
110807 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
110808 +}
110809 +EXPORT_SYMBOL(fm_mac_set_handle);
110810 +
110811 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
110812 + e_FmPcdExceptions exception)
110813 +{
110814 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
110815 +
110816 + ASSERT_COND(p_LnxWrpFmDev);
110817 +
110818 + DBG(INFO, ("got fm-pcd exception %d", exception));
110819 +
110820 + /* do nothing */
110821 + UNUSED(exception);
110822 +}
110823 +
110824 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
110825 + e_FmPcdExceptions exception,
110826 + uint16_t index)
110827 +{
110828 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
110829 +
110830 + ASSERT_COND(p_LnxWrpFmDev);
110831 +
110832 + DBG(INFO,
110833 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
110834 +
110835 + /* do nothing */
110836 + UNUSED(exception);
110837 + UNUSED(index);
110838 +}
110839 +
110840 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
110841 +{
110842 + spin_lock_init(&lock);
110843 +
110844 + if (p_LnxWrpFmDev->pcdActive) {
110845 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110846 + t_FmPcdParams fmPcdParams;
110847 + t_Error err;
110848 +
110849 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
110850 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
110851 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
110852 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
110853 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
110854 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
110855 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
110856 +
110857 +#ifndef CONFIG_GUEST_PARTITION
110858 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
110859 + if (fmPcdParams.kgSupport)
110860 + fmPcdParams.f_ExceptionId =
110861 + LnxwrpFmPcdDevIndexedExceptionsCb;
110862 + fmPcdParams.h_App = p_LnxWrpFmDev;
110863 +#endif /* !CONFIG_GUEST_PARTITION */
110864 +
110865 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
110866 + fmPcdParams.numOfSchemes = 0;
110867 + fmPcdParams.numOfClsPlanEntries = 0;
110868 + fmPcdParams.partitionId = 0;
110869 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
110870 + fmPcdParams.useHostCommand = TRUE;
110871 +
110872 + p_LnxWrpFmDev->hc_tx_fq =
110873 + FqAlloc(p_LnxWrpFmDev,
110874 + 0,
110875 + QMAN_FQ_FLAG_TO_DCPORTAL,
110876 + p_LnxWrpFmPortDev->txCh, 0);
110877 + if (!p_LnxWrpFmDev->hc_tx_fq)
110878 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
110879 + ("Frame queue allocation failed..."));
110880 +
110881 + p_LnxWrpFmDev->hc_tx_conf_fq =
110882 + FqAlloc(p_LnxWrpFmDev,
110883 + 0,
110884 + QMAN_FQ_FLAG_NO_ENQUEUE,
110885 + p_LnxWrpFmDev->hcCh, 1);
110886 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
110887 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
110888 + ("Frame queue allocation failed..."));
110889 +
110890 + p_LnxWrpFmDev->hc_tx_err_fq =
110891 + FqAlloc(p_LnxWrpFmDev,
110892 + 0,
110893 + QMAN_FQ_FLAG_NO_ENQUEUE,
110894 + p_LnxWrpFmDev->hcCh, 2);
110895 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
110896 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
110897 + ("Frame queue allocation failed..."));
110898 +
110899 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
110900 + fmPcdParams.hc.portId =
110901 + p_LnxWrpFmPortDev->settings.param.portId;
110902 + fmPcdParams.hc.liodnBase =
110903 + p_LnxWrpFmPortDev->settings.param.liodnBase;
110904 + fmPcdParams.hc.errFqid =
110905 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
110906 + fmPcdParams.hc.confFqid =
110907 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
110908 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
110909 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
110910 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
110911 +
110912 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
110913 + if (!p_LnxWrpFmDev->h_PcdDev)
110914 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
110915 +
110916 + err =
110917 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
110918 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
110919 + if (err != E_OK)
110920 + RETURN_ERROR(MAJOR, err, NO_MSG);
110921 +
110922 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
110923 + if (err != E_OK)
110924 + RETURN_ERROR(MAJOR, err, NO_MSG);
110925 +
110926 + if (p_LnxWrpFmDev->err_irq == 0) {
110927 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110928 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
110929 + FALSE);
110930 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110931 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
110932 + FALSE);
110933 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110934 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
110935 + FALSE);
110936 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110937 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
110938 + FALSE);
110939 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110940 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
110941 + FALSE);
110942 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110943 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
110944 + FALSE);
110945 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110946 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
110947 + FALSE);
110948 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
110949 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
110950 + FALSE);
110951 + }
110952 + }
110953 +
110954 + return E_OK;
110955 +}
110956 +
110957 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
110958 +{
110959 +
110960 + if (p_LnxWrpFmDev->h_PcdDev)
110961 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
110962 +
110963 + if (p_LnxWrpFmDev->hc_tx_err_fq)
110964 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
110965 +
110966 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
110967 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
110968 +
110969 + if (p_LnxWrpFmDev->hc_tx_fq)
110970 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
110971 +}
110972 +
110973 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110974 +{
110975 + t_LnxWrpFmDev *p_LnxWrpFmDev =
110976 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
110977 +
110978 + if (!p_LnxWrpFmPortDev->active)
110979 + return;
110980 +
110981 + if (p_LnxWrpFmPortDev->h_Dev)
110982 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
110983 +
110984 + devm_iounmap(p_LnxWrpFmDev->dev,
110985 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
110986 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
110987 + p_LnxWrpFmPortDev->phys_baseAddr,
110988 + p_LnxWrpFmPortDev->memSize);
110989 +}
110990 +
110991 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
110992 +{
110993 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
110994 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110995 + struct device *dev;
110996 +
110997 + dev = &of_dev->dev;
110998 +
110999 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
111000 + if (p_LnxWrpFmPortDev == NULL)
111001 + return -EIO;
111002 + /* Port can be inactive, thus will not be probed:
111003 + - in performance mode, OH ports are disabled
111004 + ...
111005 + */
111006 + if (!p_LnxWrpFmPortDev->active)
111007 + return 0;
111008 +
111009 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
111010 + return -EIO;
111011 +
111012 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
111013 +
111014 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111015 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
111016 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111017 +
111018 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111019 +
111020 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
111021 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111022 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111023 + p_LnxWrpFmPortDev->minor =
111024 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
111025 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111026 + e_FM_PORT_TYPE_RX_10G) {
111027 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111028 + p_LnxWrpFmDev->name,
111029 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
111030 + p_LnxWrpFmPortDev->minor =
111031 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
111032 + DEV_FM_RX_PORTS_MINOR_BASE;
111033 +#ifndef CONFIG_FMAN_ARM
111034 + if (IS_T1023_T1024) {
111035 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111036 + p_LnxWrpFmDev->name,
111037 + p_LnxWrpFmPortDev->id);
111038 + p_LnxWrpFmPortDev->minor =
111039 + p_LnxWrpFmPortDev->id +
111040 + DEV_FM_RX_PORTS_MINOR_BASE;
111041 + }
111042 +#endif
111043 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111044 + e_FM_PORT_TYPE_TX) {
111045 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111046 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111047 + p_LnxWrpFmPortDev->minor =
111048 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
111049 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111050 + e_FM_PORT_TYPE_TX_10G) {
111051 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111052 + p_LnxWrpFmDev->name,
111053 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
111054 + p_LnxWrpFmPortDev->minor =
111055 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
111056 + DEV_FM_TX_PORTS_MINOR_BASE;
111057 +#ifndef CONFIG_FMAN_ARM
111058 + if (IS_T1023_T1024) {
111059 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111060 + p_LnxWrpFmDev->name,
111061 + p_LnxWrpFmPortDev->id);
111062 + p_LnxWrpFmPortDev->minor =
111063 + p_LnxWrpFmPortDev->id +
111064 + DEV_FM_TX_PORTS_MINOR_BASE;
111065 + }
111066 +#endif
111067 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111068 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
111069 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111070 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111071 + p_LnxWrpFmPortDev->minor =
111072 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
111073 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111074 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
111075 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111076 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
111077 + p_LnxWrpFmPortDev->minor =
111078 + p_LnxWrpFmPortDev->id + 1 +
111079 + DEV_FM_OH_PORTS_MINOR_BASE;
111080 + }
111081 +
111082 + device_create(p_LnxWrpFmDev->fm_class, NULL,
111083 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
111084 + NULL, p_LnxWrpFmPortDev->name);
111085 +
111086 + /* create sysfs entries for stats and regs */
111087 +
111088 + if (fm_port_sysfs_create(dev) != 0) {
111089 + FreeFmPortDev(p_LnxWrpFmPortDev);
111090 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111091 + ("Unable to create sys entry - fm port!!!"));
111092 + return -EIO;
111093 + }
111094 +
111095 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
111096 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
111097 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
111098 +
111099 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
111100 +
111101 + return 0;
111102 +}
111103 +
111104 +static int fm_port_remove(struct platform_device *of_dev)
111105 +{
111106 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111107 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111108 + struct device *dev;
111109 +
111110 + dev = &of_dev->dev;
111111 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
111112 +
111113 + fm_port_sysfs_destroy(dev);
111114 +
111115 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111116 + device_destroy(p_LnxWrpFmDev->fm_class,
111117 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
111118 +
111119 + FreeFmPortDev(p_LnxWrpFmPortDev);
111120 +
111121 + dev_set_drvdata(dev, NULL);
111122 +
111123 + return 0;
111124 +}
111125 +
111126 +static const struct of_device_id fm_port_match[] = {
111127 + {
111128 + .compatible = "fsl,fman-port-oh"},
111129 + {
111130 + .compatible = "fsl,fman-port-1g-rx"},
111131 + {
111132 + .compatible = "fsl,fman-port-10g-rx"},
111133 + {
111134 + .compatible = "fsl,fman-port-1g-tx"},
111135 + {
111136 + .compatible = "fsl,fman-port-10g-tx"},
111137 + {}
111138 +};
111139 +
111140 +#ifndef MODULE
111141 +MODULE_DEVICE_TABLE(of, fm_port_match);
111142 +#endif /* !MODULE */
111143 +
111144 +static struct platform_driver fm_port_driver = {
111145 +
111146 + .driver = {
111147 + .name = "fsl-fman-port",
111148 + .of_match_table = fm_port_match,
111149 + .owner = THIS_MODULE,
111150 + },
111151 + .probe = fm_port_probe,
111152 + .remove = fm_port_remove
111153 +};
111154 +
111155 +
111156 +t_Error LNXWRP_FM_Port_Init(void)
111157 +{
111158 + /* Register to the DTB for basic FM port API */
111159 + if (platform_driver_register(&fm_port_driver))
111160 + return E_NO_DEVICE;
111161 +
111162 + return E_OK;
111163 +}
111164 +
111165 +void LNXWRP_FM_Port_Free(void)
111166 +{
111167 + platform_driver_unregister(&fm_port_driver);
111168 +}
111169 +
111170 +static int __init __cold fm_port_load(void)
111171 +{
111172 + if (LNXWRP_FM_Port_Init() != E_OK) {
111173 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
111174 + return -ENODEV;
111175 + }
111176 +
111177 + printk(KERN_CRIT "Freescale FM Ports module\n");
111178 +
111179 + return 0;
111180 +}
111181 +
111182 +static void __exit __cold fm_port_unload(void)
111183 +{
111184 + LNXWRP_FM_Port_Free();
111185 +}
111186 +
111187 +module_init(fm_port_load);
111188 +module_exit(fm_port_unload);
111189 --- /dev/null
111190 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111191 @@ -0,0 +1,4813 @@
111192 +/*
111193 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111194 + *
111195 + * Redistribution and use in source and binary forms, with or without
111196 + * modification, are permitted provided that the following conditions are met:
111197 + * * Redistributions of source code must retain the above copyright
111198 + * notice, this list of conditions and the following disclaimer.
111199 + * * Redistributions in binary form must reproduce the above copyright
111200 + * notice, this list of conditions and the following disclaimer in the
111201 + * documentation and/or other materials provided with the distribution.
111202 + * * Neither the name of Freescale Semiconductor nor the
111203 + * names of its contributors may be used to endorse or promote products
111204 + * derived from this software without specific prior written permission.
111205 + *
111206 + *
111207 + * ALTERNATIVELY, this software may be distributed under the terms of the
111208 + * GNU General Public License ("GPL") as published by the Free Software
111209 + * Foundation, either version 2 of that License or (at your option) any
111210 + * later version.
111211 + *
111212 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111213 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111214 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111215 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111216 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111217 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111218 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111219 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111220 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111221 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111222 + */
111223 +
111224 +/*
111225 + @File lnxwrp_ioctls_fm.c
111226 + @Author Shlomi Gridish
111227 + @Description FM Linux wrapper functions.
111228 +*/
111229 +
111230 +/* Linux Headers ------------------- */
111231 +#include <linux/version.h>
111232 +
111233 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111234 +#define MODVERSIONS
111235 +#endif
111236 +#ifdef MODVERSIONS
111237 +#include <config/modversions.h>
111238 +#endif /* MODVERSIONS */
111239 +
111240 +#include <linux/kernel.h>
111241 +#include <linux/module.h>
111242 +#include <linux/slab.h>
111243 +#include <linux/fs.h>
111244 +#include <linux/cdev.h>
111245 +#include <linux/device.h>
111246 +#include <linux/irq.h>
111247 +#include <linux/interrupt.h>
111248 +#include <linux/io.h>
111249 +#include <linux/ioport.h>
111250 +#include <linux/of_platform.h>
111251 +#include <linux/uaccess.h>
111252 +#include <asm/errno.h>
111253 +#ifndef CONFIG_FMAN_ARM
111254 +#include <sysdev/fsl_soc.h>
111255 +#include <linux/fsl/svr.h>
111256 +#endif
111257 +
111258 +#if defined(CONFIG_COMPAT)
111259 +#include <linux/compat.h>
111260 +#endif
111261 +
111262 +#include "part_ext.h"
111263 +#include "fm_ioctls.h"
111264 +#include "fm_pcd_ioctls.h"
111265 +#include "fm_port_ioctls.h"
111266 +#include "fm_vsp_ext.h"
111267 +
111268 +#ifndef CONFIG_FMAN_ARM
111269 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111270 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111271 +#endif
111272 +
111273 +#define __ERR_MODULE__ MODULE_FM
111274 +
111275 +#if defined(CONFIG_COMPAT)
111276 +#include "lnxwrp_ioctls_fm_compat.h"
111277 +#endif
111278 +
111279 +#include "lnxwrp_fm.h"
111280 +
111281 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
111282 +
111283 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
111284 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
111285 +#error Error: please synchronize IOC_ defines!
111286 +#endif
111287 +
111288 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
111289 +#error Error: please synchronize IOC_ defines!
111290 +#endif
111291 +
111292 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
111293 +#error Error: please synchronize IOC_ defines!
111294 +#endif
111295 +
111296 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
111297 +#error Error: please synchronize IOC_ defines!
111298 +#endif
111299 +
111300 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
111301 +#error Error: please synchronize IOC_ defines!
111302 +#endif
111303 +
111304 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
111305 +#error Error: please synchronize IOC_ defines!
111306 +#endif
111307 +
111308 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
111309 +#error Error: please synchronize IOC_ defines!
111310 +#endif
111311 +
111312 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
111313 +#error Error: please synchronize IOC_ defines!
111314 +#endif
111315 +
111316 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
111317 +#error Error: please synchronize IOC_ defines!
111318 +#endif
111319 +
111320 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
111321 +#error Error: please synchronize IOC_ defines!
111322 +#endif
111323 +
111324 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
111325 +#error Error: please synchronize IOC_ defines!
111326 +#endif
111327 +
111328 +#if DPAA_VERSION >= 11
111329 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
111330 +#error Error: please synchronize IOC_ defines!
111331 +#endif
111332 +#endif
111333 +
111334 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
111335 +#error Error: please synchronize IOC_ defines!
111336 +#endif
111337 +
111338 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
111339 +#error Error: please synchronize IOC_ defines!
111340 +#endif
111341 +
111342 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
111343 +#error Error: please synchronize IOC_ defines!
111344 +#endif
111345 +
111346 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
111347 +#error Error: please synchronize IOC_ defines!
111348 +#endif
111349 +
111350 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
111351 +#error Error: please synchronize IOC_ defines!
111352 +#endif
111353 +
111354 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
111355 +#error Error: please synchronize IOC_ defines!
111356 +#endif
111357 +
111358 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
111359 +#error Error: please synchronize IOC_ defines!
111360 +#endif
111361 +
111362 +/* net_ioctls.h === net_ext.h assertions */
111363 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
111364 +#error Error: please synchronize IOC_ defines!
111365 +#endif
111366 +
111367 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
111368 +#error Error: please synchronize IOC_ defines!
111369 +#endif
111370 +
111371 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
111372 +#error Error: please synchronize IOC_ defines!
111373 +#endif
111374 +
111375 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
111376 +#error Error: please synchronize IOC_ defines!
111377 +#endif
111378 +
111379 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
111380 +#error Error: please synchronize IOC_ defines!
111381 +#endif
111382 +
111383 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
111384 +#error Error: please synchronize IOC_ defines!
111385 +#endif
111386 +
111387 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
111388 +#error Error: please synchronize IOC_ defines!
111389 +#endif
111390 +
111391 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
111392 +#error Error: please synchronize IOC_ defines!
111393 +#endif
111394 +
111395 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
111396 +#error Error: please synchronize IOC_ defines!
111397 +#endif
111398 +
111399 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
111400 +#error Error: please synchronize IOC_ defines!
111401 +#endif
111402 +
111403 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
111404 +#error Error: please synchronize IOC_ defines!
111405 +#endif
111406 +
111407 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
111408 +#error Error: please synchronize IOC_ defines!
111409 +#endif
111410 +
111411 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
111412 +#error Error: please synchronize IOC_ defines!
111413 +#endif
111414 +
111415 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
111416 +#error Error: please synchronize IOC_ defines!
111417 +#endif
111418 +
111419 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
111420 +#error Error: please synchronize IOC_ defines!
111421 +#endif
111422 +
111423 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
111424 +#error Error: please synchronize IOC_ defines!
111425 +#endif
111426 +
111427 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
111428 +#error Error: please synchronize IOC_ defines!
111429 +#endif
111430 +
111431 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
111432 +#error Error: please synchronize IOC_ defines!
111433 +#endif
111434 +
111435 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
111436 +#error Error: please synchronize IOC_ defines!
111437 +#endif
111438 +
111439 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
111440 +#error Error: please synchronize IOC_ defines!
111441 +#endif
111442 +
111443 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
111444 +#error Error: please synchronize IOC_ defines!
111445 +#endif
111446 +
111447 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
111448 +#error Error: please synchronize IOC_ defines!
111449 +#endif
111450 +
111451 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
111452 +#error Error: please synchronize IOC_ defines!
111453 +#endif
111454 +
111455 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
111456 +#error Error: please synchronize IOC_ defines!
111457 +#endif
111458 +
111459 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
111460 +#error Error: please synchronize IOC_ defines!
111461 +#endif
111462 +
111463 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
111464 +#warning Error: please synchronize IOC_ defines!
111465 +#endif
111466 +
111467 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
111468 +#error Error: please synchronize IOC_ defines!
111469 +#endif
111470 +
111471 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
111472 +#error Error: please synchronize IOC_ defines!
111473 +#endif
111474 +
111475 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
111476 +#error Error: please synchronize IOC_ defines!
111477 +#endif
111478 +
111479 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
111480 +#error Error: please synchronize IOC_ defines!
111481 +#endif
111482 +
111483 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
111484 +#error Error: please synchronize IOC_ defines!
111485 +#endif
111486 +
111487 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
111488 +#error Error: please synchronize IOC_ defines!
111489 +#endif
111490 +
111491 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
111492 +#error Error: please synchronize IOC_ defines!
111493 +#endif
111494 +
111495 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
111496 +#error Error: please synchronize IOC_ defines!
111497 +#endif
111498 +
111499 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
111500 +#error Error: please synchronize IOC_ defines!
111501 +#endif
111502 +
111503 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
111504 +#error Error: please synchronize IOC_ defines!
111505 +#endif
111506 +
111507 +/* fm_ioctls.h === fm_ext.h assertions */
111508 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
111509 +#error Error: please synchronize IOC_ defines!
111510 +#endif
111511 +
111512 +void LnxWrpPCDIOCTLTypeChecking(void)
111513 +{
111514 + /* fm_ext.h == fm_ioctls.h */
111515 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
111516 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
111517 +
111518 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111519 + /*ioc_fm_pcd_counters_params_t : NOT USED */
111520 + /*ioc_fm_pcd_exception_params_t : private */
111521 +#if (DPAA_VERSION >= 11)
111522 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
111523 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
111524 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
111525 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
111526 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
111527 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
111528 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
111529 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
111530 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
111531 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
111532 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111533 +#endif /* (DPAA_VERSION >= 11) */
111534 +
111535 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
111536 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
111537 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
111538 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
111539 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
111540 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
111541 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
111542 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
111543 +
111544 +#if defined(CONFIG_ARM64)
111545 + /* different alignment */
111546 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
111547 +#else
111548 +#if !defined(CONFIG_COMPAT)
111549 + /* different alignment */
111550 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
111551 +#endif
111552 +#endif
111553 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
111554 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
111555 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
111556 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
111557 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
111558 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
111559 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
111560 +#if (DPAA_VERSION >= 11)
111561 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
111562 +#endif
111563 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
111564 +#if !defined(CONFIG_COMPAT)
111565 + /* different alignment */
111566 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
111567 +#endif
111568 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
111569 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
111570 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
111571 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
111572 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
111573 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
111574 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
111575 +#if !defined(CONFIG_COMPAT)
111576 + /* different alignment */
111577 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
111578 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
111579 +#endif
111580 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
111581 +#if !defined(CONFIG_COMPAT)
111582 + /* different alignment */
111583 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
111584 +#endif
111585 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
111586 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
111587 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
111588 + /*ioc_fm_pcd_port_params_t : private */
111589 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
111590 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
111591 +
111592 +#ifdef FM_CAPWAP_SUPPORT
111593 +#error TODO: unsupported feature
111594 +/*
111595 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
111596 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
111597 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
111598 +*/
111599 +#endif
111600 +
111601 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
111602 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
111603 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
111604 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
111605 + /*ioc_fm_manip_hdr_info_t : private */
111606 + /*ioc_fm_pcd_hash_table_set_t : private */
111607 +
111608 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
111609 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
111610 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
111611 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
111612 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
111613 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
111614 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
111615 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
111616 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
111617 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111618 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
111619 +#if !defined(CONFIG_COMPAT)
111620 + /* different alignment */
111621 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
111622 +#endif
111623 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
111624 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
111625 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
111626 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
111627 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
111628 +#if DPAA_VERSION >= 11
111629 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
111630 +#endif
111631 +
111632 + /* fm_port_ext.h == fm_port_ioctls.h */
111633 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
111634 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
111635 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
111636 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
111637 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
111638 +
111639 + return;
111640 +}
111641 +
111642 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
111643 +
111644 +void LnxWrpPCDIOCTLEnumChecking(void)
111645 +{
111646 + /* net_ext.h == net_ioctls.h : sampling checks */
111647 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
111648 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
111649 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
111650 +
111651 + /* fm_ext.h == fm_ioctls.h */
111652 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
111653 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
111654 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
111655 +
111656 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111657 + 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);
111658 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
111659 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
111660 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
111661 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
111662 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
111663 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
111664 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
111665 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
111666 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
111667 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
111668 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
111669 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
111670 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
111671 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
111672 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
111673 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
111674 + 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);
111675 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
111676 + 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);
111677 +#if !defined(FM_CAPWAP_SUPPORT)
111678 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
111679 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
111680 +#else
111681 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
111682 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
111683 + 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);
111684 +#endif
111685 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
111686 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
111687 +
111688 +#ifdef FM_CAPWAP_SUPPORT
111689 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
111690 +#endif
111691 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
111692 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
111693 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
111694 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
111695 +
111696 + /* fm_port_ext.h == fm_port_ioctls.h */
111697 +#if !defined(FM_CAPWAP_SUPPORT)
111698 + 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);
111699 +#else
111700 + 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);
111701 +#endif
111702 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
111703 + 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);
111704 +
111705 + return;
111706 +}
111707 +
111708 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
111709 +{
111710 + t_Error err = E_OK;
111711 +
111712 +/*
111713 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
111714 +
111715 + FM_PCD_PrsLoadSw
111716 + FM_PCD_SetAdvancedOffloadSupport
111717 + FM_PCD_Enable
111718 + FM_PCD_Disable
111719 + FM_PCD_ForceIntr
111720 + FM_PCD_SetException
111721 + FM_PCD_KgSetAdditionalDataAfterParsing
111722 + FM_PCD_KgSetDfltValue
111723 + FM_PCD_NetEnvCharacteristicsSet
111724 + FM_PCD_NetEnvCharacteristicsDelete
111725 + FM_PCD_KgSchemeSet
111726 + FM_PCD_KgSchemeDelete
111727 + FM_PCD_MatchTableSet
111728 + FM_PCD_MatchTableDelete
111729 + FM_PCD_CcRootBuild
111730 + FM_PCD_CcRootDelete
111731 + FM_PCD_PlcrProfileSet
111732 + FM_PCD_PlcrProfileDelete
111733 + FM_PCD_CcRootModifyNextEngine
111734 + FM_PCD_MatchTableModifyNextEngine
111735 + FM_PCD_MatchTableModifyMissNextEngine
111736 + FM_PCD_MatchTableRemoveKey
111737 + FM_PCD_MatchTableAddKey
111738 + FM_PCD_MatchTableModifyKeyAndNextEngine
111739 + FM_PCD_HashTableSet
111740 + FM_PCD_HashTableDelete
111741 + FM_PCD_HashTableAddKey
111742 + FM_PCD_HashTableRemoveKey
111743 + FM_PCD_MatchTableModifyKey
111744 + FM_PCD_ManipNodeReplace
111745 + FM_PCD_ManipNodeSet
111746 + FM_PCD_ManipNodeDelete
111747 +
111748 +Status: not exported, should be thru sysfs
111749 + FM_PCD_KgSchemeGetCounter
111750 + FM_PCD_KgSchemeSetCounter
111751 + FM_PCD_PlcrProfileGetCounter
111752 + FM_PCD_PlcrProfileSetCounter
111753 +
111754 +Status: not exported
111755 + FM_PCD_MatchTableFindNRemoveKey
111756 + FM_PCD_MatchTableFindNModifyNextEngine
111757 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
111758 + FM_PCD_MatchTableFindNModifyKey
111759 + FM_PCD_MatchTableGetIndexedHashBucket
111760 + FM_PCD_MatchTableGetNextEngine
111761 + FM_PCD_MatchTableGetKeyCounter
111762 +
111763 +Status: not exported, would be nice to have
111764 + FM_PCD_HashTableModifyNextEngine
111765 + FM_PCD_HashTableModifyMissNextEngine
111766 + FM_PCD_HashTableGetMissNextEngine
111767 + FM_PCD_ManipGetStatistics
111768 +
111769 +Status: not exported
111770 +#if DPAA_VERSION >= 11
111771 +
111772 + FM_VSP_GetStatistics -- it's not available yet
111773 +#endif
111774 +
111775 +Status: feature not supported
111776 +#ifdef FM_CAPWAP_SUPPORT
111777 +#error unsupported feature
111778 + FM_PCD_StatisticsSetNode
111779 +#endif
111780 +
111781 + */
111782 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
111783 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
111784 +
111785 + switch (cmd)
111786 + {
111787 +#if defined(CONFIG_COMPAT)
111788 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
111789 +#endif
111790 + case FM_PCD_IOC_PRS_LOAD_SW:
111791 + {
111792 + ioc_fm_pcd_prs_sw_params_t *param;
111793 + uint8_t *p_code;
111794 +
111795 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
111796 + if (!param)
111797 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111798 +
111799 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
111800 +
111801 +#if defined(CONFIG_COMPAT)
111802 + if (compat)
111803 + {
111804 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
111805 +
111806 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
111807 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
111808 + if (!compat_param)
111809 + {
111810 + XX_Free(param);
111811 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111812 + }
111813 +
111814 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
111815 + if (copy_from_user(compat_param,
111816 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
111817 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
111818 + {
111819 + XX_Free(compat_param);
111820 + XX_Free(param);
111821 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111822 + }
111823 +
111824 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
111825 +
111826 + XX_Free(compat_param);
111827 + }
111828 + else
111829 +#endif
111830 + {
111831 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
111832 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
111833 + {
111834 + XX_Free(param);
111835 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111836 + }
111837 + }
111838 +
111839 + if (!param->p_code || !param->size)
111840 + {
111841 + XX_Free(param);
111842 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111843 + }
111844 +
111845 + p_code = (uint8_t *) XX_Malloc(param->size);
111846 + if (!p_code)
111847 + {
111848 + XX_Free(param);
111849 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111850 + }
111851 +
111852 + memset(p_code, 0, param->size);
111853 + if (copy_from_user(p_code, param->p_code, param->size))
111854 + {
111855 + XX_Free(p_code);
111856 + XX_Free(param);
111857 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111858 + }
111859 +
111860 + param->p_code = p_code;
111861 +
111862 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
111863 +
111864 + XX_Free(p_code);
111865 + XX_Free(param);
111866 + break;
111867 + }
111868 +
111869 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
111870 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
111871 + break;
111872 +
111873 + case FM_PCD_IOC_ENABLE:
111874 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
111875 + break;
111876 +
111877 + case FM_PCD_IOC_DISABLE:
111878 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
111879 + break;
111880 +
111881 + case FM_PCD_IOC_FORCE_INTR:
111882 + {
111883 + int exception;
111884 +
111885 +#if defined(CONFIG_COMPAT)
111886 + if (compat)
111887 + {
111888 + if (get_user(exception, (int *) compat_ptr(arg)))
111889 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111890 + }
111891 + else
111892 +#endif
111893 + {
111894 + if (get_user(exception, (int *)arg))
111895 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111896 + }
111897 +
111898 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
111899 + break;
111900 + }
111901 +
111902 + case FM_PCD_IOC_SET_EXCEPTION:
111903 + {
111904 + ioc_fm_pcd_exception_params_t *param;
111905 +
111906 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
111907 + sizeof(ioc_fm_pcd_exception_params_t));
111908 + if (!param)
111909 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111910 +
111911 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
111912 +
111913 +#if defined(CONFIG_COMPAT)
111914 + if (compat)
111915 + {
111916 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
111917 + sizeof(ioc_fm_pcd_exception_params_t)))
111918 + {
111919 + XX_Free(param);
111920 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111921 + }
111922 + }
111923 + else
111924 +#endif
111925 + {
111926 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
111927 + sizeof(ioc_fm_pcd_exception_params_t)))
111928 + {
111929 + XX_Free(param);
111930 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111931 + }
111932 + }
111933 +
111934 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
111935 +
111936 + XX_Free(param);
111937 + break;
111938 + }
111939 +
111940 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
111941 + {
111942 + uint8_t payloadOffset;
111943 +
111944 +#if defined(CONFIG_COMPAT)
111945 + if (compat)
111946 + {
111947 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
111948 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111949 + }
111950 + else
111951 +#endif
111952 + {
111953 + if (get_user(payloadOffset, (uint8_t*) arg))
111954 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111955 + }
111956 +
111957 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
111958 + break;
111959 + }
111960 +
111961 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
111962 + {
111963 + ioc_fm_pcd_kg_dflt_value_params_t *param;
111964 +
111965 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
111966 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
111967 + if (!param)
111968 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
111969 +
111970 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
111971 +
111972 +#if defined(CONFIG_COMPAT)
111973 + if (compat)
111974 + {
111975 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
111976 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
111977 + {
111978 + XX_Free(param);
111979 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111980 + }
111981 + }
111982 + else
111983 +#endif
111984 + {
111985 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
111986 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
111987 + {
111988 + XX_Free(param);
111989 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
111990 + }
111991 + }
111992 +
111993 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
111994 +
111995 + XX_Free(param);
111996 + break;
111997 + }
111998 +
111999 +#if defined(CONFIG_COMPAT)
112000 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
112001 +#endif
112002 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
112003 + {
112004 + ioc_fm_pcd_net_env_params_t *param;
112005 +
112006 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
112007 + if (!param)
112008 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112009 +
112010 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
112011 +
112012 +#if defined(CONFIG_COMPAT)
112013 + if (compat)
112014 + {
112015 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112016 +
112017 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112018 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112019 + if (!compat_param)
112020 + {
112021 + XX_Free(param);
112022 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112023 + }
112024 +
112025 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112026 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112027 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112028 + {
112029 + XX_Free(compat_param);
112030 + XX_Free(param);
112031 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112032 + }
112033 +
112034 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
112035 + XX_Free(compat_param);
112036 + }
112037 + else
112038 +#endif
112039 + {
112040 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
112041 + sizeof(ioc_fm_pcd_net_env_params_t)))
112042 + {
112043 + XX_Free(param);
112044 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112045 + }
112046 + }
112047 +
112048 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
112049 +
112050 + if (!param->id)
112051 + {
112052 + XX_Free(param);
112053 + err = E_INVALID_VALUE;
112054 + /* Since the LLD has no errno-style error reporting,
112055 + we're left here with no other option than to report
112056 + a generic E_INVALID_VALUE */
112057 + break;
112058 + }
112059 +
112060 +#if defined(CONFIG_COMPAT)
112061 + if (compat)
112062 + {
112063 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112064 +
112065 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112066 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112067 + if (!compat_param)
112068 + {
112069 + XX_Free(param);
112070 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112071 + }
112072 +
112073 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112074 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
112075 +
112076 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112077 + compat_param,
112078 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112079 + err = E_READ_FAILED;
112080 +
112081 + XX_Free(compat_param);
112082 + }
112083 + else
112084 +#endif
112085 + {
112086 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
112087 + param,
112088 + sizeof(ioc_fm_pcd_net_env_params_t)))
112089 + err = E_READ_FAILED;
112090 + }
112091 +
112092 + XX_Free(param);
112093 + break;
112094 + }
112095 +
112096 +#if defined(CONFIG_COMPAT)
112097 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
112098 +#endif
112099 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
112100 + {
112101 + ioc_fm_obj_t id;
112102 +
112103 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112104 +
112105 +#if defined(CONFIG_COMPAT)
112106 + if (compat)
112107 + {
112108 + ioc_compat_fm_obj_t compat_id;
112109 +
112110 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112111 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112112 +
112113 + compat_obj_delete(&compat_id, &id);
112114 + }
112115 + else
112116 +#endif
112117 + {
112118 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112119 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112120 + }
112121 +
112122 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
112123 + break;
112124 + }
112125 +
112126 +#if defined(CONFIG_COMPAT)
112127 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
112128 +#endif
112129 + case FM_PCD_IOC_KG_SCHEME_SET:
112130 + {
112131 + ioc_fm_pcd_kg_scheme_params_t *param;
112132 +
112133 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
112134 + if (!param)
112135 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112136 +
112137 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
112138 +
112139 +#if defined(CONFIG_COMPAT)
112140 + if (compat)
112141 + {
112142 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
112143 +
112144 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112145 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112146 + if (!compat_param)
112147 + {
112148 + XX_Free(param);
112149 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112150 + }
112151 +
112152 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112153 +
112154 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
112155 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112156 + {
112157 + XX_Free(compat_param);
112158 + XX_Free(param);
112159 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112160 + }
112161 +
112162 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
112163 +
112164 + XX_Free(compat_param);
112165 + }
112166 + else
112167 +#endif
112168 + {
112169 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
112170 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112171 + {
112172 + XX_Free(param);
112173 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112174 + }
112175 + }
112176 +
112177 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
112178 +
112179 + if (!param->id)
112180 + {
112181 + XX_Free(param);
112182 + err = E_INVALID_VALUE;
112183 + /* Since the LLD has no errno-style error reporting,
112184 + we're left here with no other option than to report
112185 + a generic E_INVALID_VALUE */
112186 + break;
112187 + }
112188 +
112189 +#if defined(CONFIG_COMPAT)
112190 + if (compat)
112191 + {
112192 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
112193 +
112194 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112195 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112196 + if (!compat_param)
112197 + {
112198 + XX_Free(param);
112199 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112200 + }
112201 +
112202 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112203 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
112204 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
112205 + compat_param,
112206 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112207 + err = E_READ_FAILED;
112208 +
112209 + XX_Free(compat_param);
112210 + }
112211 + else
112212 +#endif
112213 + {
112214 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
112215 + param,
112216 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112217 + err = E_READ_FAILED;
112218 + }
112219 +
112220 + XX_Free(param);
112221 + break;
112222 + }
112223 +
112224 +#if defined(CONFIG_COMPAT)
112225 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
112226 +#endif
112227 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
112228 + {
112229 + ioc_fm_pcd_kg_scheme_spc_t *param;
112230 +
112231 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112232 + if (!param)
112233 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112234 +
112235 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112236 +
112237 +#if defined(CONFIG_COMPAT)
112238 + if (compat)
112239 + {
112240 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
112241 +
112242 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112243 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112244 + if (!compat_param)
112245 + {
112246 + XX_Free(param);
112247 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112248 + }
112249 +
112250 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112251 +
112252 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
112253 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112254 + {
112255 + XX_Free(compat_param);
112256 + XX_Free(param);
112257 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112258 + }
112259 +
112260 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
112261 +
112262 + XX_Free(compat_param);
112263 + }
112264 + else
112265 +#endif
112266 + {
112267 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
112268 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112269 + {
112270 + XX_Free(param);
112271 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112272 + }
112273 + }
112274 +
112275 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
112276 +
112277 +#if defined(CONFIG_COMPAT)
112278 + if (compat)
112279 + {
112280 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
112281 +
112282 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112283 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112284 + if (!compat_param)
112285 + {
112286 + XX_Free(param);
112287 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112288 + }
112289 +
112290 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112291 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
112292 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
112293 + compat_param,
112294 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112295 + err = E_READ_FAILED;
112296 +
112297 + XX_Free(compat_param);
112298 + }
112299 + else
112300 +#endif
112301 + {
112302 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
112303 + param,
112304 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112305 + err = E_READ_FAILED;
112306 + }
112307 +
112308 + XX_Free(param);
112309 + break;
112310 + }
112311 +
112312 +#if defined(CONFIG_COMPAT)
112313 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
112314 +#endif
112315 + case FM_PCD_IOC_KG_SCHEME_DELETE:
112316 + {
112317 + ioc_fm_obj_t id;
112318 +
112319 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112320 +
112321 +#if defined(CONFIG_COMPAT)
112322 + if (compat)
112323 + {
112324 + ioc_compat_fm_obj_t compat_id;
112325 +
112326 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112327 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112328 +
112329 + compat_obj_delete(&compat_id, &id);
112330 + }
112331 + else
112332 +#endif
112333 + {
112334 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112335 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112336 + }
112337 +
112338 + err = FM_PCD_KgSchemeDelete(id.obj);
112339 + break;
112340 + }
112341 +
112342 +#if defined(CONFIG_COMPAT)
112343 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
112344 +#endif
112345 + case FM_PCD_IOC_MATCH_TABLE_SET:
112346 + {
112347 + ioc_fm_pcd_cc_node_params_t *param;
112348 + uint8_t *keys;
112349 + uint8_t *masks;
112350 + int i,k;
112351 +
112352 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
112353 + sizeof(ioc_fm_pcd_cc_node_params_t) +
112354 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112355 + if (!param)
112356 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112357 +
112358 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
112359 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112360 +
112361 + keys = (uint8_t *) (param + 1);
112362 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
112363 +
112364 +#if defined(CONFIG_COMPAT)
112365 + if (compat)
112366 + {
112367 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112368 +
112369 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112370 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112371 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112372 + if (!compat_param)
112373 + {
112374 + XX_Free(param);
112375 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112376 + }
112377 +
112378 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112379 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112380 +
112381 + if (copy_from_user(compat_param,
112382 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112383 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112384 + {
112385 + XX_Free(compat_param);
112386 + XX_Free(param);
112387 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112388 + }
112389 +
112390 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
112391 +
112392 + XX_Free(compat_param);
112393 + }
112394 + else
112395 +#endif
112396 + {
112397 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
112398 + {
112399 + XX_Free(param);
112400 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112401 + }
112402 + }
112403 +
112404 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
112405 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
112406 +
112407 + /* support for indexed lookup */
112408 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
112409 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
112410 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
112411 + {
112412 + for (i=0, k=0;
112413 + i < param->keys_params.num_of_keys;
112414 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
112415 + {
112416 + if (param->keys_params.key_params[i].p_key &&
112417 + param->keys_params.key_size)
112418 + {
112419 + if (copy_from_user(&keys[k],
112420 + param->keys_params.key_params[i].p_key,
112421 + param->keys_params.key_size))
112422 + {
112423 + XX_Free(param);
112424 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112425 + }
112426 +
112427 + param->keys_params.key_params[i].p_key = &keys[k];
112428 + }
112429 +
112430 + if (param->keys_params.key_params[i].p_mask)
112431 + {
112432 + if (copy_from_user(&masks[k],
112433 + param->keys_params.key_params[i].p_mask,
112434 + param->keys_params.key_size))
112435 + {
112436 + XX_Free(param);
112437 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112438 + }
112439 +
112440 + param->keys_params.key_params[i].p_mask = &masks[k];
112441 + }
112442 + }
112443 + }
112444 +
112445 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
112446 +
112447 + if (!param->id) {
112448 + XX_Free(param);
112449 + err = E_INVALID_VALUE;
112450 + /* Since the LLD has no errno-style error reporting,
112451 + we're left here with no other option than to report
112452 + a generic E_INVALID_VALUE */
112453 + break;
112454 + }
112455 +
112456 +#if defined(CONFIG_COMPAT)
112457 + if (compat)
112458 + {
112459 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112460 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112461 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112462 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112463 + if (!compat_param)
112464 + {
112465 + XX_Free(param);
112466 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112467 + }
112468 +
112469 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112470 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112471 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
112472 +
112473 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112474 + compat_param,
112475 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112476 + err = E_READ_FAILED;
112477 +
112478 + XX_Free(compat_param);
112479 + }
112480 + else
112481 +#endif
112482 + {
112483 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
112484 + param,
112485 + sizeof(ioc_fm_pcd_cc_node_params_t)))
112486 + err = E_READ_FAILED;
112487 + }
112488 +
112489 + XX_Free(param);
112490 + break;
112491 + }
112492 +
112493 +#if defined(CONFIG_COMPAT)
112494 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
112495 +#endif
112496 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
112497 + {
112498 + ioc_fm_obj_t id;
112499 +
112500 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112501 +
112502 +#if defined(CONFIG_COMPAT)
112503 + if (compat)
112504 + {
112505 + ioc_compat_fm_obj_t compat_id;
112506 +
112507 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112508 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112509 +
112510 + compat_obj_delete(&compat_id, &id);
112511 + }
112512 + else
112513 +#endif
112514 + {
112515 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112516 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112517 + }
112518 +
112519 + err = FM_PCD_MatchTableDelete(id.obj);
112520 + break;
112521 + }
112522 +
112523 +#if defined(CONFIG_COMPAT)
112524 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
112525 +#endif
112526 + case FM_PCD_IOC_CC_ROOT_BUILD:
112527 + {
112528 + ioc_fm_pcd_cc_tree_params_t *param;
112529 +
112530 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
112531 + if (!param)
112532 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112533 +
112534 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
112535 +
112536 +#if defined(CONFIG_COMPAT)
112537 + if (compat)
112538 + {
112539 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112540 +
112541 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
112542 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112543 + if (!compat_param)
112544 + {
112545 + XX_Free(param);
112546 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112547 + }
112548 +
112549 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112550 + if (copy_from_user(compat_param,
112551 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112552 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112553 + {
112554 + XX_Free(compat_param);
112555 + XX_Free(param);
112556 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112557 + }
112558 +
112559 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
112560 +
112561 + XX_Free(compat_param);
112562 + }
112563 + else
112564 +#endif
112565 + {
112566 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
112567 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112568 + {
112569 + XX_Free(param);
112570 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112571 + }
112572 + }
112573 +
112574 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
112575 +
112576 + if (!param->id) {
112577 + XX_Free(param);
112578 + err = E_INVALID_VALUE;
112579 + /* Since the LLD has no errno-style error reporting,
112580 + we're left here with no other option than to report
112581 + a generic E_INVALID_VALUE */
112582 + break;
112583 + }
112584 +
112585 +#if defined(CONFIG_COMPAT)
112586 + if (compat)
112587 + {
112588 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112589 +
112590 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112591 + if (!compat_param)
112592 + {
112593 + XX_Free(param);
112594 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112595 + }
112596 +
112597 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112598 +
112599 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
112600 +
112601 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112602 + compat_param,
112603 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112604 + err = E_READ_FAILED;
112605 +
112606 + XX_Free(compat_param);
112607 + }
112608 + else
112609 +#endif
112610 + {
112611 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
112612 + param,
112613 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112614 + err = E_READ_FAILED;
112615 + }
112616 +
112617 + XX_Free(param);
112618 + break;
112619 + }
112620 +
112621 +#if defined(CONFIG_COMPAT)
112622 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
112623 +#endif
112624 + case FM_PCD_IOC_CC_ROOT_DELETE:
112625 + {
112626 + ioc_fm_obj_t id;
112627 +
112628 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112629 +
112630 +#if defined(CONFIG_COMPAT)
112631 + if (compat)
112632 + {
112633 + ioc_compat_fm_obj_t compat_id;
112634 +
112635 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112636 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112637 +
112638 + compat_obj_delete(&compat_id, &id);
112639 + }
112640 + else
112641 +#endif
112642 + {
112643 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112644 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112645 + }
112646 +
112647 + err = FM_PCD_CcRootDelete(id.obj);
112648 + break;
112649 + }
112650 +
112651 +#if defined(CONFIG_COMPAT)
112652 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
112653 +#endif
112654 + case FM_PCD_IOC_PLCR_PROFILE_SET:
112655 + {
112656 + ioc_fm_pcd_plcr_profile_params_t *param;
112657 +
112658 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112659 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
112660 + if (!param)
112661 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112662 +
112663 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
112664 +
112665 +#if defined(CONFIG_COMPAT)
112666 + if (compat)
112667 + {
112668 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
112669 +
112670 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112671 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112672 + if (!compat_param)
112673 + {
112674 + XX_Free(param);
112675 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112676 + }
112677 +
112678 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112679 + if (copy_from_user(compat_param, (
112680 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
112681 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
112682 + {
112683 + XX_Free(compat_param);
112684 + XX_Free(param);
112685 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112686 + }
112687 +
112688 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
112689 +
112690 + XX_Free(compat_param);
112691 + }
112692 + else
112693 +#endif
112694 + {
112695 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
112696 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
112697 + {
112698 + XX_Free(param);
112699 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112700 + }
112701 + }
112702 +
112703 + if (!param->modify &&
112704 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
112705 + {
112706 + t_Handle h_Port;
112707 + ioc_fm_pcd_port_params_t *port_params;
112708 +
112709 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
112710 + if (!port_params)
112711 + {
112712 + XX_Free(param);
112713 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112714 + }
112715 +
112716 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
112717 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
112718 + sizeof(ioc_fm_pcd_port_params_t)))
112719 + {
112720 + XX_Free(port_params);
112721 + XX_Free(param);
112722 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112723 + }
112724 +
112725 + switch(port_params->port_type)
112726 + {
112727 + case (e_IOC_FM_PORT_TYPE_RX):
112728 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
112729 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
112730 + break;
112731 + }
112732 + goto invalid_port_id;
112733 +
112734 + case (e_IOC_FM_PORT_TYPE_RX_10G):
112735 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
112736 +#ifndef CONFIG_FMAN_ARM
112737 + if (IS_T1023_T1024) {
112738 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
112739 + } else {
112740 +#else
112741 + {
112742 +#endif
112743 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
112744 + }
112745 + break;
112746 + }
112747 + goto invalid_port_id;
112748 +
112749 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
112750 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
112751 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
112752 + break;
112753 + }
112754 + goto invalid_port_id;
112755 +
112756 + default:
112757 +invalid_port_id:
112758 + XX_Free(port_params);
112759 + XX_Free(param);
112760 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
112761 + }
112762 +
112763 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
112764 + XX_Free(port_params);
112765 + }
112766 +
112767 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
112768 +
112769 + if (!param->id) {
112770 + XX_Free(param);
112771 + err = E_INVALID_VALUE;
112772 + /* Since the LLD has no errno-style error reporting,
112773 + we're left here with no other option than to report
112774 + a generic E_INVALID_VALUE */
112775 + break;
112776 + }
112777 +
112778 +#if defined(CONFIG_COMPAT)
112779 + if (compat)
112780 + {
112781 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
112782 +
112783 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
112784 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112785 + if (!compat_param)
112786 + {
112787 + XX_Free(param);
112788 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112789 + }
112790 +
112791 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
112792 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
112793 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
112794 + compat_param,
112795 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
112796 + err = E_READ_FAILED;
112797 +
112798 + XX_Free(compat_param);
112799 + }
112800 + else
112801 +#endif
112802 + {
112803 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
112804 + param,
112805 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
112806 + err = E_READ_FAILED;
112807 + }
112808 +
112809 + XX_Free(param);
112810 + break;
112811 + }
112812 +
112813 +#if defined(CONFIG_COMPAT)
112814 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
112815 +#endif
112816 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
112817 + {
112818 + ioc_fm_obj_t id;
112819 +
112820 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112821 +
112822 +#if defined(CONFIG_COMPAT)
112823 + if (compat)
112824 + {
112825 + ioc_compat_fm_obj_t compat_id;
112826 +
112827 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112828 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112829 +
112830 + compat_obj_delete(&compat_id, &id);
112831 + }
112832 + else
112833 +#endif
112834 + {
112835 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112836 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112837 + }
112838 +
112839 + err = FM_PCD_PlcrProfileDelete(id.obj);
112840 + break;
112841 + }
112842 +
112843 +#if defined(CONFIG_COMPAT)
112844 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
112845 +#endif
112846 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
112847 + {
112848 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
112849 +
112850 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
112851 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
112852 + if (!param)
112853 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112854 +
112855 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
112856 +
112857 +#if defined(CONFIG_COMPAT)
112858 + if (compat)
112859 + {
112860 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
112861 +
112862 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
112863 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
112864 + if (!compat_param)
112865 + {
112866 + XX_Free(param);
112867 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112868 + }
112869 +
112870 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
112871 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
112872 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
112873 + {
112874 + XX_Free(compat_param);
112875 + XX_Free(param);
112876 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112877 + }
112878 +
112879 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
112880 +
112881 + XX_Free(compat_param);
112882 + }
112883 + else
112884 +#endif
112885 + {
112886 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
112887 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
112888 + {
112889 + XX_Free(param);
112890 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112891 + }
112892 + }
112893 +
112894 + err = FM_PCD_CcRootModifyNextEngine(param->id,
112895 + param->grp_indx,
112896 + param->indx,
112897 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
112898 +
112899 + XX_Free(param);
112900 + break;
112901 + }
112902 +
112903 +#if defined(CONFIG_COMPAT)
112904 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
112905 +#endif
112906 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
112907 + {
112908 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
112909 +
112910 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
112911 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
112912 + if (!param)
112913 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112914 +
112915 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
112916 +
112917 +#if defined(CONFIG_COMPAT)
112918 + if (compat)
112919 + {
112920 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
112921 +
112922 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
112923 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
112924 + if (!compat_param)
112925 + {
112926 + XX_Free(param);
112927 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112928 + }
112929 +
112930 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
112931 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
112932 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
112933 + {
112934 + XX_Free(compat_param);
112935 + XX_Free(param);
112936 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112937 + }
112938 +
112939 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
112940 +
112941 + XX_Free(compat_param);
112942 + }
112943 + else
112944 +#endif
112945 + {
112946 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
112947 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
112948 + {
112949 + XX_Free(param);
112950 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112951 + }
112952 + }
112953 +
112954 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
112955 + param->key_indx,
112956 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
112957 +
112958 + XX_Free(param);
112959 + break;
112960 + }
112961 +
112962 +#if defined(CONFIG_COMPAT)
112963 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
112964 +#endif
112965 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
112966 + {
112967 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
112968 +
112969 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
112970 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
112971 + if (!param)
112972 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112973 +
112974 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
112975 +
112976 +#if defined(CONFIG_COMPAT)
112977 + if (compat)
112978 + {
112979 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
112980 +
112981 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
112982 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
112983 + if (!compat_param)
112984 + {
112985 + XX_Free(param);
112986 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112987 + }
112988 +
112989 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
112990 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
112991 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
112992 + {
112993 + XX_Free(compat_param);
112994 + XX_Free(param);
112995 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112996 + }
112997 +
112998 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
112999 +
113000 + XX_Free(compat_param);
113001 + }
113002 + else
113003 +#endif
113004 + {
113005 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
113006 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113007 + {
113008 + XX_Free(param);
113009 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113010 + }
113011 + }
113012 +
113013 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
113014 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113015 +
113016 + XX_Free(param);
113017 + break;
113018 + }
113019 +
113020 +#if defined(CONFIG_COMPAT)
113021 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
113022 +#endif
113023 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
113024 + {
113025 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
113026 +
113027 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113028 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113029 + if (!param)
113030 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113031 +
113032 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113033 +
113034 +#if defined(CONFIG_COMPAT)
113035 + if (compat)
113036 + {
113037 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
113038 +
113039 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113040 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113041 + if (!compat_param)
113042 + {
113043 + XX_Free(param);
113044 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113045 + }
113046 +
113047 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113048 + if (copy_from_user(compat_param,
113049 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
113050 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
113051 + {
113052 + XX_Free(compat_param);
113053 + XX_Free(param);
113054 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113055 + }
113056 +
113057 + param->id = compat_ptr(compat_param->id);
113058 + param->key_indx = compat_param->key_indx;
113059 +
113060 + XX_Free(compat_param);
113061 + }
113062 + else
113063 +#endif
113064 + {
113065 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
113066 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
113067 + {
113068 + XX_Free(param);
113069 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113070 + }
113071 + }
113072 +
113073 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
113074 +
113075 + XX_Free(param);
113076 + break;
113077 + }
113078 +#if defined(CONFIG_COMPAT)
113079 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
113080 +#endif
113081 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
113082 + {
113083 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113084 +
113085 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113086 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113087 + if (!param)
113088 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113089 +
113090 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113091 +
113092 +#if defined(CONFIG_COMPAT)
113093 + if (compat)
113094 + {
113095 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113096 +
113097 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113098 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113099 + if (!compat_param)
113100 + {
113101 + XX_Free(param);
113102 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113103 + }
113104 +
113105 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113106 + if (copy_from_user(compat_param,
113107 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113108 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113109 + {
113110 + XX_Free(compat_param);
113111 + XX_Free(param);
113112 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113113 + }
113114 +
113115 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113116 +
113117 + XX_Free(compat_param);
113118 + }
113119 + else
113120 +#endif
113121 + {
113122 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113123 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113124 + {
113125 + XX_Free(param);
113126 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113127 + }
113128 + }
113129 +
113130 + if (param->key_size)
113131 + {
113132 + int size = 0;
113133 +
113134 + if (param->key_params.p_key) size += param->key_size;
113135 + if (param->key_params.p_mask) size += param->key_size;
113136 +
113137 + if (size)
113138 + {
113139 + uint8_t *p_tmp;
113140 +
113141 + p_tmp = (uint8_t*) XX_Malloc(size);
113142 + if (!p_tmp)
113143 + {
113144 + XX_Free(param);
113145 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113146 + }
113147 +
113148 + if (param->key_params.p_key)
113149 + {
113150 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113151 + {
113152 + XX_Free(p_tmp);
113153 + XX_Free(param);
113154 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113155 + }
113156 +
113157 + param->key_params.p_key = p_tmp;
113158 + }
113159 +
113160 + if (param->key_params.p_mask)
113161 + {
113162 + p_tmp += param->key_size;
113163 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113164 + {
113165 + XX_Free(p_tmp - param->key_size);
113166 + XX_Free(param);
113167 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113168 + }
113169 +
113170 + param->key_params.p_mask = p_tmp;
113171 + }
113172 + }
113173 + }
113174 +
113175 + err = FM_PCD_MatchTableAddKey(
113176 + param->id,
113177 + param->key_indx,
113178 + param->key_size,
113179 + (t_FmPcdCcKeyParams*)&param->key_params);
113180 +
113181 + if (param->key_params.p_key)
113182 + XX_Free(param->key_params.p_key);
113183 + XX_Free(param);
113184 + break;
113185 + }
113186 +
113187 +#if defined(CONFIG_COMPAT)
113188 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
113189 +#endif
113190 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
113191 + {
113192 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113193 +
113194 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113195 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113196 + if (!param)
113197 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113198 +
113199 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113200 +
113201 +#if defined(CONFIG_COMPAT)
113202 + if (compat)
113203 + {
113204 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113205 +
113206 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113207 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113208 + if (!compat_param)
113209 + {
113210 + XX_Free(param);
113211 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113212 + }
113213 +
113214 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113215 + if (copy_from_user(compat_param,
113216 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113217 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113218 + {
113219 + XX_Free(compat_param);
113220 + XX_Free(param);
113221 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113222 + }
113223 +
113224 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113225 +
113226 + XX_Free(compat_param);
113227 + }
113228 + else
113229 +#endif
113230 + {
113231 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113232 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113233 + {
113234 + XX_Free(param);
113235 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113236 + }
113237 + }
113238 +
113239 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
113240 + param->key_indx,
113241 + param->key_size,
113242 + (t_FmPcdCcKeyParams*)(&param->key_params));
113243 +
113244 + XX_Free(param);
113245 + break;
113246 + }
113247 +
113248 +
113249 +#if defined(CONFIG_COMPAT)
113250 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
113251 +#endif
113252 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
113253 + {
113254 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113255 +
113256 +#if defined(CONFIG_COMPAT)
113257 + if (compat)
113258 + {
113259 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113260 +
113261 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113262 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113263 + if (!compat_param)
113264 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113265 +
113266 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113267 + if (copy_from_user(compat_param,
113268 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113269 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113270 + {
113271 + XX_Free(compat_param);
113272 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113273 + }
113274 +
113275 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113276 +
113277 + XX_Free(compat_param);
113278 + }
113279 + else
113280 +#endif
113281 + {
113282 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113283 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113284 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113285 + }
113286 +
113287 +
113288 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
113289 + param.key_index,
113290 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113291 +
113292 +#if defined(CONFIG_COMPAT)
113293 + if (compat)
113294 + {
113295 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113296 +
113297 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113298 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113299 + if (!compat_param)
113300 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113301 +
113302 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113303 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113304 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113305 + compat_param,
113306 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113307 + XX_Free(compat_param);
113308 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113309 + }
113310 + XX_Free(compat_param);
113311 + }
113312 + else
113313 +#endif
113314 + {
113315 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113316 + &param,
113317 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113318 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113319 + }
113320 +
113321 + break;
113322 + }
113323 +
113324 +
113325 +#if defined(CONFIG_COMPAT)
113326 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
113327 +#endif
113328 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
113329 + {
113330 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113331 +
113332 +#if defined(CONFIG_COMPAT)
113333 + if (compat)
113334 + {
113335 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113336 +
113337 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113338 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113339 + if (!compat_param)
113340 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113341 +
113342 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113343 + if (copy_from_user(compat_param,
113344 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113345 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113346 + {
113347 + XX_Free(compat_param);
113348 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113349 + }
113350 +
113351 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113352 +
113353 + XX_Free(compat_param);
113354 + }
113355 + else
113356 +#endif
113357 + {
113358 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113359 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113360 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113361 + }
113362 +
113363 +
113364 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
113365 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113366 +
113367 +#if defined(CONFIG_COMPAT)
113368 + if (compat)
113369 + {
113370 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113371 +
113372 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113373 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113374 + if (!compat_param)
113375 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113376 +
113377 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113378 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113379 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113380 + compat_param,
113381 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113382 + XX_Free(compat_param);
113383 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113384 + }
113385 + XX_Free(compat_param);
113386 + }
113387 + else
113388 +#endif
113389 + {
113390 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113391 + &param,
113392 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113393 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113394 + }
113395 +
113396 + break;
113397 + }
113398 +
113399 +
113400 +#if defined(CONFIG_COMPAT)
113401 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
113402 +#endif
113403 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
113404 + {
113405 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113406 +
113407 +#if defined(CONFIG_COMPAT)
113408 + if (compat)
113409 + {
113410 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113411 +
113412 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113413 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113414 + if (!compat_param)
113415 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113416 +
113417 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113418 + if (copy_from_user(compat_param,
113419 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113420 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113421 + {
113422 + XX_Free(compat_param);
113423 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113424 + }
113425 +
113426 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113427 +
113428 + XX_Free(compat_param);
113429 + }
113430 + else
113431 +#endif
113432 + {
113433 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113434 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113435 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113436 + }
113437 +
113438 +
113439 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
113440 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113441 +
113442 +#if defined(CONFIG_COMPAT)
113443 + if (compat)
113444 + {
113445 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113446 +
113447 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113448 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113449 + if (!compat_param)
113450 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113451 +
113452 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113453 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113454 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113455 + compat_param,
113456 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113457 + XX_Free(compat_param);
113458 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113459 + }
113460 + XX_Free(compat_param);
113461 + }
113462 + else
113463 +#endif
113464 + {
113465 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113466 + &param,
113467 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113468 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113469 + }
113470 +
113471 + break;
113472 + }
113473 +
113474 +#if defined(CONFIG_COMPAT)
113475 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
113476 +#endif
113477 + case FM_PCD_IOC_HASH_TABLE_SET:
113478 + {
113479 + ioc_fm_pcd_hash_table_params_t *param;
113480 +
113481 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
113482 + sizeof(ioc_fm_pcd_hash_table_params_t));
113483 + if (!param)
113484 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113485 +
113486 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
113487 +
113488 +#if defined(CONFIG_COMPAT)
113489 + if (compat)
113490 + {
113491 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113492 +
113493 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113494 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113495 + if (!compat_param)
113496 + {
113497 + XX_Free(param);
113498 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113499 + }
113500 +
113501 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113502 + if (copy_from_user(compat_param,
113503 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
113504 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113505 + {
113506 + XX_Free(compat_param);
113507 + XX_Free(param);
113508 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113509 + }
113510 +
113511 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
113512 +
113513 + XX_Free(compat_param);
113514 + }
113515 + else
113516 +#endif
113517 + {
113518 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
113519 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113520 + {
113521 + XX_Free(param);
113522 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113523 + }
113524 + }
113525 +
113526 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
113527 +
113528 + if (!param->id)
113529 + {
113530 + XX_Free(param);
113531 + err = E_INVALID_VALUE;
113532 + /* Since the LLD has no errno-style error reporting,
113533 + we're left here with no other option than to report
113534 + a generic E_INVALID_VALUE */
113535 + break;
113536 + }
113537 +
113538 +#if defined(CONFIG_COMPAT)
113539 + if (compat)
113540 + {
113541 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113542 +
113543 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113544 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113545 + if (!compat_param)
113546 + {
113547 + XX_Free(param);
113548 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113549 + }
113550 +
113551 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113552 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
113553 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
113554 + compat_param,
113555 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113556 + err = E_READ_FAILED;
113557 +
113558 + XX_Free(compat_param);
113559 + }
113560 + else
113561 +#endif
113562 + {
113563 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
113564 + param,
113565 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113566 + err = E_READ_FAILED;
113567 + }
113568 +
113569 + XX_Free(param);
113570 + break;
113571 + }
113572 +
113573 +#if defined(CONFIG_COMPAT)
113574 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
113575 +#endif
113576 + case FM_PCD_IOC_HASH_TABLE_DELETE:
113577 + {
113578 + ioc_fm_obj_t id;
113579 +
113580 + memset(&id, 0, sizeof(ioc_fm_obj_t));
113581 +
113582 +#if defined(CONFIG_COMPAT)
113583 + if (compat)
113584 + {
113585 + ioc_compat_fm_obj_t compat_id;
113586 +
113587 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113588 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113589 +
113590 + id.obj = compat_pcd_id2ptr(compat_id.obj);
113591 + }
113592 + else
113593 +#endif
113594 + {
113595 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113596 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113597 + }
113598 +
113599 + err = FM_PCD_HashTableDelete(id.obj);
113600 + break;
113601 + }
113602 +
113603 +#if defined(CONFIG_COMPAT)
113604 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
113605 +#endif
113606 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
113607 + {
113608 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
113609 +
113610 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
113611 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
113612 + if (!param)
113613 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113614 +
113615 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
113616 +
113617 +#if defined(CONFIG_COMPAT)
113618 + if (compat)
113619 + {
113620 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
113621 +
113622 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
113623 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
113624 + if (!compat_param)
113625 + {
113626 + XX_Free(param);
113627 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113628 + }
113629 +
113630 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
113631 + if (copy_from_user(compat_param,
113632 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
113633 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
113634 + {
113635 + XX_Free(compat_param);
113636 + XX_Free(param);
113637 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113638 + }
113639 +
113640 + if (compat_param->key_size)
113641 + {
113642 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
113643 + param->key_size = compat_param->key_size;
113644 +
113645 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
113646 + }
113647 + else
113648 + {
113649 + XX_Free(compat_param);
113650 + XX_Free(param);
113651 + err = E_INVALID_VALUE;
113652 + break;
113653 + }
113654 +
113655 + XX_Free(compat_param);
113656 + }
113657 + else
113658 +#endif
113659 + {
113660 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
113661 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
113662 + {
113663 + XX_Free(param);
113664 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113665 + }
113666 + }
113667 +
113668 + if (param->key_size)
113669 + {
113670 + int size = 0;
113671 +
113672 + if (param->key_params.p_key) size += param->key_size;
113673 + if (param->key_params.p_mask) size += param->key_size;
113674 +
113675 + if (size)
113676 + {
113677 + uint8_t *p_tmp;
113678 +
113679 + p_tmp = (uint8_t*) XX_Malloc(size);
113680 + if (!p_tmp)
113681 + {
113682 + XX_Free(param);
113683 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113684 + }
113685 +
113686 + if (param->key_params.p_key)
113687 + {
113688 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113689 + {
113690 + XX_Free(p_tmp);
113691 + XX_Free(param);
113692 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113693 + }
113694 +
113695 + param->key_params.p_key = p_tmp;
113696 + }
113697 +
113698 + if (param->key_params.p_mask)
113699 + {
113700 + p_tmp += param->key_size;
113701 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113702 + {
113703 + XX_Free(p_tmp - param->key_size);
113704 + XX_Free(param);
113705 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113706 + }
113707 +
113708 + param->key_params.p_mask = p_tmp;
113709 + }
113710 + }
113711 + }
113712 +
113713 + err = FM_PCD_HashTableAddKey(
113714 + param->p_hash_tbl,
113715 + param->key_size,
113716 + (t_FmPcdCcKeyParams*)&param->key_params);
113717 +
113718 + if (param->key_params.p_key)
113719 + XX_Free(param->key_params.p_key);
113720 + XX_Free(param);
113721 + break;
113722 + }
113723 +
113724 +#if defined(CONFIG_COMPAT)
113725 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
113726 +#endif
113727 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
113728 + {
113729 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
113730 +
113731 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
113732 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
113733 + if (!param)
113734 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113735 +
113736 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
113737 +
113738 +#if defined(CONFIG_COMPAT)
113739 + if (compat)
113740 + {
113741 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
113742 +
113743 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
113744 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
113745 + if (!compat_param)
113746 + {
113747 + XX_Free(param);
113748 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113749 + }
113750 +
113751 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
113752 + if (copy_from_user(compat_param,
113753 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
113754 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
113755 + {
113756 + XX_Free(compat_param);
113757 + XX_Free(param);
113758 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113759 + }
113760 +
113761 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
113762 + param->key_size = compat_param->key_size;
113763 +
113764 + XX_Free(compat_param);
113765 + }
113766 + else
113767 +#endif
113768 + {
113769 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
113770 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
113771 + {
113772 + XX_Free(param);
113773 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113774 + }
113775 + }
113776 +
113777 + if (param->key_size)
113778 + {
113779 + uint8_t *p_key;
113780 +
113781 + p_key = (uint8_t*) XX_Malloc(param->key_size);
113782 + if (!p_key)
113783 + {
113784 + XX_Free(param);
113785 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113786 + }
113787 +
113788 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
113789 + {
113790 + XX_Free(p_key);
113791 + XX_Free(param);
113792 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113793 + }
113794 + param->p_key = p_key;
113795 + }
113796 +
113797 + err = FM_PCD_HashTableRemoveKey(
113798 + param->p_hash_tbl,
113799 + param->key_size,
113800 + param->p_key);
113801 +
113802 + if (param->p_key)
113803 + XX_Free(param->p_key);
113804 + XX_Free(param);
113805 + break;
113806 + }
113807 +
113808 +#if defined(CONFIG_COMPAT)
113809 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
113810 +#endif
113811 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
113812 + {
113813 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
113814 +
113815 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
113816 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
113817 + if (!param)
113818 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113819 +
113820 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
113821 +
113822 +#if defined(CONFIG_COMPAT)
113823 + if (compat)
113824 + {
113825 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
113826 +
113827 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
113828 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
113829 + if (!compat_param)
113830 + {
113831 + XX_Free(param);
113832 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113833 + }
113834 +
113835 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
113836 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
113837 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
113838 + {
113839 + XX_Free(compat_param);
113840 + XX_Free(param);
113841 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113842 + }
113843 +
113844 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
113845 +
113846 + XX_Free(compat_param);
113847 + }
113848 + else
113849 +#endif
113850 + {
113851 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
113852 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
113853 + {
113854 + XX_Free(param);
113855 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113856 + }
113857 + }
113858 +
113859 + if (param->key_size)
113860 + {
113861 + int size = 0;
113862 +
113863 + if (param->p_key) size += param->key_size;
113864 + if (param->p_mask) size += param->key_size;
113865 +
113866 + if (size)
113867 + {
113868 + uint8_t *p_tmp;
113869 +
113870 + p_tmp = (uint8_t*) XX_Malloc(size);
113871 + if (!p_tmp)
113872 + {
113873 + XX_Free(param);
113874 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113875 + }
113876 +
113877 + if (param->p_key)
113878 + {
113879 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
113880 + {
113881 + XX_Free(p_tmp);
113882 + XX_Free(param);
113883 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113884 + }
113885 +
113886 + param->p_key = p_tmp;
113887 + }
113888 +
113889 + if (param->p_mask)
113890 + {
113891 + p_tmp += param->key_size;
113892 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
113893 + {
113894 + XX_Free(p_tmp - param->key_size);
113895 + XX_Free(param);
113896 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113897 + }
113898 +
113899 + param->p_mask = p_tmp;
113900 + }
113901 + }
113902 + }
113903 +
113904 + err = FM_PCD_MatchTableModifyKey(param->id,
113905 + param->key_indx,
113906 + param->key_size,
113907 + param->p_key,
113908 + param->p_mask);
113909 +
113910 + if (param->p_key)
113911 + XX_Free(param->p_key);
113912 + else if (param->p_mask)
113913 + XX_Free(param->p_mask);
113914 + XX_Free(param);
113915 + break;
113916 + }
113917 +
113918 +#if defined(CONFIG_COMPAT)
113919 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
113920 +#endif
113921 + case FM_PCD_IOC_MANIP_NODE_SET:
113922 + {
113923 + ioc_fm_pcd_manip_params_t *param;
113924 + uint8_t *p_data = NULL;
113925 + uint8_t size;
113926 +
113927 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
113928 + sizeof(ioc_fm_pcd_manip_params_t));
113929 +
113930 + if (!param)
113931 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113932 +
113933 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
113934 +
113935 +#if defined(CONFIG_COMPAT)
113936 + if (compat)
113937 + {
113938 + ioc_compat_fm_pcd_manip_params_t *compat_param;
113939 +
113940 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
113941 + sizeof(ioc_compat_fm_pcd_manip_params_t));
113942 + if (!compat_param)
113943 + {
113944 + XX_Free(param);
113945 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113946 + }
113947 +
113948 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
113949 + if (copy_from_user(compat_param,
113950 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
113951 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
113952 + {
113953 + XX_Free(compat_param);
113954 + XX_Free(param);
113955 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113956 + }
113957 +
113958 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
113959 +
113960 + XX_Free(compat_param);
113961 + }
113962 + else
113963 +#endif
113964 + {
113965 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
113966 + sizeof(ioc_fm_pcd_manip_params_t)))
113967 + {
113968 + XX_Free(param);
113969 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113970 + }
113971 + }
113972 +
113973 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
113974 + {
113975 + size = param->u.hdr.insrt_params.u.generic.size;
113976 + p_data = (uint8_t *) XX_Malloc(size);
113977 + if (!p_data )
113978 + {
113979 + XX_Free(param);
113980 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
113981 + }
113982 +
113983 + if (param->u.hdr.insrt_params.u.generic.p_data &&
113984 + copy_from_user(p_data,
113985 + param->u.hdr.insrt_params.u.generic.p_data, size))
113986 + {
113987 + XX_Free(p_data);
113988 + XX_Free(param);
113989 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113990 + }
113991 +
113992 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
113993 + }
113994 +
113995 + if (param->id)
113996 + {
113997 + /* Security Hole: the user can pass any piece of garbage
113998 + in 'param->id', and that will go straight through to the LLD,
113999 + no checks being done by the wrapper! */
114000 + err = FM_PCD_ManipNodeReplace(
114001 + (t_Handle) param->id,
114002 + (t_FmPcdManipParams*) param);
114003 + if (err)
114004 + {
114005 + if (p_data)
114006 + XX_Free(p_data);
114007 + XX_Free(param);
114008 + break;
114009 + }
114010 + }
114011 + else
114012 + {
114013 + param->id = FM_PCD_ManipNodeSet(
114014 + p_LnxWrpFmDev->h_PcdDev,
114015 + (t_FmPcdManipParams*) param);
114016 + if (!param->id)
114017 + {
114018 + if (p_data)
114019 + XX_Free(p_data);
114020 + XX_Free(param);
114021 + err = E_INVALID_VALUE;
114022 + /* Since the LLD has no errno-style error reporting,
114023 + we're left here with no other option than to report
114024 + a generic E_INVALID_VALUE */
114025 + break;
114026 + }
114027 + }
114028 +
114029 +#if defined(CONFIG_COMPAT)
114030 + if (compat)
114031 + {
114032 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114033 +
114034 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114035 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114036 + if (!compat_param)
114037 + {
114038 + if (p_data)
114039 + XX_Free(p_data);
114040 + XX_Free(param);
114041 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114042 + }
114043 +
114044 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114045 +
114046 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
114047 +
114048 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114049 + compat_param,
114050 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114051 + err = E_READ_FAILED;
114052 +
114053 + XX_Free(compat_param);
114054 + }
114055 + else
114056 +#endif
114057 + {
114058 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
114059 + param, sizeof(ioc_fm_pcd_manip_params_t)))
114060 + err = E_READ_FAILED;
114061 + }
114062 +
114063 + if (p_data)
114064 + XX_Free(p_data);
114065 + XX_Free(param);
114066 + break;
114067 + }
114068 +
114069 +#if defined(CONFIG_COMPAT)
114070 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
114071 +#endif
114072 + case FM_PCD_IOC_MANIP_NODE_DELETE:
114073 + {
114074 + ioc_fm_obj_t id;
114075 +
114076 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114077 +#if defined(CONFIG_COMPAT)
114078 + if (compat)
114079 + {
114080 + ioc_compat_fm_obj_t compat_id;
114081 +
114082 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114083 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114084 +
114085 + compat_obj_delete(&compat_id, &id);
114086 + }
114087 + else
114088 +#endif
114089 + {
114090 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114091 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114092 + }
114093 +
114094 + err = FM_PCD_ManipNodeDelete(id.obj);
114095 + break;
114096 + }
114097 +
114098 +#if defined(CONFIG_COMPAT)
114099 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
114100 +#endif
114101 + case FM_PCD_IOC_MANIP_GET_STATS:
114102 + {
114103 + ioc_fm_pcd_manip_get_stats_t param;
114104 +
114105 +#if defined(CONFIG_COMPAT)
114106 + if (compat)
114107 + {
114108 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114109 +
114110 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
114111 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114112 + if (!compat_param)
114113 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114114 +
114115 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114116 + if (copy_from_user(compat_param,
114117 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
114118 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
114119 + {
114120 + XX_Free(compat_param);
114121 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114122 + }
114123 +
114124 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
114125 +
114126 + XX_Free(compat_param);
114127 + }
114128 + else
114129 +#endif
114130 + {
114131 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
114132 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114133 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114134 + }
114135 +
114136 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
114137 + (t_FmPcdManipStats*) &param.stats);
114138 +
114139 +#if defined(CONFIG_COMPAT)
114140 + if (compat)
114141 + {
114142 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114143 +
114144 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
114145 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114146 + if (!compat_param)
114147 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114148 +
114149 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114150 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
114151 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
114152 + compat_param,
114153 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
114154 + XX_Free(compat_param);
114155 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114156 + }
114157 + XX_Free(compat_param);
114158 + }
114159 + else
114160 +#endif
114161 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
114162 + &param,
114163 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114164 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114165 +
114166 + break;
114167 + }
114168 +
114169 +#if (DPAA_VERSION >= 11)
114170 +#if defined(CONFIG_COMPAT)
114171 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
114172 +#endif
114173 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
114174 + {
114175 + ioc_fm_pcd_frm_replic_group_params_t *param;
114176 +
114177 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
114178 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114179 + if (!param)
114180 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114181 +
114182 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114183 +
114184 +#if defined(CONFIG_COMPAT)
114185 + if (compat)
114186 + {
114187 + ioc_compat_fm_pcd_frm_replic_group_params_t
114188 + *compat_param;
114189 +
114190 + compat_param =
114191 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114192 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114193 + if (!compat_param)
114194 + {
114195 + XX_Free(param);
114196 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114197 + ("IOCTL FM PCD"));
114198 + }
114199 +
114200 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114201 + if (copy_from_user(compat_param,
114202 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114203 + compat_ptr(arg),
114204 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
114205 + XX_Free(compat_param);
114206 + XX_Free(param);
114207 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114208 + }
114209 +
114210 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114211 + param, COMPAT_US_TO_K);
114212 +
114213 + XX_Free(compat_param);
114214 + }
114215 + else
114216 +#endif
114217 + {
114218 + if (copy_from_user(param,
114219 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114220 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114221 + {
114222 + XX_Free(param);
114223 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114224 + }
114225 + }
114226 +
114227 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
114228 + (t_FmPcdFrmReplicGroupParams*)param);
114229 +
114230 + if (!param->id) {
114231 + XX_Free(param);
114232 + err = E_INVALID_VALUE;
114233 + /*
114234 + * Since the LLD has no errno-style error reporting,
114235 + * we're left here with no other option than to report
114236 + * a generic E_INVALID_VALUE
114237 + */
114238 + break;
114239 + }
114240 +
114241 +#if defined(CONFIG_COMPAT)
114242 + if (compat)
114243 + {
114244 + ioc_compat_fm_pcd_frm_replic_group_params_t
114245 + *compat_param;
114246 +
114247 + compat_param =
114248 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114249 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114250 + if (!compat_param)
114251 + {
114252 + XX_Free(param);
114253 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114254 + ("IOCTL FM PCD"));
114255 + }
114256 +
114257 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114258 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114259 + param, COMPAT_K_TO_US);
114260 + if (copy_to_user(
114261 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114262 + compat_ptr(arg),
114263 + compat_param,
114264 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
114265 + err = E_WRITE_FAILED;
114266 +
114267 + XX_Free(compat_param);
114268 + }
114269 + else
114270 +#endif
114271 + {
114272 + if (copy_to_user(
114273 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114274 + param,
114275 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114276 + err = E_WRITE_FAILED;
114277 + }
114278 +
114279 + XX_Free(param);
114280 + break;
114281 + }
114282 + break;
114283 +
114284 +#if defined(CONFIG_COMPAT)
114285 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
114286 +#endif
114287 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
114288 + {
114289 + ioc_fm_obj_t id;
114290 +
114291 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114292 +#if defined(CONFIG_COMPAT)
114293 + if (compat)
114294 + {
114295 + ioc_compat_fm_obj_t compat_id;
114296 +
114297 + if (copy_from_user(&compat_id,
114298 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114299 + sizeof(ioc_compat_fm_obj_t)))
114300 + break;
114301 + compat_obj_delete(&compat_id, &id);
114302 + }
114303 + else
114304 +#endif
114305 + {
114306 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114307 + sizeof(ioc_fm_obj_t)))
114308 + break;
114309 + }
114310 +
114311 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
114312 + }
114313 + break;
114314 +
114315 +#if defined(CONFIG_COMPAT)
114316 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
114317 +#endif
114318 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
114319 + {
114320 + ioc_fm_pcd_frm_replic_member_params_t param;
114321 +
114322 +#if defined(CONFIG_COMPAT)
114323 + if (compat)
114324 + {
114325 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
114326 +
114327 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114328 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114329 +
114330 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
114331 + }
114332 + else
114333 +#endif
114334 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114335 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114336 +
114337 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
114338 + param.member.member_index,
114339 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
114340 + }
114341 + break;
114342 +
114343 +#if defined(CONFIG_COMPAT)
114344 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
114345 +#endif
114346 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
114347 + {
114348 + ioc_fm_pcd_frm_replic_member_t param;
114349 +
114350 +#if defined(CONFIG_COMPAT)
114351 + if (compat)
114352 + {
114353 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
114354 +
114355 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114356 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114357 +
114358 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
114359 + }
114360 + else
114361 +#endif
114362 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114363 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114364 +
114365 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
114366 + }
114367 + break;
114368 +
114369 +#if defined(CONFIG_COMPAT)
114370 + case FM_IOC_VSP_CONFIG_COMPAT:
114371 +#endif
114372 + case FM_IOC_VSP_CONFIG:
114373 + {
114374 + ioc_fm_vsp_params_t param;
114375 +
114376 +#if defined(CONFIG_COMPAT)
114377 + if (compat)
114378 + {
114379 + ioc_compat_fm_vsp_params_t compat_param;
114380 +
114381 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114382 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114383 +
114384 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
114385 + }
114386 + else
114387 +#endif
114388 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114389 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114390 + {
114391 + uint8_t portId = param.port_params.port_id;
114392 + param.liodn_offset =
114393 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
114394 + }
114395 + param.p_fm = p_LnxWrpFmDev->h_Dev;
114396 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
114397 +
114398 +#if defined(CONFIG_COMPAT)
114399 + if (compat)
114400 + {
114401 + ioc_compat_fm_vsp_params_t compat_param;
114402 +
114403 + memset(&compat_param, 0, sizeof(compat_param));
114404 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
114405 +
114406 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114407 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114408 + }
114409 + else
114410 +#endif
114411 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114412 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114413 + break;
114414 + }
114415 +
114416 +#if defined(CONFIG_COMPAT)
114417 + case FM_IOC_VSP_INIT_COMPAT:
114418 +#endif
114419 + case FM_IOC_VSP_INIT:
114420 + {
114421 + ioc_fm_obj_t id;
114422 +
114423 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114424 +#if defined(CONFIG_COMPAT)
114425 + if (compat)
114426 + {
114427 + ioc_compat_fm_obj_t compat_id;
114428 +
114429 + if (copy_from_user(&compat_id,
114430 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114431 + sizeof(ioc_compat_fm_obj_t)))
114432 + break;
114433 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114434 + }
114435 + else
114436 +#endif
114437 + {
114438 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114439 + sizeof(ioc_fm_obj_t)))
114440 + break;
114441 + }
114442 +
114443 + return FM_VSP_Init(id.obj);
114444 + }
114445 +
114446 +#if defined(CONFIG_COMPAT)
114447 + case FM_IOC_VSP_FREE_COMPAT:
114448 +#endif
114449 + case FM_IOC_VSP_FREE:
114450 + {
114451 + ioc_fm_obj_t id;
114452 +
114453 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114454 +#if defined(CONFIG_COMPAT)
114455 + if (compat)
114456 + {
114457 + ioc_compat_fm_obj_t compat_id;
114458 +
114459 + if (copy_from_user(&compat_id,
114460 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114461 + sizeof(ioc_compat_fm_obj_t)))
114462 + break;
114463 + compat_obj_delete(&compat_id, &id);
114464 + }
114465 + else
114466 +#endif
114467 + {
114468 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114469 + sizeof(ioc_fm_obj_t)))
114470 + break;
114471 + }
114472 +
114473 + return FM_VSP_Free(id.obj);
114474 + }
114475 +
114476 +#if defined(CONFIG_COMPAT)
114477 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
114478 +#endif
114479 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
114480 + {
114481 + ioc_fm_buf_pool_depletion_params_t param;
114482 +
114483 +#if defined(CONFIG_COMPAT)
114484 + if (compat)
114485 + {
114486 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
114487 +
114488 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114489 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114490 +
114491 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
114492 + }
114493 + else
114494 +#endif
114495 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114496 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114497 +
114498 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
114499 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
114500 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114501 +
114502 + break;
114503 + }
114504 +
114505 +
114506 +#if defined(CONFIG_COMPAT)
114507 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
114508 +#endif
114509 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
114510 + {
114511 + ioc_fm_buffer_prefix_content_params_t param;
114512 +
114513 +#if defined(CONFIG_COMPAT)
114514 + if (compat)
114515 + {
114516 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
114517 +
114518 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114519 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114520 +
114521 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
114522 + }
114523 + else
114524 +#endif
114525 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114526 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114527 +
114528 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
114529 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
114530 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114531 +
114532 + break;
114533 + }
114534 +
114535 +#if defined(CONFIG_COMPAT)
114536 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
114537 +#endif
114538 + case FM_IOC_VSP_CONFIG_NO_SG:
114539 + {
114540 + ioc_fm_vsp_config_no_sg_params_t param;
114541 +
114542 +#if defined(CONFIG_COMPAT)
114543 + if (compat)
114544 + {
114545 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
114546 +
114547 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114548 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114549 +
114550 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
114551 + }
114552 + else
114553 +#endif
114554 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114555 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114556 +
114557 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
114558 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114559 +
114560 + break;
114561 + }
114562 +
114563 +#if defined(CONFIG_COMPAT)
114564 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
114565 +#endif
114566 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
114567 + {
114568 + ioc_fm_vsp_prs_result_params_t param;
114569 +
114570 +#if defined(CONFIG_COMPAT)
114571 + if (compat)
114572 + {
114573 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114574 +
114575 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114576 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114577 +
114578 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
114579 + }
114580 + else
114581 +#endif
114582 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114583 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114584 +
114585 + /* this call just adds the parse results offset to p_data */
114586 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
114587 +
114588 + if (!param.p_data)
114589 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114590 +
114591 +#if defined(CONFIG_COMPAT)
114592 + if (compat)
114593 + {
114594 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114595 +
114596 + memset(&compat_param, 0, sizeof(compat_param));
114597 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
114598 +
114599 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114600 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114601 + }
114602 + else
114603 +#endif
114604 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114605 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114606 +
114607 + break;
114608 + }
114609 +#endif /* (DPAA_VERSION >= 11) */
114610 +
114611 +#ifdef FM_CAPWAP_SUPPORT
114612 +#warning "feature not supported!"
114613 +#if defined(CONFIG_COMPAT)
114614 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
114615 +#endif
114616 + case FM_PCD_IOC_STATISTICS_SET_NODE:
114617 + {
114618 +/* ioc_fm_pcd_stats_params_t param;
114619 + ...
114620 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
114621 + (t_FmPcdStatsParams *)&param);
114622 +*/
114623 + err = E_NOT_SUPPORTED;
114624 + break;
114625 + }
114626 +#endif /* FM_CAPWAP_SUPPORT */
114627 +
114628 + default:
114629 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
114630 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
114631 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
114632 + }
114633 +
114634 + if (err)
114635 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
114636 +
114637 + return E_OK;
114638 +}
114639 +
114640 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
114641 +{
114642 + p_version->version.major = FMD_API_VERSION_MAJOR;
114643 + p_version->version.minor = FMD_API_VERSION_MINOR;
114644 + p_version->version.respin = FMD_API_VERSION_RESPIN;
114645 + p_version->version.reserved = 0;
114646 +}
114647 +
114648 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
114649 +{
114650 + t_Error err = E_OK;
114651 +
114652 + switch (cmd)
114653 + {
114654 + case FM_IOC_SET_PORTS_BANDWIDTH:
114655 + {
114656 + ioc_fm_port_bandwidth_params *param;
114657 +
114658 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
114659 + if (!param)
114660 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114661 +
114662 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
114663 +
114664 +#if defined(CONFIG_COMPAT)
114665 + if (compat)
114666 + {
114667 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
114668 + {
114669 + XX_Free(param);
114670 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114671 + }
114672 + }
114673 + else
114674 +#endif
114675 + {
114676 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
114677 + {
114678 + XX_Free(param);
114679 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114680 + }
114681 + }
114682 +
114683 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
114684 +
114685 + XX_Free(param);
114686 + break;
114687 + }
114688 +
114689 + case FM_IOC_GET_REVISION:
114690 + {
114691 + ioc_fm_revision_info_t *param;
114692 +
114693 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
114694 + if (!param)
114695 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114696 +
114697 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
114698 + /* This one never returns anything other than E_OK */
114699 +
114700 +#if defined(CONFIG_COMPAT)
114701 + if (compat)
114702 + {
114703 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
114704 + param,
114705 + sizeof(ioc_fm_revision_info_t))){
114706 + XX_Free(param);
114707 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114708 + }
114709 + }
114710 + else
114711 +#endif
114712 + {
114713 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
114714 + param,
114715 + sizeof(ioc_fm_revision_info_t))){
114716 + XX_Free(param);
114717 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114718 + }
114719 + }
114720 + XX_Free(param);
114721 + break;
114722 + }
114723 +
114724 + case FM_IOC_SET_COUNTER:
114725 + {
114726 + ioc_fm_counters_params_t *param;
114727 +
114728 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
114729 + if (!param)
114730 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114731 +
114732 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
114733 +
114734 +#if defined(CONFIG_COMPAT)
114735 + if (compat)
114736 + {
114737 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
114738 + {
114739 + XX_Free(param);
114740 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114741 + }
114742 + }
114743 + else
114744 +#endif
114745 + {
114746 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
114747 + {
114748 + XX_Free(param);
114749 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114750 + }
114751 + }
114752 +
114753 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
114754 +
114755 + XX_Free(param);
114756 + break;
114757 + }
114758 +
114759 + case FM_IOC_GET_COUNTER:
114760 + {
114761 + ioc_fm_counters_params_t *param;
114762 +
114763 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
114764 + if (!param)
114765 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114766 +
114767 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
114768 +
114769 +#if defined(CONFIG_COMPAT)
114770 + if (compat)
114771 + {
114772 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
114773 + {
114774 + XX_Free(param);
114775 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114776 + }
114777 + }
114778 + else
114779 +#endif
114780 + {
114781 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
114782 + {
114783 + XX_Free(param);
114784 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114785 + }
114786 + }
114787 +
114788 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
114789 +
114790 +#if defined(CONFIG_COMPAT)
114791 + if (compat)
114792 + {
114793 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
114794 + err = E_READ_FAILED;
114795 + }
114796 + else
114797 +#endif
114798 + {
114799 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
114800 + err = E_READ_FAILED;
114801 + }
114802 +
114803 + XX_Free(param);
114804 + break;
114805 + }
114806 +
114807 + case FM_IOC_FORCE_INTR:
114808 + {
114809 + ioc_fm_exceptions param;
114810 +
114811 +#if defined(CONFIG_COMPAT)
114812 + if (compat)
114813 + {
114814 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
114815 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114816 + }
114817 + else
114818 +#endif
114819 + {
114820 + if (get_user(param, (ioc_fm_exceptions*)arg))
114821 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114822 + }
114823 +
114824 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
114825 + break;
114826 + }
114827 +
114828 + case FM_IOC_GET_API_VERSION:
114829 + {
114830 + ioc_fm_api_version_t version;
114831 +
114832 + FM_Get_Api_Version(&version);
114833 +
114834 +#if defined(CONFIG_COMPAT)
114835 + if (compat)
114836 + {
114837 + if (copy_to_user(
114838 + (ioc_fm_api_version_t *)compat_ptr(arg),
114839 + &version, sizeof(version)))
114840 + err = E_READ_FAILED;
114841 + }
114842 + else
114843 +#endif
114844 + {
114845 + if (copy_to_user((ioc_fm_api_version_t *)arg,
114846 + &version, sizeof(version)))
114847 + err = E_READ_FAILED;
114848 + }
114849 + }
114850 + break;
114851 +
114852 + case FM_IOC_CTRL_MON_START:
114853 + {
114854 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
114855 + }
114856 + break;
114857 +
114858 + case FM_IOC_CTRL_MON_STOP:
114859 + {
114860 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
114861 + }
114862 + break;
114863 +
114864 +#if defined(CONFIG_COMPAT)
114865 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
114866 +#endif
114867 + case FM_IOC_CTRL_MON_GET_COUNTERS:
114868 + {
114869 + ioc_fm_ctrl_mon_counters_params_t param;
114870 + t_FmCtrlMon mon;
114871 +
114872 +#if defined(CONFIG_COMPAT)
114873 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
114874 +
114875 + if (compat)
114876 + {
114877 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
114878 + sizeof(compat_param)))
114879 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114880 +
114881 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
114882 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
114883 + }
114884 + else
114885 +#endif
114886 + {
114887 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
114888 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114889 + }
114890 +
114891 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
114892 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114893 +
114894 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
114895 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114896 + }
114897 + break;
114898 +
114899 + default:
114900 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
114901 + }
114902 +
114903 + if (err)
114904 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
114905 +
114906 + return E_OK;
114907 +}
114908 +
114909 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
114910 +{
114911 + t_Error err = E_OK;
114912 +
114913 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
114914 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
114915 +
114916 + switch (cmd)
114917 + {
114918 + case FM_PORT_IOC_DISABLE:
114919 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
114920 + /* deliberately ignoring error codes here */
114921 + return E_OK;
114922 +
114923 + case FM_PORT_IOC_ENABLE:
114924 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
114925 + /* deliberately ignoring error codes here */
114926 + return E_OK;
114927 +
114928 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
114929 + {
114930 + ioc_fm_port_frame_err_select_t errs;
114931 +
114932 +#if defined(CONFIG_COMPAT)
114933 + if (compat)
114934 + {
114935 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
114936 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114937 + }
114938 + else
114939 +#endif
114940 + {
114941 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
114942 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114943 + }
114944 +
114945 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
114946 + break;
114947 + }
114948 +
114949 + case FM_PORT_IOC_SET_RATE_LIMIT:
114950 + {
114951 + ioc_fm_port_rate_limit_t *param;
114952 +
114953 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
114954 + if (!param)
114955 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
114956 +
114957 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
114958 +
114959 +#if defined(CONFIG_COMPAT)
114960 + if (compat)
114961 + {
114962 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
114963 + {
114964 + XX_Free(param);
114965 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114966 + }
114967 + }
114968 + else
114969 +#endif
114970 + {
114971 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
114972 + {
114973 + XX_Free(param);
114974 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114975 + }
114976 + }
114977 +
114978 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
114979 +
114980 + XX_Free(param);
114981 + break;
114982 + }
114983 +
114984 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
114985 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
114986 + /* deliberately ignoring error codes here */
114987 + return E_OK;
114988 +
114989 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
114990 + {
114991 + ioc_fm_port_pcd_fqids_params_t *param;
114992 +
114993 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
114994 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
114995 +
114996 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
114997 + if (!param)
114998 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
114999 +
115000 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
115001 +
115002 +#if defined(CONFIG_COMPAT)
115003 + if (compat)
115004 + {
115005 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115006 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115007 + {
115008 + XX_Free(param);
115009 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115010 + }
115011 + }
115012 + else
115013 +#endif
115014 + {
115015 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
115016 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115017 + {
115018 + XX_Free(param);
115019 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115020 + }
115021 + }
115022 +
115023 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
115024 + param->num_fqids,
115025 + param->alignment,
115026 + &param->base_fqid))
115027 + {
115028 + XX_Free(param);
115029 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
115030 + }
115031 +
115032 +#if defined(CONFIG_COMPAT)
115033 + if (compat)
115034 + {
115035 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115036 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115037 + err = E_READ_FAILED;
115038 + }
115039 + else
115040 +#endif
115041 + {
115042 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
115043 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115044 + err = E_READ_FAILED;
115045 + }
115046 +
115047 + XX_Free(param);
115048 + break;
115049 + }
115050 +
115051 + case FM_PORT_IOC_FREE_PCD_FQIDS:
115052 + {
115053 + uint32_t base_fqid;
115054 +
115055 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
115056 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115057 +
115058 +#if defined(CONFIG_COMPAT)
115059 + if (compat)
115060 + {
115061 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
115062 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115063 + }
115064 + else
115065 +#endif
115066 + {
115067 + if (get_user(base_fqid, (uint32_t*)arg))
115068 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115069 + }
115070 +
115071 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
115072 + err = E_WRITE_FAILED;
115073 +
115074 + break;
115075 + }
115076 +
115077 +#if defined(CONFIG_COMPAT)
115078 + case FM_PORT_IOC_SET_PCD_COMPAT:
115079 +#endif
115080 + case FM_PORT_IOC_SET_PCD:
115081 + {
115082 + ioc_fm_port_pcd_params_t *port_pcd_params;
115083 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
115084 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
115085 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
115086 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
115087 +
115088 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
115089 + sizeof(ioc_fm_port_pcd_params_t) +
115090 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115091 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115092 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115093 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115094 + if (!port_pcd_params)
115095 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115096 +
115097 + memset(port_pcd_params, 0,
115098 + sizeof(ioc_fm_port_pcd_params_t) +
115099 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115100 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115101 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115102 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115103 +
115104 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
115105 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
115106 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
115107 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
115108 +
115109 +#if defined(CONFIG_COMPAT)
115110 + if (compat)
115111 + {
115112 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
115113 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
115114 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
115115 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
115116 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
115117 +
115118 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
115119 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115120 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115121 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115122 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115123 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115124 + if (!compat_port_pcd_params)
115125 + {
115126 + XX_Free(port_pcd_params);
115127 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115128 + }
115129 +
115130 + memset(compat_port_pcd_params, 0,
115131 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115132 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115133 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115134 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115135 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115136 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
115137 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
115138 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
115139 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
115140 +
115141 + if (copy_from_user(compat_port_pcd_params,
115142 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
115143 + sizeof(ioc_compat_fm_port_pcd_params_t)))
115144 + err = E_WRITE_FAILED;
115145 +
115146 + while (!err) /* pseudo-while */
115147 + {
115148 + /* set pointers from where to copy from: */
115149 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
115150 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
115151 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
115152 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
115153 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
115154 +#if (DPAA_VERSION >= 11)
115155 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
115156 +#endif
115157 + /* the prs member is the same, no compat structure...memcpy only */
115158 + if (port_pcd_params->p_prs_params)
115159 + {
115160 + if (copy_from_user(same_port_pcd_prs_params,
115161 + port_pcd_params->p_prs_params,
115162 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115163 + {
115164 + err = E_WRITE_FAILED;
115165 + break; /* from pseudo-while */
115166 + }
115167 +
115168 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
115169 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115170 + }
115171 +
115172 + if (port_pcd_params->p_cc_params)
115173 + {
115174 + if (copy_from_user(compat_port_pcd_cc_params,
115175 + port_pcd_params->p_cc_params,
115176 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
115177 + {
115178 + err = E_WRITE_FAILED;
115179 + break; /* from pseudo-while */
115180 + }
115181 +
115182 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115183 + }
115184 +
115185 + if (port_pcd_params->p_kg_params)
115186 + {
115187 + if (copy_from_user(compat_port_pcd_kg_params,
115188 + port_pcd_params->p_kg_params,
115189 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
115190 + {
115191 + err = E_WRITE_FAILED;
115192 + break; /* from pseudo-while */
115193 + }
115194 +
115195 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115196 + }
115197 +
115198 + if (port_pcd_params->p_plcr_params)
115199 + {
115200 + if (copy_from_user(compat_port_pcd_plcr_params,
115201 + port_pcd_params->p_plcr_params,
115202 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
115203 + {
115204 + err = E_WRITE_FAILED;
115205 + break; /* from pseudo-while */
115206 + }
115207 +
115208 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115209 + }
115210 +
115211 + break; /* pseudo-while: always run once! */
115212 + }
115213 +
115214 + if (!err)
115215 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
115216 +
115217 + XX_Free(compat_port_pcd_params);
115218 + }
115219 + else
115220 +#endif
115221 + {
115222 + if (copy_from_user(port_pcd_params,
115223 + (ioc_fm_port_pcd_params_t*) arg,
115224 + sizeof(ioc_fm_port_pcd_params_t)))
115225 + err = E_WRITE_FAILED;
115226 +
115227 + while (!err) /* pseudo-while */
115228 + {
115229 + if (port_pcd_params->p_prs_params)
115230 + {
115231 + if (copy_from_user(port_pcd_prs_params,
115232 + port_pcd_params->p_prs_params,
115233 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115234 + {
115235 + err = E_WRITE_FAILED;
115236 + break; /* from pseudo-while */
115237 + }
115238 +
115239 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115240 + }
115241 +
115242 + if (port_pcd_params->p_cc_params)
115243 + {
115244 + if (copy_from_user(port_pcd_cc_params,
115245 + port_pcd_params->p_cc_params,
115246 + sizeof(ioc_fm_port_pcd_cc_params_t)))
115247 + {
115248 + err = E_WRITE_FAILED;
115249 + break; /* from pseudo-while */
115250 + }
115251 +
115252 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115253 + }
115254 +
115255 + if (port_pcd_params->p_kg_params)
115256 + {
115257 + if (copy_from_user(port_pcd_kg_params,
115258 + port_pcd_params->p_kg_params,
115259 + sizeof(ioc_fm_port_pcd_kg_params_t)))
115260 + {
115261 + err = E_WRITE_FAILED;
115262 + break; /* from pseudo-while */
115263 + }
115264 +
115265 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115266 + }
115267 +
115268 + if (port_pcd_params->p_plcr_params)
115269 + {
115270 + if (copy_from_user(port_pcd_plcr_params,
115271 + port_pcd_params->p_plcr_params,
115272 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
115273 + {
115274 + err = E_WRITE_FAILED;
115275 + break; /* from pseudo-while */
115276 + }
115277 +
115278 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115279 + }
115280 +
115281 + break; /* pseudo-while: always run once! */
115282 + }
115283 + }
115284 +
115285 + if (!err)
115286 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
115287 +
115288 + XX_Free(port_pcd_params);
115289 + break;
115290 + }
115291 +
115292 + case FM_PORT_IOC_DELETE_PCD:
115293 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
115294 + break;
115295 +
115296 +#if defined(CONFIG_COMPAT)
115297 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
115298 +#endif
115299 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
115300 + {
115301 + ioc_fm_pcd_kg_scheme_select_t *param;
115302 +
115303 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115304 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
115305 + if (!param)
115306 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115307 +
115308 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
115309 +
115310 +#if defined(CONFIG_COMPAT)
115311 + if (compat)
115312 + {
115313 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
115314 +
115315 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115316 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115317 + if (!compat_param)
115318 + {
115319 + XX_Free(param);
115320 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115321 + }
115322 +
115323 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115324 + if (copy_from_user(compat_param,
115325 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
115326 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
115327 + {
115328 + XX_Free(compat_param);
115329 + XX_Free(param);
115330 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115331 + }
115332 +
115333 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
115334 +
115335 + XX_Free(compat_param);
115336 + }
115337 + else
115338 +#endif
115339 + {
115340 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
115341 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
115342 + {
115343 + XX_Free(param);
115344 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115345 + }
115346 + }
115347 +
115348 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
115349 +
115350 + XX_Free(param);
115351 + break;
115352 + }
115353 +
115354 +#if defined(CONFIG_COMPAT)
115355 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
115356 +#endif
115357 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
115358 + {
115359 + ioc_fm_obj_t id;
115360 +
115361 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115362 +
115363 +#if defined(CONFIG_COMPAT)
115364 + if (compat)
115365 + {
115366 + ioc_compat_fm_obj_t compat_id;
115367 +
115368 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115369 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115370 +
115371 + id.obj = compat_ptr(compat_id.obj);
115372 + }
115373 + else
115374 +#endif
115375 + {
115376 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115377 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115378 + }
115379 +
115380 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
115381 + break;
115382 + }
115383 +
115384 +#if defined(CONFIG_COMPAT)
115385 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
115386 +#endif
115387 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
115388 + {
115389 + ioc_fm_pcd_port_schemes_params_t *param;
115390 +
115391 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115392 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115393 + if (!param)
115394 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115395 +
115396 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115397 +
115398 +#if defined(CONFIG_COMPAT)
115399 + if (compat)
115400 + {
115401 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115402 +
115403 + if (copy_from_user(&compat_param,
115404 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115405 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115406 + {
115407 + XX_Free(param);
115408 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115409 + }
115410 +
115411 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115412 + }
115413 + else
115414 +#endif
115415 + {
115416 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115417 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115418 + {
115419 + XX_Free(param);
115420 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115421 + }
115422 + }
115423 +
115424 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115425 +
115426 + XX_Free(param);
115427 + break;
115428 + }
115429 +
115430 +#if defined(CONFIG_COMPAT)
115431 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
115432 +#endif
115433 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
115434 + {
115435 + ioc_fm_pcd_port_schemes_params_t *param;
115436 +
115437 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115438 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115439 + if (!param)
115440 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115441 +
115442 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115443 +
115444 +#if defined(CONFIG_COMPAT)
115445 + if (compat)
115446 + {
115447 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115448 +
115449 + if (copy_from_user(&compat_param,
115450 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115451 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115452 + {
115453 + XX_Free(param);
115454 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115455 + }
115456 +
115457 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115458 + }
115459 + else
115460 +#endif
115461 + {
115462 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115463 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115464 + {
115465 + XX_Free(param);
115466 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115467 + }
115468 + }
115469 +
115470 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115471 +
115472 + XX_Free(param);
115473 + break;
115474 + }
115475 +
115476 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
115477 + {
115478 + uint16_t num;
115479 + if (get_user(num, (uint16_t*) arg))
115480 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115481 +
115482 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
115483 + break;
115484 + }
115485 +
115486 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
115487 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
115488 + break;
115489 +
115490 + case FM_PORT_IOC_DETACH_PCD:
115491 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
115492 + break;
115493 +
115494 + case FM_PORT_IOC_ATTACH_PCD:
115495 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
115496 + break;
115497 +
115498 +#if defined(CONFIG_COMPAT)
115499 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
115500 +#endif
115501 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
115502 + {
115503 + ioc_fm_obj_t id;
115504 +
115505 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115506 +
115507 +#if defined(CONFIG_COMPAT)
115508 + if (compat)
115509 + {
115510 + ioc_compat_fm_obj_t compat_id;
115511 +
115512 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115513 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115514 +
115515 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
115516 + }
115517 + else
115518 +#endif
115519 + {
115520 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115521 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115522 + }
115523 +
115524 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
115525 + break;
115526 + }
115527 +
115528 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
115529 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
115530 + {
115531 + ioc_fm_port_congestion_groups_t *param;
115532 +
115533 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
115534 + if (!param)
115535 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115536 +
115537 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
115538 +
115539 +#if defined(CONFIG_COMPAT)
115540 + if (compat)
115541 + {
115542 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
115543 + sizeof(t_FmPortCongestionGrps)))
115544 + {
115545 + XX_Free(param);
115546 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115547 + }
115548 + }
115549 + else
115550 +#endif /* CONFIG_COMPAT */
115551 + {
115552 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
115553 + sizeof(t_FmPortCongestionGrps)))
115554 + {
115555 + XX_Free(param);
115556 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115557 + }
115558 + }
115559 +
115560 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
115561 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115562 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115563 + ;
115564 +
115565 + XX_Free(param);
115566 + break;
115567 + }
115568 +
115569 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
115570 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
115571 + {
115572 + ioc_fm_port_mac_addr_params_t *param;
115573 +
115574 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
115575 + sizeof(ioc_fm_port_mac_addr_params_t));
115576 + if (!param)
115577 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115578 +
115579 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
115580 +
115581 +#if defined(CONFIG_COMPAT)
115582 + if (compat)
115583 + {
115584 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
115585 + sizeof(ioc_fm_port_mac_addr_params_t)))
115586 + {
115587 + XX_Free(param);
115588 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115589 + }
115590 + }
115591 + else
115592 +#endif /* CONFIG_COMPAT */
115593 + {
115594 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
115595 + sizeof(ioc_fm_port_mac_addr_params_t)))
115596 + {
115597 + XX_Free(param);
115598 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115599 + }
115600 + }
115601 +
115602 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
115603 + {
115604 + int id = -1;
115605 +
115606 + switch(p_LnxWrpFmPortDev->settings.param.portType)
115607 + {
115608 + case e_FM_PORT_TYPE_RX:
115609 + case e_FM_PORT_TYPE_TX:
115610 + id = p_LnxWrpFmPortDev->id;
115611 + break;
115612 + case e_FM_PORT_TYPE_RX_10G:
115613 + case e_FM_PORT_TYPE_TX_10G:
115614 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
115615 + break;
115616 + default:
115617 + err = E_NOT_AVAILABLE;
115618 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
115619 + }
115620 + if (id >= 0)
115621 + {
115622 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115623 + t_Handle mac_handle = fm->macs[id].h_Dev;
115624 +
115625 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
115626 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
115627 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
115628 + }
115629 + }
115630 + else
115631 + {
115632 + err = E_NOT_AVAILABLE;
115633 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
115634 + }
115635 +
115636 + XX_Free(param);
115637 + break;
115638 + }
115639 +
115640 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
115641 + {
115642 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115643 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115644 + ioc_fm_port_tx_pause_frames_params_t param;
115645 + int mac_id = p_LnxWrpFmPortDev->id;
115646 +
115647 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
115648 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115649 +
115650 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
115651 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
115652 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115653 +
115654 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
115655 + {
115656 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115657 + param.priority,
115658 + param.pause_time,
115659 + param.thresh_time);
115660 + }
115661 + else
115662 + {
115663 + err = E_NOT_AVAILABLE;
115664 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
115665 + }
115666 +
115667 + break;
115668 + }
115669 +
115670 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
115671 + {
115672 + ioc_fm_buffer_prefix_content_t *param;
115673 +
115674 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
115675 + if (!param)
115676 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115677 +
115678 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
115679 +
115680 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
115681 + sizeof(ioc_fm_buffer_prefix_content_t)))
115682 + {
115683 + XX_Free(param);
115684 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115685 + }
115686 +
115687 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
115688 + (t_FmBufferPrefixContent *)param))
115689 + {
115690 + XX_Free(param);
115691 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115692 + }
115693 +
115694 + XX_Free(param);
115695 + break;
115696 + }
115697 +
115698 +#if (DPAA_VERSION >= 11)
115699 +#if defined(CONFIG_COMPAT)
115700 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
115701 +#endif
115702 + case FM_PORT_IOC_VSP_ALLOC:
115703 + {
115704 + ioc_fm_port_vsp_alloc_params_t *param;
115705 + t_LnxWrpFmDev *p_LnxWrpFmDev;
115706 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
115707 +
115708 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
115709 + sizeof(ioc_fm_port_vsp_alloc_params_t));
115710 + if (!param)
115711 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115712 +
115713 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
115714 +
115715 +#if defined(CONFIG_COMPAT)
115716 + if (compat)
115717 + {
115718 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
115719 +
115720 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
115721 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
115722 + if (!compat_param)
115723 + {
115724 + XX_Free(param);
115725 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115726 + }
115727 +
115728 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
115729 + if (copy_from_user(compat_param,
115730 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
115731 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
115732 + {
115733 + XX_Free(compat_param);
115734 + XX_Free(param);
115735 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115736 + }
115737 +
115738 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
115739 +
115740 + XX_Free(compat_param);
115741 + }
115742 + else
115743 +#endif
115744 + {
115745 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
115746 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
115747 + {
115748 + XX_Free(param);
115749 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115750 + }
115751 + }
115752 +
115753 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
115754 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
115755 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
115756 + {
115757 + /* Determine the Tx port t_Handle from the Rx port id */
115758 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115759 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
115760 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
115761 + }
115762 +
115763 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
115764 + {
115765 + XX_Free(param);
115766 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115767 + }
115768 +
115769 + XX_Free(param);
115770 + break;
115771 + }
115772 +#endif /* (DPAA_VERSION >= 11) */
115773 +
115774 + case FM_PORT_IOC_GET_MAC_STATISTICS:
115775 + {
115776 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115777 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115778 + ioc_fm_port_mac_statistics_t param;
115779 + int mac_id = p_LnxWrpFmPortDev->id;
115780 +
115781 + if (!p_LnxWrpFmDev)
115782 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115783 +
115784 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
115785 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
115786 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
115787 +
115788 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
115789 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115790 +
115791 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
115792 + (t_FmMacStatistics *)&param))
115793 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115794 +
115795 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
115796 + sizeof(ioc_fm_port_mac_statistics_t)))
115797 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115798 +
115799 + break;
115800 + }
115801 +
115802 + case FM_PORT_IOC_GET_BMI_COUNTERS:
115803 + {
115804 + t_LnxWrpFmDev *p_LnxWrpFmDev =
115805 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
115806 + ioc_fm_port_bmi_stats_t param;
115807 +
115808 + if (!p_LnxWrpFmDev)
115809 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
115810 +
115811 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
115812 + (t_FmPortBmiStats *)&param))
115813 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115814 +
115815 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
115816 + sizeof(ioc_fm_port_bmi_stats_t)))
115817 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115818 +
115819 + break;
115820 + }
115821 +
115822 + default:
115823 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
115824 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
115825 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
115826 + }
115827 +
115828 + if (err)
115829 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
115830 +
115831 + return E_OK;
115832 +}
115833 +
115834 +/*****************************************************************************/
115835 +/* API routines for the FM Linux Device */
115836 +/*****************************************************************************/
115837 +
115838 +static int fm_open(struct inode *inode, struct file *file)
115839 +{
115840 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
115841 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
115842 + unsigned int major = imajor(inode);
115843 + unsigned int minor = iminor(inode);
115844 + struct device_node *fm_node;
115845 + static struct of_device_id fm_node_of_match[] = {
115846 + { .compatible = "fsl,fman", },
115847 + { /* end of list */ },
115848 + };
115849 +
115850 + DBG(TRACE, ("Opening minor - %d - ", minor));
115851 +
115852 + if (file->private_data != NULL)
115853 + return 0;
115854 +
115855 + /* Get all the FM nodes */
115856 + for_each_matching_node(fm_node, fm_node_of_match) {
115857 + struct platform_device *of_dev;
115858 +
115859 + of_dev = of_find_device_by_node(fm_node);
115860 + if (unlikely(of_dev == NULL)) {
115861 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
115862 + return -ENXIO;
115863 + }
115864 +
115865 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
115866 + if (p_LnxWrpFmDev->major == major)
115867 + break;
115868 + fm_unbind((struct fm *)p_LnxWrpFmDev);
115869 + p_LnxWrpFmDev = NULL;
115870 + }
115871 +
115872 + if (!p_LnxWrpFmDev)
115873 + return -ENODEV;
115874 +
115875 + if (minor == DEV_FM_MINOR_BASE)
115876 + file->private_data = p_LnxWrpFmDev;
115877 + else if (minor == DEV_FM_PCD_MINOR_BASE)
115878 + file->private_data = p_LnxWrpFmDev;
115879 + else {
115880 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
115881 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
115882 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
115883 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
115884 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
115885 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
115886 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
115887 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
115888 + else
115889 + return -EINVAL;
115890 +
115891 + /* if trying to open port, check if it initialized */
115892 + if (!p_LnxWrpFmPortDev->h_Dev)
115893 + return -ENODEV;
115894 +
115895 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
115896 + file->private_data = p_LnxWrpFmPortDev;
115897 + fm_unbind((struct fm *)p_LnxWrpFmDev);
115898 + }
115899 +
115900 + if (file->private_data == NULL)
115901 + return -ENXIO;
115902 +
115903 + return 0;
115904 +}
115905 +
115906 +static int fm_close(struct inode *inode, struct file *file)
115907 +{
115908 + t_LnxWrpFmDev *p_LnxWrpFmDev;
115909 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
115910 + unsigned int minor = iminor(inode);
115911 + int err = 0;
115912 +
115913 + DBG(TRACE, ("Closing minor - %d - ", minor));
115914 +
115915 + if ((minor == DEV_FM_MINOR_BASE) ||
115916 + (minor == DEV_FM_PCD_MINOR_BASE))
115917 + {
115918 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
115919 + if (!p_LnxWrpFmDev)
115920 + return -ENODEV;
115921 + fm_unbind((struct fm *)p_LnxWrpFmDev);
115922 + }
115923 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
115924 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
115925 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
115926 + {
115927 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
115928 + if (!p_LnxWrpFmPortDev)
115929 + return -ENODEV;
115930 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
115931 + }
115932 +
115933 + return err;
115934 +}
115935 +
115936 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
115937 +{
115938 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
115939 +
115940 + if ((minor == DEV_FM_MINOR_BASE) ||
115941 + (minor == DEV_FM_PCD_MINOR_BASE))
115942 + {
115943 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
115944 + if (!p_LnxWrpFmDev)
115945 + return -ENODEV;
115946 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
115947 + return -EFAULT;
115948 + }
115949 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
115950 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
115951 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
115952 + {
115953 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
115954 + if (!p_LnxWrpFmPortDev)
115955 + return -ENODEV;
115956 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
115957 + return -EFAULT;
115958 + }
115959 + else
115960 + {
115961 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
115962 + return -ENODEV;
115963 + }
115964 +
115965 + return 0;
115966 +}
115967 +
115968 +#ifdef CONFIG_COMPAT
115969 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
115970 +{
115971 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
115972 + long res;
115973 +
115974 + fm_mutex_lock();
115975 + res = fm_ioctls(minor, file, cmd, arg, true);
115976 + fm_mutex_unlock();
115977 +
115978 + return res;
115979 +}
115980 +#endif
115981 +
115982 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
115983 +{
115984 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
115985 + long res;
115986 +
115987 + fm_mutex_lock();
115988 + res = fm_ioctls(minor, file, cmd, arg, false);
115989 + fm_mutex_unlock();
115990 +
115991 + return res;
115992 +}
115993 +
115994 +/* Globals for FM character device */
115995 +struct file_operations fm_fops =
115996 +{
115997 + .owner = THIS_MODULE,
115998 + .unlocked_ioctl = fm_ioctl,
115999 +#ifdef CONFIG_COMPAT
116000 + .compat_ioctl = fm_compat_ioctl,
116001 +#endif
116002 + .open = fm_open,
116003 + .release = fm_close,
116004 +};
116005 --- /dev/null
116006 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116007 @@ -0,0 +1,1297 @@
116008 +/*
116009 + * Copyright 2008-2012 Freescale Semiconductor Inc.
116010 + *
116011 + * Redistribution and use in source and binary forms, with or without
116012 + * modification, are permitted provided that the following conditions are met:
116013 + * * Redistributions of source code must retain the above copyright
116014 + * notice, this list of conditions and the following disclaimer.
116015 + * * Redistributions in binary form must reproduce the above copyright
116016 + * notice, this list of conditions and the following disclaimer in the
116017 + * documentation and/or other materials provided with the distribution.
116018 + * * Neither the name of Freescale Semiconductor nor the
116019 + * names of its contributors may be used to endorse or promote products
116020 + * derived from this software without specific prior written permission.
116021 + *
116022 + *
116023 + * ALTERNATIVELY, this software may be distributed under the terms of the
116024 + * GNU General Public License ("GPL") as published by the Free Software
116025 + * Foundation, either version 2 of that License or (at your option) any
116026 + * later version.
116027 + *
116028 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
116029 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
116030 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116031 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
116032 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
116033 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
116034 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
116035 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116036 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116037 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116038 + */
116039 +
116040 +/*
116041 + @File lnxwrp_fm_compat_ioctls.c
116042 +
116043 + @Description FM PCD compat functions
116044 +
116045 +*/
116046 +
116047 +#if !defined(CONFIG_COMPAT)
116048 +#error "missing COMPAT layer..."
116049 +#endif
116050 +
116051 +
116052 +#include <linux/kernel.h>
116053 +#include <linux/module.h>
116054 +#include <linux/fs.h>
116055 +#include <linux/cdev.h>
116056 +#include <linux/device.h>
116057 +#include <linux/irq.h>
116058 +#include <linux/interrupt.h>
116059 +#include <linux/io.h>
116060 +#include <linux/ioport.h>
116061 +#include <asm/uaccess.h>
116062 +#include <asm/errno.h>
116063 +#ifndef CONFIG_FMAN_ARM
116064 +#include <sysdev/fsl_soc.h>
116065 +#endif
116066 +
116067 +#include "part_ext.h"
116068 +#include "fm_ioctls.h"
116069 +#include "fm_pcd_ioctls.h"
116070 +#include "fm_port_ioctls.h"
116071 +#include "lnxwrp_ioctls_fm_compat.h"
116072 +
116073 +#if defined(FM_COMPAT_DBG)
116074 +static void hex_dump(void * p_addr, unsigned int size)
116075 +{
116076 + int i;
116077 +
116078 + for(i=0; i<size; i+=16)
116079 + {
116080 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
116081 + *(unsigned int *)(p_addr + i),
116082 + *(unsigned int *)(p_addr + i + 4),
116083 + *(unsigned int *)(p_addr + i + 8),
116084 + *(unsigned int *)(p_addr + i +12)
116085 + );
116086 + }
116087 +}
116088 +#endif
116089 +
116090 +/* maping kernel pointers w/ UserSpace id's { */
116091 +struct map_node {
116092 + void *ptr;
116093 + u8 node_type;
116094 +};
116095 +
116096 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
116097 +
116098 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
116099 +{
116100 + compat_uptr_t k;
116101 +
116102 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
116103 +
116104 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116105 + if(compat_ptr2id_array[k].ptr == p){
116106 + compat_ptr2id_array[k].ptr = NULL;
116107 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
116108 + }
116109 +}
116110 +EXPORT_SYMBOL(compat_del_ptr2id);
116111 +
116112 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
116113 +{
116114 + compat_uptr_t k;
116115 +
116116 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
116117 +
116118 + if(!p)
116119 + return 0;
116120 +
116121 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116122 + if(compat_ptr2id_array[k].ptr == NULL)
116123 + {
116124 + compat_ptr2id_array[k].ptr = p;
116125 + compat_ptr2id_array[k].node_type = node_type;
116126 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
116127 + return k | COMPAT_PTR2ID_WATERMARK;
116128 + }
116129 +
116130 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
116131 + return 0;
116132 +}
116133 +EXPORT_SYMBOL(compat_add_ptr2id);
116134 +
116135 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
116136 +{
116137 + compat_uptr_t k;
116138 +
116139 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
116140 +
116141 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116142 + if(compat_ptr2id_array[k].ptr == p &&
116143 + compat_ptr2id_array[k].node_type == node_type) {
116144 +
116145 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
116146 + return k | COMPAT_PTR2ID_WATERMARK;
116147 + }
116148 +
116149 + return 0;
116150 +}
116151 +EXPORT_SYMBOL(compat_get_ptr2id);
116152 +
116153 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
116154 +{
116155 +
116156 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
116157 +
116158 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
116159 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
116160 + dump_stack();
116161 + return compat_ptr(comp);
116162 + }
116163 +
116164 + comp &= ~COMPAT_PTR2ID_WM_MASK;
116165 +
116166 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
116167 + && compat_ptr2id_array[comp].node_type == node_type)) {
116168 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
116169 + return compat_ptr2id_array[comp].ptr;
116170 + }
116171 + return NULL;
116172 +}
116173 +EXPORT_SYMBOL(compat_get_id2ptr);
116174 +/* } maping kernel pointers w/ UserSpace id's */
116175 +
116176 +void compat_obj_delete(
116177 + ioc_compat_fm_obj_t *compat_id,
116178 + ioc_fm_obj_t *id)
116179 +{
116180 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116181 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
116182 +}
116183 +
116184 +static inline void compat_copy_fm_pcd_plcr_next_engine(
116185 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
116186 + ioc_fm_pcd_plcr_next_engine_params_u *param,
116187 + ioc_fm_pcd_engine next_engine,
116188 + uint8_t compat)
116189 +{
116190 + _fm_cpt_dbg (compat, " {->...\n");
116191 +
116192 + switch (next_engine)
116193 + {
116194 + case e_IOC_FM_PCD_PLCR:
116195 + if (compat == COMPAT_US_TO_K)
116196 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
116197 + else
116198 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
116199 + break;
116200 + case e_IOC_FM_PCD_KG:
116201 + if (compat == COMPAT_US_TO_K)
116202 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116203 + else
116204 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116205 + break;
116206 + default:
116207 + if (compat == COMPAT_US_TO_K)
116208 + param->action = compat_param->action;
116209 + else
116210 + compat_param->action = param->action;
116211 + break;
116212 + }
116213 +
116214 + _fm_cpt_dbg (compat, " ...->}\n");
116215 +}
116216 +
116217 +void compat_copy_fm_pcd_plcr_profile(
116218 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
116219 + ioc_fm_pcd_plcr_profile_params_t *param,
116220 + uint8_t compat)
116221 +{
116222 + _fm_cpt_dbg (compat, " {->...\n");
116223 +
116224 + if (compat == COMPAT_US_TO_K)
116225 + {
116226 + param->modify = compat_param->modify;
116227 +
116228 + /* profile_select */
116229 + if (!compat_param->modify)
116230 + {
116231 + param->profile_select.new_params.profile_type =
116232 + compat_param->profile_select.new_params.profile_type;
116233 + param->profile_select.new_params.p_fm_port =
116234 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
116235 + param->profile_select.new_params.relative_profile_id =
116236 + compat_param->profile_select.new_params.relative_profile_id;
116237 + }
116238 + else
116239 + param->profile_select.p_profile =
116240 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
116241 +
116242 + param->alg_selection = compat_param->alg_selection;
116243 + param->color_mode = compat_param->color_mode;
116244 +
116245 + /* both parameters in the union has the same size, so memcpy works */
116246 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
116247 +
116248 + memcpy(&param->non_passthrough_alg_param,
116249 + &compat_param->non_passthrough_alg_param,
116250 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116251 +
116252 + param->next_engine_on_green = compat_param->next_engine_on_green;
116253 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
116254 + param->next_engine_on_red = compat_param->next_engine_on_red;
116255 +
116256 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
116257 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
116258 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
116259 + }
116260 + else
116261 + {
116262 + compat_param->modify = param->modify;
116263 +
116264 + /* profile_select */
116265 + if (!param->modify)
116266 + {
116267 + compat_param->profile_select.new_params.profile_type =
116268 + param->profile_select.new_params.profile_type;
116269 + compat_param->profile_select.new_params.p_fm_port =
116270 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
116271 + compat_param->profile_select.new_params.relative_profile_id =
116272 + param->profile_select.new_params.relative_profile_id;
116273 + }
116274 + else
116275 + compat_param->profile_select.p_profile =
116276 + compat_pcd_ptr2id(param->profile_select.p_profile);
116277 +
116278 + compat_param->alg_selection = param->alg_selection;
116279 + compat_param->color_mode = param->color_mode;
116280 +
116281 + /* both parameters in the union has the same size, so memcpy works */
116282 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
116283 +
116284 + memcpy(&compat_param->non_passthrough_alg_param,
116285 + &param->non_passthrough_alg_param,
116286 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116287 +
116288 + compat_param->next_engine_on_green = param->next_engine_on_green;
116289 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
116290 + compat_param->next_engine_on_red = param->next_engine_on_red;
116291 +
116292 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
116293 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
116294 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
116295 +
116296 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116297 + }
116298 +
116299 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
116300 + &param->params_on_green, param->next_engine_on_green, compat);
116301 +
116302 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
116303 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
116304 +
116305 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
116306 + &param->params_on_red, param->next_engine_on_red, compat);
116307 +
116308 + _fm_cpt_dbg (compat, " ...->}\n");
116309 +}
116310 +
116311 +static inline void compat_copy_fm_pcd_cc_next_kg(
116312 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
116313 + ioc_fm_pcd_cc_next_kg_params_t *param,
116314 + uint8_t compat)
116315 +{
116316 + _fm_cpt_dbg (compat, " {->...\n");
116317 +
116318 + if (compat == COMPAT_US_TO_K)
116319 + {
116320 + param->new_fqid = compat_param->new_fqid;
116321 + param->override_fqid = compat_param->override_fqid;
116322 +#if DPAA_VERSION >= 11
116323 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
116324 +#endif
116325 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116326 + }
116327 + else
116328 + {
116329 + compat_param->new_fqid = param->new_fqid;
116330 + compat_param->override_fqid = param->override_fqid;
116331 +#if DPAA_VERSION >= 11
116332 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
116333 +#endif
116334 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116335 + }
116336 +
116337 + _fm_cpt_dbg (compat, " ...->}\n");
116338 +}
116339 +
116340 +static inline void compat_copy_fm_pcd_cc_next_cc(
116341 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
116342 + ioc_fm_pcd_cc_next_cc_params_t *param,
116343 + uint8_t compat)
116344 +{
116345 + _fm_cpt_dbg (compat, " {->...\n");
116346 +
116347 + if (compat == COMPAT_US_TO_K)
116348 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
116349 + else
116350 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
116351 +
116352 + _fm_cpt_dbg (compat, " ...->}\n");
116353 +}
116354 +
116355 +static inline void compat_copy_fm_pcd_cc_next_engine(
116356 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
116357 + ioc_fm_pcd_cc_next_engine_params_t *param,
116358 + uint8_t compat)
116359 +{
116360 + _fm_cpt_dbg (compat, " {->...\n");
116361 +
116362 + if (compat == COMPAT_US_TO_K)
116363 + {
116364 + param->next_engine = compat_param->next_engine;
116365 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
116366 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
116367 +
116368 + switch (param->next_engine)
116369 + {
116370 +#if DPAA_VERSION >= 11
116371 + case e_IOC_FM_PCD_FR:
116372 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
116373 + break;
116374 +#endif /* DPAA_VERSION >= 11 */
116375 + case e_IOC_FM_PCD_CC:
116376 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116377 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116378 + break;
116379 + case e_IOC_FM_PCD_KG:
116380 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116381 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116382 + break;
116383 + case e_IOC_FM_PCD_DONE:
116384 + case e_IOC_FM_PCD_PLCR:
116385 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116386 + default:
116387 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
116388 + }
116389 + param->statistics_en = compat_param->statistics_en;
116390 + }
116391 + else
116392 + {
116393 + compat_param->next_engine = param->next_engine;
116394 +
116395 + switch (compat_param->next_engine)
116396 + {
116397 +#if DPAA_VERSION >= 11
116398 + case e_IOC_FM_PCD_FR:
116399 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
116400 + break;
116401 +#endif /* DPAA_VERSION >= 11 */
116402 + case e_IOC_FM_PCD_CC:
116403 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116404 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116405 + break;
116406 + case e_IOC_FM_PCD_KG:
116407 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116408 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116409 + break;
116410 + case e_IOC_FM_PCD_DONE:
116411 + case e_IOC_FM_PCD_PLCR:
116412 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116413 + default:
116414 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
116415 + }
116416 + compat_param->statistics_en = param->statistics_en;
116417 + }
116418 +
116419 + _fm_cpt_dbg (compat, " ...->}\n");
116420 +}
116421 +
116422 +void compat_copy_fm_pcd_cc_key(
116423 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
116424 + ioc_fm_pcd_cc_key_params_t *param,
116425 + uint8_t compat)
116426 +{
116427 + if (compat == COMPAT_US_TO_K)
116428 + {
116429 + param->p_key = compat_ptr(compat_param->p_key);
116430 + param->p_mask = compat_ptr(compat_param->p_mask);
116431 + }
116432 + else
116433 + {
116434 + compat_param->p_key = ptr_to_compat(param->p_key);
116435 + compat_param->p_mask = ptr_to_compat(param->p_mask);
116436 + }
116437 +
116438 + compat_copy_fm_pcd_cc_next_engine(
116439 + &compat_param->cc_next_engine_params,
116440 + &param->cc_next_engine_params,
116441 + compat);
116442 +}
116443 +
116444 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
116445 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
116446 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
116447 + uint8_t compat)
116448 +{
116449 + if (compat == COMPAT_US_TO_K)
116450 + {
116451 + param->id = compat_pcd_id2ptr(compat_param->id);
116452 + param->key_indx = compat_param->key_indx;
116453 + param->key_size = compat_param->key_size;
116454 + compat_copy_fm_pcd_cc_key(
116455 + &compat_param->key_params,
116456 + &param->key_params,
116457 + compat);
116458 + }
116459 + else
116460 + {
116461 + compat_param->id = compat_pcd_ptr2id(param->id);
116462 + compat_param->key_indx = param->key_indx;
116463 + compat_param->key_size = param->key_size;
116464 + compat_copy_fm_pcd_cc_key(
116465 + &compat_param->key_params,
116466 + &param->key_params,
116467 + compat);
116468 + }
116469 +}
116470 +
116471 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
116472 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
116473 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
116474 + uint8_t compat)
116475 +{
116476 + if (compat == COMPAT_US_TO_K)
116477 + {
116478 + param->id = compat_pcd_id2ptr(compat_param->id);
116479 + param->key_indx = compat_param->key_indx;
116480 + param->key_size = compat_param->key_size;
116481 + }
116482 + else
116483 + {
116484 + compat_param->id = compat_pcd_ptr2id(param->id);
116485 + compat_param->key_indx = param->key_indx;
116486 + compat_param->key_size = param->key_size;
116487 + }
116488 +
116489 + compat_copy_fm_pcd_cc_next_engine(
116490 + &compat_param->cc_next_engine_params,
116491 + &param->cc_next_engine_params,
116492 + compat);
116493 +}
116494 +
116495 +void compat_fm_pcd_cc_tree_modify_next_engine(
116496 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
116497 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
116498 + uint8_t compat)
116499 +{
116500 + if (compat == COMPAT_US_TO_K)
116501 + {
116502 + param->id = compat_pcd_id2ptr(compat_param->id);
116503 + param->grp_indx = compat_param->grp_indx;
116504 + param->indx = compat_param->indx;
116505 + }
116506 + else
116507 + {
116508 + compat_param->id = compat_pcd_ptr2id(param->id);
116509 + compat_param->grp_indx = param->grp_indx;
116510 + compat_param->indx = param->indx;
116511 + }
116512 +
116513 + compat_copy_fm_pcd_cc_next_engine(
116514 + &compat_param->cc_next_engine_params,
116515 + &param->cc_next_engine_params,
116516 + compat);
116517 +}
116518 +
116519 +void compat_copy_fm_pcd_hash_table(
116520 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
116521 + ioc_fm_pcd_hash_table_params_t *param,
116522 + uint8_t compat)
116523 +{
116524 + if (compat == COMPAT_US_TO_K)
116525 + {
116526 + param->max_num_of_keys = compat_param->max_num_of_keys;
116527 + param->statistics_mode = compat_param->statistics_mode;
116528 + param->kg_hash_shift = compat_param->kg_hash_shift;
116529 + param->hash_res_mask = compat_param->hash_res_mask;
116530 + param->hash_shift = compat_param->hash_shift;
116531 + param->match_key_size = compat_param->match_key_size;
116532 + param->id = compat_pcd_id2ptr(compat_param->id);
116533 + }
116534 + else
116535 + {
116536 + compat_param->max_num_of_keys = param->max_num_of_keys;
116537 + compat_param->statistics_mode = param->statistics_mode;
116538 + compat_param->kg_hash_shift = param->kg_hash_shift;
116539 + compat_param->hash_res_mask = param->hash_res_mask;
116540 + compat_param->hash_shift = param->hash_shift;
116541 + compat_param->match_key_size = param->match_key_size;
116542 +
116543 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116544 + }
116545 +
116546 + compat_copy_fm_pcd_cc_next_engine(
116547 + &compat_param->cc_next_engine_params_for_miss,
116548 + &param->cc_next_engine_params_for_miss,
116549 + compat);
116550 +}
116551 +
116552 +void compat_copy_fm_pcd_cc_grp(
116553 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
116554 + ioc_fm_pcd_cc_grp_params_t *param,
116555 + uint8_t compat)
116556 +{
116557 + int k;
116558 +
116559 + _fm_cpt_dbg (compat, " {->...\n");
116560 +
116561 + if (compat == COMPAT_US_TO_K)
116562 + {
116563 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
116564 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
116565 + }
116566 + else
116567 + {
116568 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
116569 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
116570 + }
116571 +
116572 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
116573 + compat_copy_fm_pcd_cc_next_engine(
116574 + &compat_param->next_engine_per_entries_in_grp[k],
116575 + &param->next_engine_per_entries_in_grp[k],
116576 + compat);
116577 +
116578 + _fm_cpt_dbg (compat, " ...->}\n");
116579 +}
116580 +
116581 +void compat_copy_fm_pcd_cc_tree(
116582 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
116583 + ioc_fm_pcd_cc_tree_params_t *param,
116584 + uint8_t compat)
116585 +{
116586 + int k;
116587 + _fm_cpt_dbg (compat, " {->...\n");
116588 +
116589 + if (compat == COMPAT_US_TO_K)
116590 + {
116591 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
116592 + param->num_of_groups = compat_param->num_of_groups;
116593 + }
116594 + else
116595 + {
116596 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
116597 + compat_param->num_of_groups = param->num_of_groups;
116598 +
116599 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116600 + }
116601 +
116602 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
116603 + compat_copy_fm_pcd_cc_grp(
116604 + &compat_param->fm_pcd_cc_group_params[k],
116605 + &param->fm_pcd_cc_group_params[k],
116606 + compat);
116607 +
116608 + _fm_cpt_dbg (compat, " ...->}\n");
116609 +}
116610 +
116611 +void compat_fm_pcd_prs_sw(
116612 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
116613 + ioc_fm_pcd_prs_sw_params_t *param,
116614 + uint8_t compat)
116615 +{
116616 + if (compat == COMPAT_US_TO_K)
116617 + {
116618 + param->override = compat_param->override;
116619 + param->size = compat_param->size;
116620 + param->base = compat_param->base;
116621 + param->p_code = compat_ptr(compat_param->p_code);
116622 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
116623 + param->num_of_labels = compat_param->num_of_labels;
116624 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
116625 + }
116626 +}
116627 +
116628 +void compat_copy_fm_pcd_kg_scheme(
116629 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
116630 + ioc_fm_pcd_kg_scheme_params_t *param,
116631 + uint8_t compat)
116632 +{
116633 + _fm_cpt_dbg(compat," {->...\n");
116634 +
116635 + if (compat == COMPAT_US_TO_K)
116636 + {
116637 + param->modify = compat_param->modify;
116638 +
116639 + /* scm_id */
116640 + if (compat_param->modify)
116641 + {
116642 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
116643 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
116644 + }
116645 + else
116646 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
116647 +
116648 + param->always_direct = compat_param->always_direct;
116649 + /* net_env_params */
116650 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
116651 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
116652 + memcpy(param->net_env_params.unit_ids,
116653 + compat_param->net_env_params.unit_ids,
116654 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116655 +
116656 + param->use_hash = compat_param->use_hash;
116657 + memcpy(&param->key_extract_and_hash_params,
116658 + &compat_param->key_extract_and_hash_params,
116659 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
116660 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
116661 + param->base_fqid = compat_param->base_fqid;
116662 +#if DPAA_VERSION >= 11
116663 + param->override_storage_profile =
116664 + compat_param->override_storage_profile;
116665 + param->storage_profile = compat_param->storage_profile;
116666 +#endif
116667 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
116668 + memcpy(param->extracted_ors,
116669 + compat_param->extracted_ors,
116670 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
116671 + param->next_engine = compat_param->next_engine;
116672 +
116673 + /* kg_next_engine_params */
116674 + if (param->next_engine == e_IOC_FM_PCD_CC)
116675 + {
116676 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
116677 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
116678 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
116679 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
116680 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
116681 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
116682 + &compat_param->kg_next_engine_params.cc.plcr_profile,
116683 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
116684 + }
116685 + else
116686 + memcpy(&param->kg_next_engine_params,
116687 + &compat_param->kg_next_engine_params,
116688 + sizeof(param->kg_next_engine_params));
116689 +
116690 + memcpy(&param->scheme_counter,
116691 + &compat_param->scheme_counter,
116692 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
116693 + }
116694 + else
116695 + {
116696 + compat_param->modify = param->modify;
116697 +
116698 + /* scm_id */
116699 + if (param->modify)
116700 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
116701 + else
116702 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
116703 +
116704 + compat_param->always_direct = param->always_direct;
116705 +
116706 + /* net_env_params */
116707 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
116708 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
116709 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116710 +
116711 + compat_param->use_hash = param->use_hash;
116712 + 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));
116713 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
116714 + compat_param->base_fqid = param->base_fqid;
116715 +#if DPAA_VERSION >= 11
116716 + compat_param->override_storage_profile =
116717 + param->override_storage_profile;
116718 + compat_param->storage_profile = param->storage_profile;
116719 +#endif
116720 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
116721 + 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));
116722 + compat_param->next_engine = param->next_engine;
116723 +
116724 + /* kg_next_engine_params */
116725 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
116726 + {
116727 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
116728 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
116729 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
116730 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
116731 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
116732 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
116733 + &param->kg_next_engine_params.cc.plcr_profile,
116734 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
116735 + }
116736 + else
116737 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
116738 +
116739 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
116740 +
116741 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116742 + }
116743 +
116744 + _fm_cpt_dbg(compat," ...->}\n");
116745 +}
116746 +
116747 +void compat_copy_fm_pcd_kg_scheme_spc(
116748 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
116749 + ioc_fm_pcd_kg_scheme_spc_t *param,
116750 + uint8_t compat)
116751 +{
116752 + if (compat == COMPAT_US_TO_K)
116753 + {
116754 + param->id = compat_pcd_id2ptr(compat_param->id);
116755 + param->val = compat_param->val;
116756 + } else {
116757 + compat_param->id = compat_pcd_ptr2id(param->id);
116758 + compat_param->val = param->val;
116759 + }
116760 +}
116761 +
116762 +
116763 +void compat_copy_fm_pcd_kg_scheme_select(
116764 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
116765 + ioc_fm_pcd_kg_scheme_select_t *param,
116766 + uint8_t compat)
116767 +{
116768 + if (compat == COMPAT_US_TO_K)
116769 + {
116770 + param->direct = compat_param->direct;
116771 + if (param->direct)
116772 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
116773 + }
116774 +}
116775 +
116776 +void compat_copy_fm_pcd_kg_schemes_params(
116777 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
116778 + ioc_fm_pcd_port_schemes_params_t *param,
116779 + uint8_t compat)
116780 +{
116781 + int k;
116782 +
116783 + if (compat == COMPAT_US_TO_K) {
116784 + param->num_of_schemes = compat_param->num_of_schemes;
116785 + for(k=0; k < compat_param->num_of_schemes; k++)
116786 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
116787 + }
116788 +}
116789 +
116790 +void compat_copy_fm_port_pcd_cc(
116791 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
116792 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
116793 + uint8_t compat)
116794 +{
116795 + if (compat == COMPAT_US_TO_K){
116796 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
116797 + }
116798 +}
116799 +
116800 +void compat_copy_fm_port_pcd_kg(
116801 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
116802 + ioc_fm_port_pcd_kg_params_t *param,
116803 + uint8_t compat)
116804 +{
116805 + if (compat == COMPAT_US_TO_K){
116806 + uint8_t k;
116807 +
116808 + param->num_of_schemes = compat_param->num_of_schemes;
116809 + for(k=0; k<compat_param->num_of_schemes; k++)
116810 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
116811 +
116812 + param->direct_scheme = compat_param->direct_scheme;
116813 + if (param->direct_scheme)
116814 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
116815 + }
116816 +}
116817 +
116818 +void compat_copy_fm_port_pcd(
116819 + ioc_compat_fm_port_pcd_params_t *compat_param,
116820 + ioc_fm_port_pcd_params_t *param,
116821 + uint8_t compat)
116822 +{
116823 + if (compat == COMPAT_US_TO_K)
116824 + {
116825 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
116826 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
116827 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
116828 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
116829 +
116830 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
116831 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
116832 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
116833 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
116834 +
116835 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
116836 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
116837 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
116838 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
116839 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
116840 +#if (DPAA_VERSION >= 11)
116841 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
116842 +#endif
116843 + param->pcd_support = compat_param->pcd_support;
116844 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
116845 +
116846 + if (param->p_cc_params)
116847 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
116848 + if (param->p_kg_params)
116849 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
116850 + if (param->p_plcr_params)
116851 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
116852 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
116853 +#if (DPAA_VERSION >= 11)
116854 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
116855 +#endif
116856 + }
116857 +}
116858 +
116859 +void compat_copy_fm_port_pcd_modify_tree(
116860 + ioc_compat_fm_obj_t *compat_id,
116861 + ioc_fm_obj_t *id,
116862 + uint8_t compat)
116863 +{
116864 + if (compat == COMPAT_US_TO_K)
116865 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116866 +}
116867 +
116868 +#if (DPAA_VERSION >= 11)
116869 +void compat_copy_fm_port_vsp_alloc_params(
116870 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
116871 + ioc_fm_port_vsp_alloc_params_t *param,
116872 + uint8_t compat)
116873 +{
116874 + if (compat == COMPAT_US_TO_K)
116875 + {
116876 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
116877 +
116878 + param->dflt_relative_id = compat_param->dflt_relative_id;
116879 + param->num_of_profiles = compat_param->num_of_profiles;
116880 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
116881 + }
116882 +}
116883 +#endif /* (DPAA_VERSION >= 11) */
116884 +
116885 +void compat_copy_fm_pcd_cc_tbl_get_stats(
116886 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
116887 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
116888 + uint8_t compat)
116889 +{
116890 + if (compat == COMPAT_US_TO_K)
116891 + {
116892 + param->id = compat_pcd_id2ptr(compat_param->id);
116893 + param->key_index = compat_param->key_index;
116894 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
116895 + } else {
116896 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116897 + compat_param->key_index = param->key_index;
116898 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
116899 + }
116900 +}
116901 +
116902 +
116903 +void compat_copy_fm_pcd_net_env(
116904 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
116905 + ioc_fm_pcd_net_env_params_t *param,
116906 + uint8_t compat)
116907 +{
116908 + if (compat == COMPAT_US_TO_K)
116909 + {
116910 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
116911 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116912 + param->id = NULL; /* to avoid passing garbage to the kernel */
116913 + }
116914 + else
116915 + {
116916 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
116917 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
116918 +
116919 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116920 + }
116921 +}
116922 +
116923 +void compat_copy_fm_pcd_cc_node_modify_key(
116924 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
116925 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
116926 + uint8_t compat)
116927 +{
116928 + if (compat == COMPAT_US_TO_K)
116929 + {
116930 + param->key_indx = compat_param->key_indx;
116931 + param->key_size = compat_param->key_size;
116932 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
116933 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
116934 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
116935 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
116936 + param->id = compat_pcd_id2ptr(compat_param->id);
116937 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
116938 + }
116939 + else
116940 + {
116941 + compat_param->key_indx = param->key_indx;
116942 + compat_param->key_size = param->key_size;
116943 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
116944 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
116945 +
116946 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116947 + }
116948 +}
116949 +
116950 +void compat_copy_keys(
116951 + ioc_compat_keys_params_t *compat_param,
116952 + ioc_keys_params_t *param,
116953 + uint8_t compat)
116954 +{
116955 + int k = 0;
116956 +
116957 + _fm_cpt_dbg(compat," {->...\n");
116958 +
116959 + if (compat == COMPAT_US_TO_K) {
116960 + param->max_num_of_keys = compat_param->max_num_of_keys;
116961 + param->mask_support = compat_param->mask_support;
116962 + param->statistics_mode = compat_param->statistics_mode;
116963 + param->num_of_keys = compat_param->num_of_keys;
116964 + param->key_size = compat_param->key_size;
116965 +#if (DPAA_VERSION >= 11)
116966 + memcpy(&param->frame_length_ranges,
116967 + &compat_param->frame_length_ranges,
116968 + sizeof(param->frame_length_ranges[0]) *
116969 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
116970 +#endif /* (DPAA_VERSION >= 11) */
116971 + }
116972 + else {
116973 + compat_param->max_num_of_keys = param->max_num_of_keys;
116974 + compat_param->mask_support = param->mask_support;
116975 + compat_param->statistics_mode = param->statistics_mode;
116976 + compat_param->num_of_keys = param->num_of_keys;
116977 + compat_param->key_size = param->key_size;
116978 +#if (DPAA_VERSION >= 11)
116979 + memcpy(&compat_param->frame_length_ranges,
116980 + &param->frame_length_ranges,
116981 + sizeof(compat_param->frame_length_ranges[0]) *
116982 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
116983 +#endif /* (DPAA_VERSION >= 11) */
116984 + }
116985 +
116986 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
116987 + compat_copy_fm_pcd_cc_key(
116988 + &compat_param->key_params[k],
116989 + &param->key_params[k],
116990 + compat);
116991 +
116992 + compat_copy_fm_pcd_cc_next_engine(
116993 + &compat_param->cc_next_engine_params_for_miss,
116994 + &param->cc_next_engine_params_for_miss,
116995 + compat);
116996 +
116997 + _fm_cpt_dbg(compat," ...->}\n");
116998 +}
116999 +
117000 +void compat_copy_fm_pcd_cc_node(
117001 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117002 + ioc_fm_pcd_cc_node_params_t *param,
117003 + uint8_t compat)
117004 +{
117005 + _fm_cpt_dbg(compat," {->...\n");
117006 +
117007 + if (compat == COMPAT_US_TO_K)
117008 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
117009 +
117010 + else
117011 + {
117012 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117013 +
117014 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117015 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117016 + }
117017 +
117018 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117019 +
117020 + _fm_cpt_dbg(compat," ...->}\n");
117021 +}
117022 +
117023 +void compat_fm_pcd_manip_set_node(
117024 + ioc_compat_fm_pcd_manip_params_t *compat_param,
117025 + ioc_fm_pcd_manip_params_t *param,
117026 + uint8_t compat)
117027 +{
117028 + if (compat == COMPAT_US_TO_K) {
117029 + param->type = compat_param->type;
117030 + switch (param->type) {
117031 + case e_IOC_FM_PCD_MANIP_HDR:
117032 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
117033 + memcpy(&param->u.hdr.rmv_params,
117034 + &compat_param->u.hdr.rmv_params,
117035 + sizeof(param->u.hdr.rmv_params));
117036 +
117037 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
117038 + param->u.hdr.insrt_params.type =
117039 + compat_param->u.hdr.insrt_params.type;
117040 + switch (compat_param->u.hdr.insrt_params.type)
117041 + {
117042 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
117043 + param->u.hdr.insrt_params.u.generic.offset =
117044 + compat_param->u.hdr.insrt_params.u.generic.offset;
117045 + param->u.hdr.insrt_params.u.generic.size =
117046 + compat_param->u.hdr.insrt_params.u.generic.size;
117047 + param->u.hdr.insrt_params.u.generic.replace =
117048 + compat_param->u.hdr.insrt_params.u.generic.replace;
117049 + param->u.hdr.insrt_params.u.generic.p_data =
117050 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
117051 + break;
117052 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
117053 + param->u.hdr.insrt_params.u.by_hdr.type =
117054 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
117055 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
117056 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
117057 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
117058 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
117059 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
117060 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
117061 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
117062 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
117063 + break;
117064 + default:
117065 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
117066 + }
117067 +
117068 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
117069 + memcpy(&param->u.hdr.field_update_params,
117070 + &compat_param->u.hdr.field_update_params,
117071 + sizeof(param->u.hdr.field_update_params));
117072 +
117073 + param->u.hdr.custom = compat_param->u.hdr.custom;
117074 + memcpy(&param->u.hdr.custom_params,
117075 + &compat_param->u.hdr.custom_params,
117076 + sizeof(param->u.hdr.custom_params));
117077 +
117078 + param->u.hdr.dont_parse_after_manip =
117079 + compat_param->u.hdr.dont_parse_after_manip;
117080 + break;
117081 + case e_IOC_FM_PCD_MANIP_REASSEM:
117082 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
117083 + break;
117084 + case e_IOC_FM_PCD_MANIP_FRAG:
117085 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
117086 + break;
117087 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
117088 + memcpy(&param->u.special_offload,
117089 + &compat_param->u.special_offload,
117090 + sizeof(param->u.special_offload));
117091 + break;
117092 + }
117093 +
117094 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
117095 + param->id = compat_pcd_id2ptr(compat_param->id);
117096 + }
117097 + else {
117098 + compat_param->type = param->type;
117099 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
117100 +
117101 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
117102 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
117103 + compat_param->u.hdr.insrt_params.u.generic.p_data =
117104 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
117105 +
117106 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
117107 + /* ... should be one that was added previously by the very call to
117108 + compat_add_ptr2id() below: */
117109 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117110 + }
117111 +}
117112 +
117113 +void compat_copy_fm_pcd_manip_get_stats(
117114 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
117115 + ioc_fm_pcd_manip_get_stats_t *param,
117116 + uint8_t compat)
117117 +{
117118 + _fm_cpt_dbg (compat, " {->...\n");
117119 +
117120 + if (compat == COMPAT_US_TO_K)
117121 + {
117122 + param->id = compat_pcd_id2ptr(compat_param->id);
117123 + memcpy(&param->stats, &compat_param->stats,
117124 + sizeof(ioc_fm_pcd_manip_stats_t));
117125 + }
117126 + else
117127 + {
117128 + compat_param->id = compat_add_ptr2id(param->id,
117129 + FM_MAP_TYPE_PCD_NODE);
117130 + memcpy(&compat_param->stats, &param->stats,
117131 + sizeof(ioc_fm_pcd_manip_stats_t));
117132 + }
117133 +
117134 + _fm_cpt_dbg (compat, " ...->}\n");
117135 +}
117136 +
117137 +#if (DPAA_VERSION >= 11)
117138 +void compat_copy_fm_pcd_frm_replic_group_params(
117139 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
117140 + ioc_fm_pcd_frm_replic_group_params_t *param,
117141 + uint8_t compat)
117142 +{
117143 + int k;
117144 +
117145 + _fm_cpt_dbg (compat, " {->...\n");
117146 +
117147 + if (compat == COMPAT_US_TO_K)
117148 + {
117149 + param->max_num_of_entries = compat_param->max_num_of_entries;
117150 + param->num_of_entries = compat_param->num_of_entries;
117151 + param->id = compat_pcd_id2ptr(compat_param->id);
117152 + }
117153 + else
117154 + {
117155 + compat_param->max_num_of_entries = param->max_num_of_entries;
117156 + compat_param->num_of_entries = param->num_of_entries;
117157 + compat_param->id = compat_add_ptr2id(param->id,
117158 + FM_MAP_TYPE_PCD_NODE);
117159 + }
117160 +
117161 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
117162 + compat_copy_fm_pcd_cc_next_engine(
117163 + &compat_param->next_engine_params[k],
117164 + &param->next_engine_params[k],
117165 + compat);
117166 +
117167 + _fm_cpt_dbg (compat, " ...->}\n");
117168 +}
117169 +
117170 +void compat_copy_fm_pcd_frm_replic_member(
117171 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
117172 + ioc_fm_pcd_frm_replic_member_t *param,
117173 + uint8_t compat)
117174 +{
117175 + _fm_cpt_dbg (compat, " {->...\n");
117176 +
117177 + if (compat == COMPAT_US_TO_K)
117178 + {
117179 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
117180 + param->member_index = compat_param->member_index;
117181 + }
117182 +
117183 + _fm_cpt_dbg (compat, " ...->}\n");
117184 +}
117185 +
117186 +void compat_copy_fm_pcd_frm_replic_member_params(
117187 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
117188 + ioc_fm_pcd_frm_replic_member_params_t *param,
117189 + uint8_t compat)
117190 +{
117191 + _fm_cpt_dbg (compat, " {->...\n");
117192 +
117193 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
117194 + &param->member, compat);
117195 +
117196 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
117197 + &param->next_engine_params, compat);
117198 +
117199 + _fm_cpt_dbg (compat, " ...->}\n");
117200 +}
117201 +
117202 +void compat_copy_fm_vsp_params(
117203 + ioc_compat_fm_vsp_params_t *compat_param,
117204 + ioc_fm_vsp_params_t *param,
117205 + uint8_t compat)
117206 +{
117207 + _fm_cpt_dbg (compat, " {->...\n");
117208 +
117209 + if (compat == COMPAT_US_TO_K)
117210 + {
117211 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117212 + param->liodn_offset = compat_param->liodn_offset;
117213 + param->port_params.port_id = compat_param->port_params.port_id;
117214 + param->port_params.port_type = compat_param->port_params.port_type;
117215 + param->relative_profile_id = compat_param->relative_profile_id;
117216 + }
117217 + else
117218 + {
117219 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117220 + compat_param->liodn_offset = param->liodn_offset;
117221 + compat_param->port_params.port_id = param->port_params.port_id;
117222 + compat_param->port_params.port_type = param->port_params.port_type;
117223 + compat_param->relative_profile_id = param->relative_profile_id;
117224 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117225 + }
117226 +
117227 + _fm_cpt_dbg (compat, " ...->}\n");
117228 +}
117229 +
117230 +void compat_copy_fm_buf_pool_depletion_params(
117231 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
117232 + ioc_fm_buf_pool_depletion_params_t *param,
117233 + uint8_t compat)
117234 +{
117235 + _fm_cpt_dbg (compat, " {->...\n");
117236 +
117237 + if (compat == COMPAT_US_TO_K)
117238 + {
117239 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117240 + memcpy(&param->fm_buf_pool_depletion,
117241 + &compat_param->fm_buf_pool_depletion,
117242 + sizeof(ioc_fm_buf_pool_depletion_t));
117243 + }
117244 +
117245 + _fm_cpt_dbg (compat, " ...->}\n");
117246 +}
117247 +
117248 +void compat_copy_fm_buffer_prefix_content_params(
117249 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
117250 + ioc_fm_buffer_prefix_content_params_t *param,
117251 + uint8_t compat)
117252 +{
117253 + _fm_cpt_dbg (compat, " {->...\n");
117254 +
117255 + if (compat == COMPAT_US_TO_K)
117256 + {
117257 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117258 + memcpy(&param->fm_buffer_prefix_content,
117259 + &compat_param->fm_buffer_prefix_content,
117260 + sizeof(ioc_fm_buffer_prefix_content_t));
117261 + }
117262 +
117263 + _fm_cpt_dbg (compat, " ...->}\n");
117264 +}
117265 +
117266 +void compat_copy_fm_vsp_config_no_sg_params(
117267 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
117268 + ioc_fm_vsp_config_no_sg_params_t *param,
117269 + uint8_t compat)
117270 +{
117271 + _fm_cpt_dbg (compat, " {->...\n");
117272 +
117273 + if (compat == COMPAT_US_TO_K)
117274 + {
117275 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117276 + param->no_sg = compat_param->no_sg;
117277 + }
117278 +
117279 + _fm_cpt_dbg (compat, " ...->}\n");
117280 +}
117281 +
117282 +void compat_copy_fm_vsp_prs_result_params(
117283 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
117284 + ioc_fm_vsp_prs_result_params_t *param,
117285 + uint8_t compat)
117286 +{
117287 + _fm_cpt_dbg (compat, " {->...\n");
117288 +
117289 + if (compat == COMPAT_US_TO_K)
117290 + {
117291 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117292 + /* p_data is an user-space pointer that needs to remain unmodified */
117293 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
117294 + }
117295 + else
117296 + {
117297 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
117298 + /* p_data is an user-space pointer that needs to remain unmodified */
117299 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
117300 + }
117301 +
117302 + _fm_cpt_dbg (compat, " ...->}\n");
117303 +}
117304 +#endif /* (DPAA_VERSION >= 11) */
117305 --- /dev/null
117306 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
117307 @@ -0,0 +1,755 @@
117308 +/*
117309 + * Copyright 2008-2012 Freescale Semiconductor Inc.
117310 + *
117311 + * Redistribution and use in source and binary forms, with or without
117312 + * modification, are permitted provided that the following conditions are met:
117313 + * * Redistributions of source code must retain the above copyright
117314 + * notice, this list of conditions and the following disclaimer.
117315 + * * Redistributions in binary form must reproduce the above copyright
117316 + * notice, this list of conditions and the following disclaimer in the
117317 + * documentation and/or other materials provided with the distribution.
117318 + * * Neither the name of Freescale Semiconductor nor the
117319 + * names of its contributors may be used to endorse or promote products
117320 + * derived from this software without specific prior written permission.
117321 + *
117322 + *
117323 + * ALTERNATIVELY, this software may be distributed under the terms of the
117324 + * GNU General Public License ("GPL") as published by the Free Software
117325 + * Foundation, either version 2 of that License or (at your option) any
117326 + * later version.
117327 + *
117328 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
117329 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
117330 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117331 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
117332 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
117333 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
117334 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
117335 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
117336 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117337 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117338 + */
117339 +
117340 +/*
117341 + @File lnxwrp_ioctls_fm_compat.h
117342 +
117343 + @Description FM PCD compat structures definition.
117344 +
117345 +*/
117346 +
117347 +#ifndef __FM_COMPAT_IOCTLS_H
117348 +#define __FM_COMPAT_IOCTLS_H
117349 +
117350 +#include <linux/compat.h>
117351 +
117352 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
117353 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
117354 +#define COMPAT_GENERIC 2
117355 +
117356 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
117357 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
117358 +
117359 +/* mapping kernel pointers w/ UserSpace id's { */
117360 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
117361 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
117362 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
117363 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
117364 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
117365 +
117366 +/* define it for debug trace */
117367 +/*#define FM_COMPAT_DBG*/
117368 +
117369 +#define _fm_cpt_prk(stage, format, arg...) \
117370 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
117371 +
117372 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
117373 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
117374 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
117375 +
117376 +/* used for compat IOCTL debugging */
117377 +#if defined(FM_COMPAT_DBG)
117378 + #define _fm_cpt_dbg(from, format, arg...) \
117379 + do{ \
117380 + if (from == COMPAT_US_TO_K) \
117381 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
117382 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117383 + else if (from == COMPAT_K_TO_US) \
117384 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
117385 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117386 + else \
117387 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
117388 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117389 + }while(0)
117390 +#else
117391 +# define _fm_cpt_dbg(arg...)
117392 +#endif
117393 +
117394 +/*TODO: per FMan module:
117395 + *
117396 + * Parser: FM_MAP_TYPE_PARSER_NODE,
117397 + * Kg: FM_MAP_TYPE_KG_NODE,
117398 + * Policer: FM_MAP_TYPE_POLICER_NODE
117399 + * Manip: FM_MAP_TYPE_MANIP_NODE
117400 + **/
117401 +enum fm_map_node_type {
117402 + FM_MAP_TYPE_UNSPEC = 0,
117403 + FM_MAP_TYPE_PCD_NODE,
117404 +
117405 + /* add types here, update the policy */
117406 +
117407 + __FM_MAP_TYPE_AFTER_LAST,
117408 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
117409 +};
117410 +
117411 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
117412 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
117413 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
117414 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
117415 +
117416 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
117417 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
117418 + : (compat_uptr_t) 0;
117419 +}
117420 +
117421 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
117422 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
117423 + : NULL;
117424 +}
117425 +
117426 +/* other similar inlines may be added as new nodes are added
117427 + to enum fm_map_node_type above... */
117428 +/* } mapping kernel pointers w/ UserSpace id's */
117429 +
117430 +/* pcd compat structures { */
117431 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
117432 + compat_uptr_t id;
117433 + uint16_t key_indx;
117434 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
117435 +
117436 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
117437 + ioc_fm_pcd_done_action action;
117438 + compat_uptr_t p_profile;
117439 + compat_uptr_t p_direct_scheme;
117440 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
117441 +
117442 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
117443 + bool modify;
117444 + union {
117445 + struct {
117446 + ioc_fm_pcd_profile_type_selection profile_type;
117447 + compat_uptr_t p_fm_port;
117448 + uint16_t relative_profile_id;
117449 + } new_params;
117450 + compat_uptr_t p_profile;
117451 + } profile_select;
117452 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
117453 + ioc_fm_pcd_plcr_color_mode color_mode;
117454 +
117455 + union {
117456 + ioc_fm_pcd_plcr_color dflt_color;
117457 + ioc_fm_pcd_plcr_color override;
117458 + } color;
117459 +
117460 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
117461 +
117462 + ioc_fm_pcd_engine next_engine_on_green;
117463 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
117464 +
117465 + ioc_fm_pcd_engine next_engine_on_yellow;
117466 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
117467 +
117468 + ioc_fm_pcd_engine next_engine_on_red;
117469 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
117470 +
117471 + bool trap_profile_on_flow_A;
117472 + bool trap_profile_on_flow_B;
117473 + bool trap_profile_on_flow_C;
117474 + compat_uptr_t id;
117475 +} ioc_compat_fm_pcd_plcr_profile_params_t;
117476 +
117477 +typedef struct ioc_compat_fm_obj_t {
117478 + compat_uptr_t obj;
117479 +} ioc_compat_fm_obj_t;
117480 +
117481 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
117482 + bool direct;
117483 + compat_uptr_t scheme_id;
117484 +} ioc_compat_fm_pcd_kg_scheme_select_t;
117485 +
117486 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
117487 + uint8_t num_of_schemes;
117488 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117489 +} ioc_compat_fm_pcd_port_schemes_params_t;
117490 +
117491 +#if (DPAA_VERSION >= 11)
117492 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
117493 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
117494 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
117495 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
117496 + if relevant function called for Rx port */
117497 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
117498 +}ioc_compat_fm_port_vsp_alloc_params_t;
117499 +#endif /* (DPAA_VERSION >= 11) */
117500 +
117501 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
117502 + uint8_t num_of_distinction_units;
117503 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
117504 + compat_uptr_t id;
117505 +} ioc_compat_fm_pcd_net_env_params_t;
117506 +
117507 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
117508 + bool override;
117509 + uint32_t size;
117510 + uint16_t base;
117511 + compat_uptr_t p_code;
117512 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
117513 + uint8_t num_of_labels;
117514 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
117515 +} ioc_compat_fm_pcd_prs_sw_params_t;
117516 +
117517 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
117518 + bool override_fqid;
117519 + uint32_t new_fqid;
117520 +#if DPAA_VERSION >= 11
117521 + uint8_t new_relative_storage_profile_id;
117522 +#endif
117523 + compat_uptr_t p_direct_scheme;
117524 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
117525 +
117526 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
117527 + compat_uptr_t cc_node_id;
117528 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
117529 +
117530 +#if DPAA_VERSION >= 11
117531 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
117532 + compat_uptr_t frm_replic_id;
117533 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
117534 +#endif /* DPAA_VERSION >= 11 */
117535 +
117536 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
117537 + ioc_fm_pcd_engine next_engine;
117538 + union {
117539 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
117540 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
117541 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
117542 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
117543 +#if DPAA_VERSION >= 11
117544 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
117545 +#endif /* DPAA_VERSION >= 11 */
117546 + } params;
117547 + compat_uptr_t manip_id;
117548 + bool statistics_en;
117549 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
117550 +
117551 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
117552 + uint8_t num_of_distinction_units;
117553 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
117554 + 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];
117555 +} ioc_compat_fm_pcd_cc_grp_params_t;
117556 +
117557 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
117558 + compat_uptr_t net_env_id;
117559 + uint8_t num_of_groups;
117560 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
117561 + compat_uptr_t id;
117562 +} ioc_compat_fm_pcd_cc_tree_params_t;
117563 +
117564 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
117565 + compat_uptr_t id;
117566 + uint8_t grp_indx;
117567 + uint8_t indx;
117568 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
117569 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
117570 +
117571 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
117572 + compat_uptr_t p_key;
117573 + compat_uptr_t p_mask;
117574 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
117575 +} ioc_compat_fm_pcd_cc_key_params_t;
117576 +
117577 +typedef struct ioc_compat_keys_params_t {
117578 + uint16_t max_num_of_keys;
117579 + bool mask_support;
117580 + ioc_fm_pcd_cc_stats_mode statistics_mode;
117581 +#if (DPAA_VERSION >= 11)
117582 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
117583 +#endif /* (DPAA_VERSION >= 11) */
117584 + uint16_t num_of_keys;
117585 + uint8_t key_size;
117586 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
117587 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
117588 +} ioc_compat_keys_params_t;
117589 +
117590 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
117591 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
117592 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
117593 + compat_uptr_t id;
117594 +} ioc_compat_fm_pcd_cc_node_params_t;
117595 +
117596 +/**************************************************************************//**
117597 + @Description Parameters for defining a hash table
117598 +*//***************************************************************************/
117599 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
117600 + uint16_t max_num_of_keys;
117601 + ioc_fm_pcd_cc_stats_mode statistics_mode;
117602 + uint8_t kg_hash_shift;
117603 + uint16_t hash_res_mask;
117604 + uint8_t hash_shift;
117605 + uint8_t match_key_size;
117606 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
117607 + compat_uptr_t id;
117608 +} ioc_compat_fm_pcd_hash_table_params_t;
117609 +
117610 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
117611 + compat_uptr_t p_hash_tbl;
117612 + uint8_t key_size;
117613 + ioc_compat_fm_pcd_cc_key_params_t key_params;
117614 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
117615 +
117616 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
117617 + compat_uptr_t id;
117618 + uint16_t key_indx;
117619 + uint8_t key_size;
117620 + compat_uptr_t p_key;
117621 + compat_uptr_t p_mask;
117622 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
117623 +
117624 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
117625 + compat_uptr_t p_hash_tbl;
117626 + uint8_t key_size;
117627 + compat_uptr_t p_key;
117628 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
117629 +
117630 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
117631 + compat_uptr_t id;
117632 + uint16_t key_indx;
117633 + uint8_t key_size;
117634 + ioc_compat_fm_pcd_cc_key_params_t key_params;
117635 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
117636 +
117637 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
117638 + compat_uptr_t plcr_profile_id;
117639 +} ioc_compat_fm_port_pcd_plcr_params_t;
117640 +
117641 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
117642 + compat_uptr_t cc_tree_id;
117643 +} ioc_compat_fm_port_pcd_cc_params_t;
117644 +
117645 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
117646 + uint8_t num_of_schemes;
117647 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117648 + bool direct_scheme;
117649 + compat_uptr_t direct_scheme_id;
117650 +} ioc_compat_fm_port_pcd_kg_params_t;
117651 +
117652 +typedef struct ioc_compat_fm_port_pcd_params_t {
117653 + ioc_fm_port_pcd_support pcd_support;
117654 + compat_uptr_t net_env_id;
117655 + compat_uptr_t p_prs_params;
117656 + compat_uptr_t p_cc_params;
117657 + compat_uptr_t p_kg_params;
117658 + compat_uptr_t p_plcr_params;
117659 + compat_uptr_t p_ip_reassembly_manip;
117660 +#if DPAA_VERSION >= 11
117661 + compat_uptr_t p_capwap_reassembly_manip;
117662 +#endif
117663 +} ioc_compat_fm_port_pcd_params_t;
117664 +
117665 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
117666 + compat_uptr_t tree_id;
117667 + uint8_t grp_id;
117668 + bool plcr_next;
117669 + bool bypass_plcr_profile_generation;
117670 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
117671 +} ioc_compat_fm_pcd_kg_cc_t;
117672 +
117673 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
117674 + bool modify;
117675 + union {
117676 + uint8_t relative_scheme_id;
117677 + compat_uptr_t scheme_id;
117678 + } scm_id;
117679 + bool always_direct;
117680 + struct {
117681 + compat_uptr_t net_env_id;
117682 + uint8_t num_of_distinction_units;
117683 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
117684 + } net_env_params;
117685 + bool use_hash;
117686 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
117687 + bool bypass_fqid_generation;
117688 + uint32_t base_fqid;
117689 + uint8_t num_of_used_extracted_ors;
117690 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
117691 +#if DPAA_VERSION >= 11
117692 + bool override_storage_profile;
117693 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
117694 +#endif /* DPAA_VERSION >= 11 */
117695 + ioc_fm_pcd_engine next_engine;
117696 + union{
117697 + ioc_fm_pcd_done_action done_action;
117698 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
117699 + ioc_compat_fm_pcd_kg_cc_t cc;
117700 + } kg_next_engine_params;
117701 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
117702 + compat_uptr_t id;
117703 +} ioc_compat_fm_pcd_kg_scheme_params_t;
117704 +
117705 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
117706 + compat_uptr_t id;
117707 + uint16_t key_indx;
117708 + uint8_t key_size;
117709 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
117710 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
117711 +
117712 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
117713 + uint8_t offset;
117714 + uint8_t size;
117715 + bool replace;
117716 + compat_uptr_t p_data;
117717 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
117718 +
117719 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
117720 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
117721 + bool update;
117722 + uint8_t size;
117723 + compat_uptr_t p_data;
117724 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
117725 +
117726 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
117727 + uint8_t size; /**< size of inserted section */
117728 + compat_uptr_t p_data; /**< data to be inserted */
117729 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
117730 +
117731 +#if (DPAA_VERSION >= 11)
117732 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
117733 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
117734 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
117735 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
117736 + the inserted header */
117737 + uint16_t id; /**< 16 bit New IP ID */
117738 + bool dont_frag_overwrite;
117739 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
117740 + * This byte is configured to be overwritten when RPD is set. */
117741 + uint8_t last_dst_offset;
117742 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
117743 + * in order to calculate UDP checksum pseudo header;
117744 + * Otherwise set it to '0'. */
117745 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
117746 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
117747 +#endif /* (DPAA_VERSION >= 11) */
117748 +
117749 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
117750 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
117751 + union {
117752 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
117753 +#if (DPAA_VERSION >= 11)
117754 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
117755 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
117756 +#endif /* (DPAA_VERSION >= 11) */
117757 + } u;
117758 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
117759 +
117760 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
117761 + ioc_fm_pcd_manip_hdr_insrt_type type;
117762 + union {
117763 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
117764 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
117765 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
117766 +#error "FM_CAPWAP_SUPPORT feature not supported!"
117767 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
117768 +#endif /* FM_CAPWAP_SUPPORT */
117769 + } u;
117770 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
117771 +
117772 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
117773 + bool rmv;
117774 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
117775 + bool insrt;
117776 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
117777 + bool field_update;
117778 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
117779 + bool custom;
117780 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
117781 + bool dont_parse_after_manip;
117782 +} ioc_compat_fm_pcd_manip_hdr_params_t;
117783 +
117784 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
117785 + bool decryption;
117786 + bool ecn_copy;
117787 + bool dscp_copy;
117788 + bool variable_ip_hdr_len;
117789 + bool variable_ip_version;
117790 + uint8_t outer_ip_hdr_len;
117791 + uint16_t arw_size;
117792 + compat_uptr_t arw_addr;
117793 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
117794 +
117795 +typedef struct ioc_compat_fm_pcd_manip_params_t {
117796 + ioc_fm_pcd_manip_type type;
117797 + union {
117798 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
117799 + ioc_fm_pcd_manip_reassem_params_t reassem;
117800 + ioc_fm_pcd_manip_frag_params_t frag;
117801 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
117802 + } u;
117803 + compat_uptr_t p_next_manip;
117804 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
117805 +#error "FM_CAPWAP_SUPPORT feature not supported!"
117806 + bool frag_or_reasm;
117807 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
117808 +#endif /* FM_CAPWAP_SUPPORT */
117809 + compat_uptr_t id;
117810 +} ioc_compat_fm_pcd_manip_params_t;
117811 +
117812 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
117813 + compat_uptr_t id;
117814 + ioc_fm_pcd_manip_stats_t stats;
117815 +} ioc_compat_fm_pcd_manip_get_stats_t;
117816 +
117817 +#if (DPAA_VERSION >= 11)
117818 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
117819 + uint8_t max_num_of_entries;
117820 + uint8_t num_of_entries;
117821 + ioc_compat_fm_pcd_cc_next_engine_params_t
117822 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
117823 + compat_uptr_t id;
117824 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
117825 +
117826 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
117827 + compat_uptr_t h_replic_group;
117828 + uint16_t member_index;
117829 +} ioc_compat_fm_pcd_frm_replic_member_t;
117830 +
117831 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
117832 + ioc_compat_fm_pcd_frm_replic_member_t member;
117833 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
117834 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
117835 +
117836 +typedef struct ioc_compat_fm_vsp_params_t {
117837 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
117838 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
117839 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
117840 + parameter associated with Rx / OP port */
117841 + uint16_t liodn_offset; /**< VSP's LIODN offset */
117842 + struct {
117843 + ioc_fm_port_type port_type; /**< Port type */
117844 + uint8_t port_id; /**< Port Id - relative to type */
117845 + } port_params;
117846 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
117847 + defined in relevant FM object */
117848 + compat_uptr_t id; /**< return value */
117849 +} ioc_compat_fm_vsp_params_t;
117850 +
117851 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
117852 + compat_uptr_t p_fm_vsp;
117853 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
117854 +} ioc_compat_fm_buf_pool_depletion_params_t;
117855 +
117856 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
117857 + compat_uptr_t p_fm_vsp;
117858 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
117859 +} ioc_compat_fm_buffer_prefix_content_params_t;
117860 +
117861 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
117862 + compat_uptr_t p_fm_vsp;
117863 + bool no_sg;
117864 +} ioc_compat_fm_vsp_config_no_sg_params_t;
117865 +
117866 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
117867 + compat_uptr_t p_fm_vsp;
117868 + compat_uptr_t p_data;
117869 +} ioc_compat_fm_vsp_prs_result_params_t;
117870 +
117871 +#endif /* (DPAA_VERSION >= 11) */
117872 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
117873 + uint32_t val;
117874 + compat_uptr_t id;
117875 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
117876 +
117877 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
117878 + uint8_t fm_ctrl_index;
117879 + compat_uptr_t p_mon;
117880 +} ioc_compat_fm_ctrl_mon_counters_params_t;
117881 +
117882 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
117883 + compat_uptr_t id;
117884 + uint16_t key_index;
117885 + ioc_fm_pcd_cc_key_statistics_t statistics;
117886 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
117887 +
117888 +
117889 +/* } pcd compat structures */
117890 +
117891 +void compat_obj_delete(
117892 + ioc_compat_fm_obj_t *compat_id,
117893 + ioc_fm_obj_t *id);
117894 +
117895 +/* pcd compat functions { */
117896 +void compat_copy_fm_pcd_plcr_profile(
117897 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
117898 + ioc_fm_pcd_plcr_profile_params_t *param,
117899 + uint8_t compat);
117900 +
117901 +void compat_copy_fm_pcd_cc_key(
117902 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
117903 + ioc_fm_pcd_cc_key_params_t *param,
117904 + uint8_t compat);
117905 +
117906 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
117907 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
117908 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
117909 + uint8_t compat);
117910 +
117911 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
117912 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
117913 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
117914 + uint8_t compat);
117915 +
117916 +void compat_fm_pcd_cc_tree_modify_next_engine(
117917 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
117918 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
117919 + uint8_t compat);
117920 +
117921 +void compat_copy_fm_pcd_hash_table(
117922 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
117923 + ioc_fm_pcd_hash_table_params_t *param,
117924 + uint8_t compat);
117925 +
117926 +void compat_copy_fm_pcd_cc_grp(
117927 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
117928 + ioc_fm_pcd_cc_grp_params_t *param,
117929 + uint8_t compat);
117930 +
117931 +void compat_copy_fm_pcd_cc_tree(
117932 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
117933 + ioc_fm_pcd_cc_tree_params_t *param,
117934 + uint8_t compat);
117935 +
117936 +void compat_copy_fm_pcd_cc_tbl_get_stats(
117937 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
117938 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
117939 + uint8_t compat);
117940 +
117941 +void compat_fm_pcd_prs_sw(
117942 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
117943 + ioc_fm_pcd_prs_sw_params_t *param,
117944 + uint8_t compat);
117945 +
117946 +void compat_copy_fm_pcd_kg_scheme(
117947 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
117948 + ioc_fm_pcd_kg_scheme_params_t *param,
117949 + uint8_t compat);
117950 +
117951 +void compat_copy_fm_pcd_kg_scheme_select(
117952 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
117953 + ioc_fm_pcd_kg_scheme_select_t *param,
117954 + uint8_t compat);
117955 +
117956 +void compat_copy_fm_pcd_kg_schemes_params(
117957 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
117958 + ioc_fm_pcd_port_schemes_params_t *param,
117959 + uint8_t compat);
117960 +
117961 +void compat_copy_fm_port_pcd_kg(
117962 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
117963 + ioc_fm_port_pcd_kg_params_t *param,
117964 + uint8_t compat);
117965 +
117966 +void compat_copy_fm_port_pcd(
117967 + ioc_compat_fm_port_pcd_params_t *compat_param,
117968 + ioc_fm_port_pcd_params_t *param,
117969 + uint8_t compat);
117970 +
117971 +#if (DPAA_VERSION >= 11)
117972 +void compat_copy_fm_port_vsp_alloc_params(
117973 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
117974 + ioc_fm_port_vsp_alloc_params_t *param,
117975 + uint8_t compat);
117976 +#endif /* (DPAA_VERSION >= 11) */
117977 +
117978 +void compat_copy_fm_pcd_net_env(
117979 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
117980 + ioc_fm_pcd_net_env_params_t *param,
117981 + uint8_t compat);
117982 +
117983 +void compat_copy_fm_pcd_cc_node_modify_key(
117984 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
117985 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
117986 + uint8_t compat);
117987 +
117988 +void compat_copy_keys(
117989 + ioc_compat_keys_params_t *compat_param,
117990 + ioc_keys_params_t *param,
117991 + uint8_t compat);
117992 +
117993 +void compat_copy_fm_pcd_cc_node(
117994 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117995 + ioc_fm_pcd_cc_node_params_t *param,
117996 + uint8_t compat);
117997 +
117998 +void compat_fm_pcd_manip_set_node(
117999 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118000 + ioc_fm_pcd_manip_params_t *param,
118001 + uint8_t compat);
118002 +
118003 +void compat_copy_fm_pcd_manip_get_stats(
118004 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118005 + ioc_fm_pcd_manip_get_stats_t *param,
118006 + uint8_t compat);
118007 +
118008 +void compat_copy_fm_port_pcd_modify_tree(
118009 + ioc_compat_fm_obj_t *compat_id,
118010 + ioc_fm_obj_t *id,
118011 + uint8_t compat);
118012 +
118013 +#if (DPAA_VERSION >= 11)
118014 +void compat_copy_fm_pcd_frm_replic_group_params(
118015 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118016 + ioc_fm_pcd_frm_replic_group_params_t *param,
118017 + uint8_t compat);
118018 +
118019 +void compat_copy_fm_pcd_frm_replic_member(
118020 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118021 + ioc_fm_pcd_frm_replic_member_t *param,
118022 + uint8_t compat);
118023 +
118024 +void compat_copy_fm_pcd_frm_replic_member_params(
118025 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118026 + ioc_fm_pcd_frm_replic_member_params_t *param,
118027 + uint8_t compat);
118028 +
118029 +void compat_copy_fm_vsp_params(
118030 + ioc_compat_fm_vsp_params_t *compat_param,
118031 + ioc_fm_vsp_params_t *param,
118032 + uint8_t compat);
118033 +
118034 +void compat_copy_fm_buf_pool_depletion_params(
118035 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118036 + ioc_fm_buf_pool_depletion_params_t *param,
118037 + uint8_t compat);
118038 +
118039 +void compat_copy_fm_buffer_prefix_content_params(
118040 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118041 + ioc_fm_buffer_prefix_content_params_t *param,
118042 + uint8_t compat);
118043 +
118044 +void compat_copy_fm_vsp_config_no_sg_params(
118045 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118046 + ioc_fm_vsp_config_no_sg_params_t *param,
118047 + uint8_t compat);
118048 +
118049 +void compat_copy_fm_vsp_prs_result_params(
118050 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118051 + ioc_fm_vsp_prs_result_params_t *param,
118052 + uint8_t compat);
118053 +
118054 +#endif /* (DPAA_VERSION >= 11) */
118055 +
118056 +void compat_copy_fm_pcd_kg_scheme_spc(
118057 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118058 + ioc_fm_pcd_kg_scheme_spc_t *param,
118059 + uint8_t compat);
118060 +
118061 +/* } pcd compat functions */
118062 +#endif
118063 --- /dev/null
118064 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118065 @@ -0,0 +1,121 @@
118066 +/*
118067 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118068 + *
118069 + * Redistribution and use in source and binary forms, with or without
118070 + * modification, are permitted provided that the following conditions are met:
118071 + * * Redistributions of source code must retain the above copyright
118072 + * notice, this list of conditions and the following disclaimer.
118073 + * * Redistributions in binary form must reproduce the above copyright
118074 + * notice, this list of conditions and the following disclaimer in the
118075 + * documentation and/or other materials provided with the distribution.
118076 + * * Neither the name of Freescale Semiconductor nor the
118077 + * names of its contributors may be used to endorse or promote products
118078 + * derived from this software without specific prior written permission.
118079 + *
118080 + *
118081 + * ALTERNATIVELY, this software may be distributed under the terms of the
118082 + * GNU General Public License ("GPL") as published by the Free Software
118083 + * Foundation, either version 2 of that License or (at your option) any
118084 + * later version.
118085 + *
118086 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118087 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118088 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118089 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118090 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118091 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118092 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118093 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118094 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118095 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118096 + */
118097 +
118098 +/*
118099 + @File lnxwrp_resources.h
118100 +
118101 + @Description FMD wrapper resource allocation functions.
118102 +
118103 +*/
118104 +
118105 +#ifndef LNXWRP_RESOURCES_H_
118106 +#define LNXWRP_RESOURCES_H_
118107 +
118108 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118109 +#include "lnxwrp_fm.h"
118110 +#else
118111 +#include "lnxwrp_resources_ut.h"
118112 +#endif
118113 +
118114 +#define ROUND(X) ((2*(X)+1)/2)
118115 +#define CEIL(X) ((X)+1)
118116 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
118117 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
118118 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
118119 +
118120 +/* used for resource calculus */
118121 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
118122 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
118123 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
118124 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
118125 +
118126 +int fm_set_active_fman_ports(struct platform_device *of_dev,
118127 + t_LnxWrpFmDev *p_LnxWrpFmDev);
118128 +
118129 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
118130 + * value and s/g software support (! Kernel does not suport s/g).
118131 + *
118132 + * Algorithm summary:
118133 + * - Calculate the the minimum fifosize required for every type of port
118134 + * (TX,RX for 1G, 2.5G and 10G).
118135 + * - Set TX the minimum fifosize required.
118136 + * - Distribute the remaining buffers (after all TX were set) to RX ports
118137 + * based on:
118138 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
118139 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
118140 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
118141 + * - if the RX is smaller than the minimum required, then set the minimum
118142 + * required
118143 + * - In the end distribuite the leftovers if there are any (due to
118144 + * unprecise calculus) or if over allocation cat some buffers from all RX
118145 + * ports w/o pass over minimum required treshold, but if there must be
118146 + * pass the treshold in order to cat the over allocation ,then this
118147 + * configuration can not be set - KERN_ALERT.
118148 +*/
118149 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
118150 + int muram_fifo_size);
118151 +
118152 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118153 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118154 +#endif
118155 +
118156 +/* Compute FMan open DMA based on total number of open DMAs and
118157 + * number of available fman ports.
118158 + *
118159 + * By default 10g ports are set to input parameters. The other ports
118160 + * tries to keep the proportion rx=2tx open dmas or tresholds.
118161 + *
118162 + * If leftovers, then those will be set as shared.
118163 + *
118164 + * If after computing overflow appears, then it decrements open dma
118165 + * for all ports w/o cross the tresholds. If the tresholds are meet
118166 + * and is still overflow, then it returns error.
118167 +*/
118168 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
118169 + int max_fm_open_dma,
118170 + int default_tx_10g_dmas,
118171 + int default_rx_10g_dmas,
118172 + int min_tx_10g_treshold, int min_rx_10g_treshold);
118173 +
118174 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118175 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118176 +#endif
118177 +
118178 +/* Compute FMan tnums based on available tnums and number of ports.
118179 + * Set defaults (minim tresholds) and then distribute leftovers.*/
118180 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
118181 +
118182 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118183 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118184 +#endif
118185 +
118186 +#endif /* LNXWRP_RESOURCES_H_ */
118187 --- /dev/null
118188 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118189 @@ -0,0 +1,191 @@
118190 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
118191 + * All rights reserved.
118192 + *
118193 + * Redistribution and use in source and binary forms, with or without
118194 + * modification, are permitted provided that the following conditions are met:
118195 + * * Redistributions of source code must retain the above copyright
118196 + * notice, this list of conditions and the following disclaimer.
118197 + * * Redistributions in binary form must reproduce the above copyright
118198 + * notice, this list of conditions and the following disclaimer in the
118199 + * documentation and/or other materials provided with the distribution.
118200 + * * Neither the name of Freescale Semiconductor nor the
118201 + * names of its contributors may be used to endorse or promote products
118202 + * derived from this software without specific prior written permission.
118203 + *
118204 + *
118205 + * ALTERNATIVELY, this software may be distributed under the terms of the
118206 + * GNU General Public License ("GPL") as published by the Free Software
118207 + * Foundation, either version 2 of that License or (at your option) any
118208 + * later version.
118209 + *
118210 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118211 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118212 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118213 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118214 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118215 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118216 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118217 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118218 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118219 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118220 + */
118221 +
118222 +#include "lnxwrp_resources.h"
118223 +#include "lnxwrp_resources_ut.h"
118224 +
118225 +#define KILOBYTE 0x400 /* 1024 */
118226 +
118227 +typedef enum e_board_type {
118228 + e_p3041,
118229 + e_p4080,
118230 + e_p5020,
118231 + e_p1023
118232 +} e_board_type;
118233 +
118234 +uint8_t board_type;
118235 +uint32_t muram_size = 0;
118236 +uint32_t dmas_num = 0;
118237 +uint32_t task_num = 0;
118238 +uint32_t frame_size = 0;
118239 +uint32_t oh_num = 0;
118240 +uint32_t num_ports_1g = 0;
118241 +uint32_t num_ports_10g = 0;
118242 +uint32_t num_ports_2g5 = 0;
118243 +uint32_t fsl_fman_phy_maxfrm = 0;
118244 +uint32_t dpa_rx_extra_headroom = 0;
118245 +
118246 +void show_help(void){
118247 + printf(" help: \n");
118248 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
118249 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
118250 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
118251 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
118252 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
118253 + printf(" Number of ports:\n");
118254 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
118255 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
118256 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
118257 + printf(" MTU: Default:1522, Jumbo:9600 \n");
118258 +}
118259 +
118260 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
118261 + struct fm_active_ports *fm_active_ports_info = NULL;
118262 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
118263 +
118264 + switch(board_type){
118265 + case e_p3041:
118266 + case e_p5020:
118267 + muram_size = 160*KILOBYTE;
118268 + dmas_num = 32;
118269 + task_num = 128;
118270 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
118271 + goto err_fm_set_param;
118272 + break;
118273 + case e_p4080:
118274 + muram_size = 160*KILOBYTE;
118275 + dmas_num = 32;
118276 + task_num = 128;
118277 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
118278 + goto err_fm_set_param;
118279 + break;
118280 + case e_p1023:
118281 + muram_size = 64*KILOBYTE;
118282 + dmas_num = 16;
118283 + task_num = 128;
118284 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
118285 + goto err_fm_set_param;
118286 + break;
118287 + default:
118288 + goto err_fm_set_param;
118289 + break;
118290 + }
118291 +
118292 + p_LnxWrpFmDev->id = 0;
118293 + fsl_fman_phy_maxfrm = frame_size;
118294 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
118295 + fm_active_ports_info->num_oh_ports = oh_num;
118296 + fm_active_ports_info->num_tx_ports = num_ports_1g;
118297 + fm_active_ports_info->num_rx_ports = num_ports_1g;
118298 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
118299 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
118300 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
118301 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
118302 +
118303 + return 0;
118304 +
118305 +err_fm_set_param:
118306 + printf(" ERR: To many ports!!! \n");
118307 + return -1;
118308 +}
118309 +
118310 +int main (int argc, char *argv[]){
118311 + t_LnxWrpFmDev LnxWrpFmDev;
118312 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
118313 + int tokens_cnt = 1;
118314 +
118315 + char *token = NULL;
118316 +
118317 + while(tokens_cnt < argc)
118318 + {
118319 + token = argv[tokens_cnt++];
118320 + if (strcmp(token, "-b") == 0){
118321 + if(strcmp(argv[tokens_cnt],"p3") == 0)
118322 + board_type = e_p3041;
118323 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
118324 + board_type = e_p4080;
118325 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
118326 + board_type = e_p5020;
118327 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
118328 + board_type = e_p1023;
118329 + else
118330 + show_help();
118331 + tokens_cnt++;
118332 + }
118333 + else if(strcmp(token, "-d") == 0){
118334 + dmas_num = atoi(argv[tokens_cnt++]);
118335 + }
118336 + else if(strcmp(token, "-t") == 0)
118337 + task_num = atoi(argv[tokens_cnt++]);
118338 + else if(strcmp(token, "-f") == 0)
118339 + frame_size = atoi(argv[tokens_cnt++]);
118340 + else if(strcmp(token, "-o") == 0)
118341 + oh_num = atoi(argv[tokens_cnt++]);
118342 + else if(strcmp(token, "-g1") == 0)
118343 + num_ports_1g = atoi(argv[tokens_cnt++]);
118344 + else if(strcmp(token, "-g10") == 0)
118345 + num_ports_10g = atoi(argv[tokens_cnt++]);
118346 + else if(strcmp(token, "-g25") == 0)
118347 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
118348 + else {
118349 + show_help();
118350 + return -1;
118351 + }
118352 + }
118353 +
118354 + if(fm_set_param(p_LnxWrpFmDev) < 0){
118355 + show_help();
118356 + return -1;
118357 + }
118358 +
118359 + if(fm_precalculate_fifosizes(
118360 + p_LnxWrpFmDev,
118361 + 128*KILOBYTE)
118362 + != 0)
118363 + return -1;
118364 + if(fm_precalculate_open_dma(
118365 + p_LnxWrpFmDev,
118366 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
118367 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
118368 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
118369 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
118370 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
118371 + != 0)
118372 + return -1;
118373 + if(fm_precalculate_tnums(
118374 + p_LnxWrpFmDev,
118375 + task_num) /* max TNUMS: dpa integration file. */
118376 + != 0)
118377 + return -1;
118378 +
118379 + return 0;
118380 +}
118381 --- /dev/null
118382 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
118383 @@ -0,0 +1,144 @@
118384 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
118385 + * All rights reserved.
118386 + *
118387 + * Redistribution and use in source and binary forms, with or without
118388 + * modification, are permitted provided that the following conditions are met:
118389 + * * Redistributions of source code must retain the above copyright
118390 + * notice, this list of conditions and the following disclaimer.
118391 + * * Redistributions in binary form must reproduce the above copyright
118392 + * notice, this list of conditions and the following disclaimer in the
118393 + * documentation and/or other materials provided with the distribution.
118394 + * * Neither the name of Freescale Semiconductor nor the
118395 + * names of its contributors may be used to endorse or promote products
118396 + * derived from this software without specific prior written permission.
118397 + *
118398 + *
118399 + * ALTERNATIVELY, this software may be distributed under the terms of the
118400 + * GNU General Public License ("GPL") as published by the Free Software
118401 + * Foundation, either version 2 of that License or (at your option) any
118402 + * later version.
118403 + *
118404 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118405 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118406 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118407 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118408 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118409 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118410 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118411 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118412 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118413 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118414 + */
118415 +
118416 +#ifndef FM_RESS_TEST_H_
118417 +#define FM_RESS_TEST_H_
118418 +
118419 +#include <stdint.h>
118420 +#include <stdbool.h>
118421 +#include <stdio.h>
118422 +#include <assert.h>
118423 +#include <string.h>
118424 +#include <stdlib.h>
118425 +
118426 +#define _Packed
118427 +#define _PackedType __attribute__ ((packed))
118428 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
118429 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
118430 +#define KERN_ALERT ""
118431 +#define KERN_INFO ""
118432 +#define ASSERT_COND assert
118433 +#define printk printf
118434 +#define NET_IP_ALIGN 0
118435 +#define FM_FIFO_ALLOCATION_OLD_ALG
118436 +
118437 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
118438 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
118439 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
118440 +#else
118441 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
118442 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
118443 +#endif
118444 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
118445 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
118446 +
118447 +/* information about all active ports for an FMan.
118448 + * !Some ports may be disabled by u-boot, thus will not be available */
118449 +struct fm_active_ports {
118450 + uint32_t num_oh_ports;
118451 + uint32_t num_tx_ports;
118452 + uint32_t num_rx_ports;
118453 + uint32_t num_tx25_ports;
118454 + uint32_t num_rx25_ports;
118455 + uint32_t num_tx10_ports;
118456 + uint32_t num_rx10_ports;
118457 +};
118458 +
118459 +/* FMan resources precalculated at fm probe based
118460 + * on available FMan port. */
118461 +struct fm_resource_settings {
118462 + /* buffers - fifo sizes */
118463 + uint32_t tx1g_num_buffers;
118464 + uint32_t rx1g_num_buffers;
118465 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
118466 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
118467 + uint32_t tx10g_num_buffers;
118468 + uint32_t rx10g_num_buffers;
118469 + uint32_t oh_num_buffers;
118470 + uint32_t shared_ext_buffers;
118471 +
118472 +
118473 + /* open DMAs */
118474 + uint32_t tx_1g_dmas;
118475 + uint32_t rx_1g_dmas;
118476 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
118477 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
118478 + uint32_t tx_10g_dmas;
118479 + uint32_t rx_10g_dmas;
118480 + uint32_t oh_dmas;
118481 + uint32_t shared_ext_open_dma;
118482 +
118483 + /* Tnums */
118484 + uint32_t tx_1g_tnums;
118485 + uint32_t rx_1g_tnums;
118486 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
118487 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
118488 + uint32_t tx_10g_tnums;
118489 + uint32_t rx_10g_tnums;
118490 + uint32_t oh_tnums;
118491 + uint32_t shared_ext_tnums;
118492 +};
118493 +
118494 +typedef struct {
118495 + uint8_t id;
118496 + struct fm_active_ports fm_active_ports_info;
118497 + struct fm_resource_settings fm_resource_settings_info;
118498 +} t_LnxWrpFmDev;
118499 +
118500 +typedef struct {
118501 + uint8_t id;
118502 +} t_LnxWrpFmPortDev;
118503 +
118504 +typedef _Packed struct t_FmPrsResult {
118505 + volatile uint8_t lpid; /**< Logical port id */
118506 + volatile uint8_t shimr; /**< Shim header result */
118507 + volatile uint16_t l2r; /**< Layer 2 result */
118508 + volatile uint16_t l3r; /**< Layer 3 result */
118509 + volatile uint8_t l4r; /**< Layer 4 result */
118510 + volatile uint8_t cplan; /**< Classification plan id */
118511 + volatile uint16_t nxthdr; /**< Next Header */
118512 + volatile uint16_t cksum; /**< Checksum */
118513 + volatile uint32_t lcv; /**< LCV */
118514 + volatile uint8_t shim_off[3]; /**< Shim offset */
118515 + volatile uint8_t eth_off; /**< ETH offset */
118516 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
118517 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
118518 + volatile uint8_t etype_off; /**< ETYPE offset */
118519 + volatile uint8_t pppoe_off; /**< PPP offset */
118520 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
118521 + volatile uint8_t ip_off[2]; /**< IP offset */
118522 + volatile uint8_t gre_off; /**< GRE offset */
118523 + volatile uint8_t l4_off; /**< Layer 4 offset */
118524 + volatile uint8_t nxthdr_off; /**< Parser end point */
118525 +} _PackedType t_FmPrsResult;
118526 +
118527 +#endif
118528 --- /dev/null
118529 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
118530 @@ -0,0 +1,28 @@
118531 +CC=gcc
118532 +
118533 +LNXWRP_RESS_UT=lnxwrp_resources_ut
118534 +OBJ=lnxwrp_resources
118535 +
118536 +INC_PATH=
118537 +LIB_PATH=
118538 +
118539 +INC=$(addprefix -I,$(INC_PATH))
118540 +LIB=$(addprefix -L,$(LIB_PATH))
118541 +
118542 +CFLAGS= -gdwarf-2 -g -O0 -Wall
118543 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
118544 +
118545 +all: $(LNXWRP_RESS_UT)
118546 +
118547 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
118548 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
118549 +
118550 +%.o: %.c
118551 + @(echo " (CC) $@")
118552 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
118553 +
118554 +.PHONY: clean
118555 +
118556 +clean:
118557 + rm -f *.o
118558 + rm -f $(LNXWRP_RESS_UT)
118559 --- /dev/null
118560 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
118561 @@ -0,0 +1,60 @@
118562 +/*
118563 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118564 + *
118565 + * Redistribution and use in source and binary forms, with or without
118566 + * modification, are permitted provided that the following conditions are met:
118567 + * * Redistributions of source code must retain the above copyright
118568 + * notice, this list of conditions and the following disclaimer.
118569 + * * Redistributions in binary form must reproduce the above copyright
118570 + * notice, this list of conditions and the following disclaimer in the
118571 + * documentation and/or other materials provided with the distribution.
118572 + * * Neither the name of Freescale Semiconductor nor the
118573 + * names of its contributors may be used to endorse or promote products
118574 + * derived from this software without specific prior written permission.
118575 + *
118576 + *
118577 + * ALTERNATIVELY, this software may be distributed under the terms of the
118578 + * GNU General Public License ("GPL") as published by the Free Software
118579 + * Foundation, either version 2 of that License or (at your option) any
118580 + * later version.
118581 + *
118582 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118583 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118584 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118585 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118586 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118587 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118588 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118589 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118590 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118591 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118592 + */
118593 +
118594 +/*
118595 + @File lnxwrp_sysfs.c
118596 +
118597 + @Description FM wrapper sysfs related functions.
118598 +
118599 +*/
118600 +
118601 +#include <linux/types.h>
118602 +#include "lnxwrp_sysfs.h"
118603 +
118604 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
118605 + const struct sysfs_stats_t *sysfs_stats,
118606 + uint8_t *offset)
118607 +{
118608 + int i = 0;
118609 +
118610 + while (sysfs_stats[i].stat_name != NULL) {
118611 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
118612 + if (offset != NULL)
118613 + *offset = i;
118614 + return sysfs_stats[i].stat_counter;
118615 + }
118616 +
118617 + i++;
118618 + }
118619 + WARN(1, "FMD: Should never get here!");
118620 + return 0;
118621 +}
118622 --- /dev/null
118623 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
118624 @@ -0,0 +1,60 @@
118625 +/*
118626 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118627 + *
118628 + * Redistribution and use in source and binary forms, with or without
118629 + * modification, are permitted provided that the following conditions are met:
118630 + * * Redistributions of source code must retain the above copyright
118631 + * notice, this list of conditions and the following disclaimer.
118632 + * * Redistributions in binary form must reproduce the above copyright
118633 + * notice, this list of conditions and the following disclaimer in the
118634 + * documentation and/or other materials provided with the distribution.
118635 + * * Neither the name of Freescale Semiconductor nor the
118636 + * names of its contributors may be used to endorse or promote products
118637 + * derived from this software without specific prior written permission.
118638 + *
118639 + *
118640 + * ALTERNATIVELY, this software may be distributed under the terms of the
118641 + * GNU General Public License ("GPL") as published by the Free Software
118642 + * Foundation, either version 2 of that License or (at your option) any
118643 + * later version.
118644 + *
118645 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118646 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118647 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118648 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118649 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118650 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118651 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118652 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118653 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118654 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118655 + */
118656 +
118657 +#ifndef LNXWRP_SYSFS_H_
118658 +#define LNXWRP_SYSFS_H_
118659 +
118660 +/* Linux Headers ------------------- */
118661 +#include <linux/version.h>
118662 +
118663 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
118664 +#define MODVERSIONS
118665 +#endif
118666 +#ifdef MODVERSIONS
118667 +#include <config/modversions.h>
118668 +#endif /* MODVERSIONS */
118669 +
118670 +#include <linux/kernel.h>
118671 +#include <linux/module.h>
118672 +#include <linux/device.h>
118673 +#include <linux/sysfs.h>
118674 +
118675 +struct sysfs_stats_t {
118676 + const char *stat_name;
118677 + uint8_t stat_counter;
118678 +};
118679 +
118680 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
118681 + const struct sysfs_stats_t *sysfs_stats,
118682 + uint8_t *offset);
118683 +
118684 +#endif /* LNXWRP_SYSFS_H_ */
118685 --- /dev/null
118686 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
118687 @@ -0,0 +1,1855 @@
118688 +/*
118689 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118690 + *
118691 + * Redistribution and use in source and binary forms, with or without
118692 + * modification, are permitted provided that the following conditions are met:
118693 + * * Redistributions of source code must retain the above copyright
118694 + * notice, this list of conditions and the following disclaimer.
118695 + * * Redistributions in binary form must reproduce the above copyright
118696 + * notice, this list of conditions and the following disclaimer in the
118697 + * documentation and/or other materials provided with the distribution.
118698 + * * Neither the name of Freescale Semiconductor nor the
118699 + * names of its contributors may be used to endorse or promote products
118700 + * derived from this software without specific prior written permission.
118701 + *
118702 + *
118703 + * ALTERNATIVELY, this software may be distributed under the terms of the
118704 + * GNU General Public License ("GPL") as published by the Free Software
118705 + * Foundation, either version 2 of that License or (at your option) any
118706 + * later version.
118707 + *
118708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118718 + */
118719 +
118720 +#include "lnxwrp_sysfs.h"
118721 +#include "lnxwrp_sysfs_fm.h"
118722 +#include "lnxwrp_fm.h"
118723 +
118724 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
118725 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
118726 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
118727 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
118728 +
118729 +#if defined(__ERR_MODULE__)
118730 +#undef __ERR_MODULE__
118731 +#endif
118732 +
118733 +#include "../../sdk_fman/Peripherals/FM/fm.h"
118734 +#include <linux/delay.h>
118735 +
118736 +
118737 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
118738 +
118739 +enum fm_dma_match_stats {
118740 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
118741 + FM_DMA_COUNTERS_BUS_ERROR,
118742 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
118743 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
118744 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
118745 +};
118746 +
118747 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
118748 + /* FM statistics */
118749 + {
118750 + .stat_name = "enq_total_frame",
118751 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
118752 + },
118753 + {
118754 + .stat_name = "deq_total_frame",
118755 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
118756 + },
118757 + {
118758 + .stat_name = "deq_0",
118759 + .stat_counter = e_FM_COUNTERS_DEQ_0,
118760 + },
118761 + {
118762 + .stat_name = "deq_1",
118763 + .stat_counter = e_FM_COUNTERS_DEQ_1,
118764 + },
118765 + {
118766 + .stat_name = "deq_2",
118767 + .stat_counter = e_FM_COUNTERS_DEQ_2,
118768 + },
118769 + {
118770 + .stat_name = "deq_3",
118771 + .stat_counter = e_FM_COUNTERS_DEQ_3,
118772 + },
118773 + {
118774 + .stat_name = "deq_from_default",
118775 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
118776 + },
118777 + {
118778 + .stat_name = "deq_from_context",
118779 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
118780 + },
118781 + {
118782 + .stat_name = "deq_from_fd",
118783 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
118784 + },
118785 + {
118786 + .stat_name = "deq_confirm",
118787 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
118788 + },
118789 + /* FM:DMA statistics */
118790 + {
118791 + .stat_name = "cmq_not_empty",
118792 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
118793 + },
118794 + {
118795 + .stat_name = "bus_error",
118796 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
118797 + },
118798 + {
118799 + .stat_name = "read_buf_ecc_error",
118800 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
118801 + },
118802 + {
118803 + .stat_name = "write_buf_ecc_sys_error",
118804 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
118805 + },
118806 + {
118807 + .stat_name = "write_buf_ecc_fm_error",
118808 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
118809 + },
118810 + /* FM:PCD statistics */
118811 + {
118812 + .stat_name = "pcd_kg_total",
118813 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
118814 + },
118815 + {
118816 + .stat_name = "pcd_plcr_yellow",
118817 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
118818 + },
118819 + {
118820 + .stat_name = "pcd_plcr_red",
118821 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
118822 + },
118823 + {
118824 + .stat_name = "pcd_plcr_recolored_to_red",
118825 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
118826 + },
118827 + {
118828 + .stat_name = "pcd_plcr_recolored_to_yellow",
118829 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
118830 + },
118831 + {
118832 + .stat_name = "pcd_plcr_total",
118833 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
118834 + },
118835 + {
118836 + .stat_name = "pcd_plcr_length_mismatch",
118837 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
118838 + },
118839 + {
118840 + .stat_name = "pcd_prs_parse_dispatch",
118841 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
118842 + },
118843 + {
118844 + .stat_name = "pcd_prs_l2_parse_result_returned",
118845 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
118846 + },
118847 + {
118848 + .stat_name = "pcd_prs_l3_parse_result_returned",
118849 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
118850 + },
118851 + {
118852 + .stat_name = "pcd_prs_l4_parse_result_returned",
118853 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
118854 + },
118855 + {
118856 + .stat_name = "pcd_prs_shim_parse_result_returned",
118857 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
118858 + },
118859 + {
118860 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
118861 + .stat_counter =
118862 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
118863 + },
118864 + {
118865 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
118866 + .stat_counter =
118867 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
118868 + },
118869 + {
118870 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
118871 + .stat_counter =
118872 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
118873 + },
118874 + {
118875 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
118876 + .stat_counter =
118877 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
118878 + },
118879 + {
118880 + .stat_name = "pcd_prs_soft_prs_cycles",
118881 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
118882 + },
118883 + {
118884 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
118885 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
118886 + },
118887 + {
118888 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
118889 + .stat_counter =
118890 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
118891 + },
118892 + {
118893 + .stat_name = "pcd_prs_muram_read_cycles",
118894 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
118895 + },
118896 + {
118897 + .stat_name = "pcd_prs_muram_read_stall_cycles",
118898 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
118899 + },
118900 + {
118901 + .stat_name = "pcd_prs_muram_write_cycles",
118902 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
118903 + },
118904 + {
118905 + .stat_name = "pcd_prs_muram_write_stall_cycles",
118906 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
118907 + },
118908 + {
118909 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
118910 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
118911 + },
118912 + {}
118913 +};
118914 +
118915 +
118916 +static ssize_t show_fm_risc_load(struct device *dev,
118917 + struct device_attribute *attr, char *buf)
118918 +{
118919 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
118920 + unsigned long flags;
118921 + int m =0;
118922 + int err =0;
118923 + unsigned n = 0;
118924 + t_FmCtrlMon util;
118925 + uint8_t i =0 ;
118926 +
118927 + if (attr == NULL || buf == NULL || dev == NULL)
118928 + return -EINVAL;
118929 +
118930 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
118931 + if (WARN_ON(p_wrp_fm_dev == NULL))
118932 + return -EINVAL;
118933 +
118934 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
118935 + return -EIO;
118936 +
118937 + local_irq_save(flags);
118938 +
118939 + /* Calculate risc load */
118940 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
118941 + msleep(1000);
118942 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
118943 +
118944 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
118945 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
118946 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
118947 + i, util.percentCnt[0], util.percentCnt[1]);
118948 + n=m+n;
118949 + }
118950 +
118951 + local_irq_restore(flags);
118952 +
118953 + return n;
118954 +}
118955 +
118956 +/* Fm stats and regs dumps via sysfs */
118957 +static ssize_t show_fm_dma_stats(struct device *dev,
118958 + struct device_attribute *attr, char *buf)
118959 +{
118960 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
118961 + t_FmDmaStatus dma_status;
118962 + unsigned long flags = 0;
118963 + unsigned n = 0;
118964 + uint8_t counter_value = 0, counter = 0;
118965 +
118966 + if (attr == NULL || buf == NULL || dev == NULL)
118967 + return -EINVAL;
118968 +
118969 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
118970 + if (WARN_ON(p_wrp_fm_dev == NULL))
118971 + return -EINVAL;
118972 +
118973 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
118974 + return -EIO;
118975 +
118976 + counter = fm_find_statistic_counter_by_name(
118977 + attr->attr.name,
118978 + fm_sysfs_stats, NULL);
118979 +
118980 + local_irq_save(flags);
118981 +
118982 + memset(&dma_status, 0, sizeof(dma_status));
118983 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
118984 +
118985 + switch (counter) {
118986 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
118987 + counter_value = dma_status.cmqNotEmpty;
118988 + break;
118989 + case FM_DMA_COUNTERS_BUS_ERROR:
118990 + counter_value = dma_status.busError;
118991 + break;
118992 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
118993 + counter_value = dma_status.readBufEccError;
118994 + break;
118995 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
118996 + counter_value = dma_status.writeBufEccSysError;
118997 + break;
118998 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
118999 + counter_value = dma_status.writeBufEccFmError;
119000 + break;
119001 + default:
119002 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
119003 + __func__);
119004 + break;
119005 + };
119006 +
119007 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
119008 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
119009 +
119010 + local_irq_restore(flags);
119011 +
119012 + return n;
119013 +}
119014 +
119015 +static ssize_t show_fm_stats(struct device *dev,
119016 + struct device_attribute *attr, char *buf)
119017 +{
119018 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119019 + unsigned long flags = 0;
119020 + unsigned n = 0, cnt_e = 0;
119021 + uint32_t cnt_val;
119022 + int err;
119023 +
119024 + if (attr == NULL || buf == NULL || dev == NULL)
119025 + return -EINVAL;
119026 +
119027 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119028 + if (WARN_ON(p_wrp_fm_dev == NULL))
119029 + return -EINVAL;
119030 +
119031 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119032 + return -EIO;
119033 +
119034 + cnt_e = fm_find_statistic_counter_by_name(
119035 + attr->attr.name,
119036 + fm_sysfs_stats, NULL);
119037 +
119038 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
119039 + (e_FmCounters) cnt_e, &cnt_val);
119040 +
119041 + if (err)
119042 + return err;
119043 +
119044 + local_irq_save(flags);
119045 +
119046 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119047 + p_wrp_fm_dev->id, cnt_val);
119048 +
119049 + local_irq_restore(flags);
119050 +
119051 + return n;
119052 +}
119053 +
119054 +static ssize_t show_fm_muram_free_sz(struct device *dev,
119055 + struct device_attribute *attr, char *buf)
119056 +{
119057 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119058 + unsigned long flags = 0;
119059 + unsigned n = 0;
119060 + uint64_t muram_free_size = 0;
119061 +
119062 + if (attr == NULL || buf == NULL || dev == NULL)
119063 + return -EINVAL;
119064 +
119065 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119066 + if (WARN_ON(p_wrp_fm_dev == NULL))
119067 + return -EINVAL;
119068 +
119069 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119070 + return -EIO;
119071 +
119072 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
119073 +
119074 + local_irq_save(flags);
119075 +
119076 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
119077 + p_wrp_fm_dev->id, muram_free_size);
119078 +
119079 + local_irq_restore(flags);
119080 +
119081 + return n;
119082 +}
119083 +
119084 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
119085 + struct device_attribute *attr, char *buf)
119086 +{
119087 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119088 + unsigned long flags = 0;
119089 + unsigned n = 0;
119090 + t_FmCtrlCodeRevisionInfo rv_info;
119091 +
119092 + if (attr == NULL || buf == NULL || dev == NULL)
119093 + return -EINVAL;
119094 +
119095 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119096 + if (WARN_ON(p_wrp_fm_dev == NULL))
119097 + return -EINVAL;
119098 +
119099 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119100 + return -EIO;
119101 +
119102 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
119103 +
119104 + local_irq_save(flags);
119105 +
119106 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
119107 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
119108 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
119109 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
119110 +
119111 + local_irq_restore(flags);
119112 +
119113 + return n;
119114 +}
119115 +
119116 +static ssize_t show_fm_pcd_stats(struct device *dev,
119117 + struct device_attribute *attr, char *buf)
119118 +{
119119 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119120 + unsigned long flags = 0;
119121 + unsigned n = 0, counter = 0;
119122 +
119123 + if (attr == NULL || buf == NULL || dev == NULL)
119124 + return -EINVAL;
119125 +
119126 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119127 + if (WARN_ON(p_wrp_fm_dev == NULL))
119128 + return -EINVAL;
119129 +
119130 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
119131 + !p_wrp_fm_dev->h_PcdDev)
119132 + return -EIO;
119133 +
119134 + counter = fm_find_statistic_counter_by_name(
119135 + attr->attr.name,
119136 + fm_sysfs_stats, NULL);
119137 +
119138 + local_irq_save(flags);
119139 +
119140 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119141 + p_wrp_fm_dev->id,
119142 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
119143 + (e_FmPcdCounters) counter));
119144 +
119145 + local_irq_restore(flags);
119146 +
119147 + return n;
119148 +}
119149 +
119150 +static ssize_t show_fm_tnum_dbg(struct device *dev,
119151 + struct device_attribute *attr,
119152 + char *buf)
119153 +{
119154 + unsigned long flags;
119155 + unsigned n = 0;
119156 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119157 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119158 +#endif
119159 +
119160 + if (attr == NULL || buf == NULL || dev == NULL)
119161 + return -EINVAL;
119162 +
119163 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119164 +
119165 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119166 + if (WARN_ON(p_wrp_fm_dev == NULL))
119167 + return -EINVAL;
119168 +
119169 + local_irq_save(flags);
119170 +
119171 + if (!p_wrp_fm_dev->active)
119172 + return -EIO;
119173 + else {
119174 + int tn_s;
119175 +
119176 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
119177 + return -EINVAL;
119178 +
119179 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
119180 + tn_s, tn_s + 15, buf, n);
119181 + }
119182 + local_irq_restore(flags);
119183 +#else
119184 +
119185 + local_irq_save(flags);
119186 + n = snprintf(buf, PAGE_SIZE,
119187 + "Debug level is too low to dump registers!!!\n");
119188 + local_irq_restore(flags);
119189 +#endif /* (defined(DEBUG_ERRORS) && ... */
119190 +
119191 + return n;
119192 +}
119193 +
119194 +static ssize_t show_fm_cls_plan(struct device *dev,
119195 + struct device_attribute *attr,
119196 + char *buf)
119197 +{
119198 + unsigned long flags;
119199 + unsigned n = 0;
119200 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119201 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119202 +#endif
119203 +
119204 + if (attr == NULL || buf == NULL || dev == NULL)
119205 + return -EINVAL;
119206 +
119207 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119208 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119209 + if (WARN_ON(p_wrp_fm_dev == NULL))
119210 + return -EINVAL;
119211 +
119212 + local_irq_save(flags);
119213 +
119214 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
119215 +
119216 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119217 + return -EIO;
119218 + else {
119219 + int cpn;
119220 +
119221 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
119222 + return -EINVAL;
119223 +
119224 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
119225 + }
119226 + local_irq_restore(flags);
119227 +#else
119228 + local_irq_save(flags);
119229 + n = snprintf(buf, PAGE_SIZE,
119230 + "Debug level is too low to dump registers!!!\n");
119231 + local_irq_restore(flags);
119232 +#endif /* (defined(DEBUG_ERRORS) && ... */
119233 +
119234 + return n;
119235 +}
119236 +
119237 +static ssize_t show_fm_profiles(struct device *dev,
119238 + struct device_attribute *attr,
119239 + char *buf)
119240 +{
119241 + unsigned long flags;
119242 + unsigned n = 0;
119243 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119244 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119245 +#endif
119246 +
119247 + if (attr == NULL || buf == NULL || dev == NULL)
119248 + return -EINVAL;
119249 +
119250 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119251 +
119252 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119253 + if (WARN_ON(p_wrp_fm_dev == NULL))
119254 + return -EINVAL;
119255 +
119256 + local_irq_save(flags);
119257 +
119258 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
119259 +
119260 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119261 + return -EIO;
119262 + else {
119263 + int pn;
119264 +
119265 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
119266 + return -EINVAL;
119267 +
119268 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
119269 + }
119270 + local_irq_restore(flags);
119271 +#else
119272 + local_irq_save(flags);
119273 + n = snprintf(buf, PAGE_SIZE,
119274 + "Debug level is too low to dump registers!!!\n");
119275 + local_irq_restore(flags);
119276 +#endif /* (defined(DEBUG_ERRORS) && ... */
119277 +
119278 + return n;
119279 +}
119280 +
119281 +static ssize_t show_fm_schemes(struct device *dev,
119282 + struct device_attribute *attr,
119283 + char *buf)
119284 +{
119285 + unsigned long flags;
119286 + unsigned n = 0;
119287 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119288 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119289 +#endif
119290 +
119291 + if (attr == NULL || buf == NULL || dev == NULL)
119292 + return -EINVAL;
119293 +
119294 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119295 +
119296 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119297 + if (WARN_ON(p_wrp_fm_dev == NULL))
119298 + return -EINVAL;
119299 +
119300 + local_irq_save(flags);
119301 +
119302 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
119303 +
119304 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119305 + return -EIO;
119306 + else {
119307 + int sn;
119308 +
119309 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
119310 + return -EINVAL;
119311 +
119312 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
119313 + }
119314 + local_irq_restore(flags);
119315 +#else
119316 +
119317 + local_irq_save(flags);
119318 + n = snprintf(buf, PAGE_SIZE,
119319 + "Debug level is too low to dump registers!!!\n");
119320 + local_irq_restore(flags);
119321 +#endif /* (defined(DEBUG_ERRORS) && ... */
119322 +
119323 + return n;
119324 +}
119325 +
119326 +/* FM */
119327 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
119328 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
119329 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
119330 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
119331 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
119332 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
119333 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
119334 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
119335 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
119336 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
119337 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
119338 +/* FM:DMA */
119339 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
119340 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
119341 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
119342 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
119343 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
119344 +/* FM:PCD */
119345 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
119346 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
119347 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
119348 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
119349 + NULL);
119350 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
119351 + NULL);
119352 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
119353 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
119354 + NULL);
119355 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
119356 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
119357 + show_fm_pcd_stats, NULL);
119358 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
119359 + show_fm_pcd_stats, NULL);
119360 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
119361 + show_fm_pcd_stats, NULL);
119362 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
119363 + show_fm_pcd_stats, NULL);
119364 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
119365 + show_fm_pcd_stats, NULL);
119366 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
119367 + show_fm_pcd_stats, NULL);
119368 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
119369 + show_fm_pcd_stats, NULL);
119370 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
119371 + show_fm_pcd_stats, NULL);
119372 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
119373 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
119374 + NULL);
119375 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
119376 + show_fm_pcd_stats, NULL);
119377 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
119378 + NULL);
119379 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
119380 + show_fm_pcd_stats, NULL);
119381 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
119382 + NULL);
119383 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
119384 + show_fm_pcd_stats, NULL);
119385 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
119386 + show_fm_pcd_stats, NULL);
119387 +
119388 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
119389 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
119390 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
119391 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
119392 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
119393 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
119394 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
119395 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
119396 +
119397 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
119398 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
119399 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
119400 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
119401 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
119402 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
119403 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
119404 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
119405 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
119406 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
119407 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
119408 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
119409 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
119410 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
119411 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
119412 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
119413 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
119414 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
119415 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
119416 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
119417 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
119418 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
119419 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
119420 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
119421 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
119422 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
119423 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
119424 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
119425 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
119426 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
119427 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
119428 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
119429 +
119430 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
119431 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
119432 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
119433 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
119434 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
119435 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
119436 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
119437 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
119438 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
119439 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
119440 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
119441 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
119442 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
119443 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
119444 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
119445 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
119446 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
119447 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
119448 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
119449 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
119450 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
119451 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
119452 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
119453 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
119454 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
119455 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
119456 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
119457 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
119458 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
119459 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
119460 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
119461 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
119462 +
119463 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
119464 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
119465 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
119466 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
119467 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
119468 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
119469 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
119470 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
119471 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
119472 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
119473 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
119474 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
119475 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
119476 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
119477 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
119478 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
119479 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
119480 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
119481 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
119482 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
119483 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
119484 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
119485 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
119486 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
119487 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
119488 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
119489 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
119490 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
119491 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
119492 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
119493 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
119494 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
119495 +
119496 +
119497 +static struct attribute *fm_dev_stats_attributes[] = {
119498 + &dev_attr_enq_total_frame.attr,
119499 + &dev_attr_deq_total_frame.attr,
119500 + &dev_attr_deq_0.attr,
119501 + &dev_attr_deq_1.attr,
119502 + &dev_attr_deq_2.attr,
119503 + &dev_attr_deq_3.attr,
119504 + &dev_attr_deq_from_default.attr,
119505 + &dev_attr_deq_from_context.attr,
119506 + &dev_attr_deq_from_fd.attr,
119507 + &dev_attr_deq_confirm.attr,
119508 + &dev_attr_cmq_not_empty.attr,
119509 + &dev_attr_bus_error.attr,
119510 + &dev_attr_read_buf_ecc_error.attr,
119511 + &dev_attr_write_buf_ecc_sys_error.attr,
119512 + &dev_attr_write_buf_ecc_fm_error.attr,
119513 + &dev_attr_pcd_kg_total.attr,
119514 + &dev_attr_pcd_plcr_yellow.attr,
119515 + &dev_attr_pcd_plcr_red.attr,
119516 + &dev_attr_pcd_plcr_recolored_to_red.attr,
119517 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
119518 + &dev_attr_pcd_plcr_total.attr,
119519 + &dev_attr_pcd_plcr_length_mismatch.attr,
119520 + &dev_attr_pcd_prs_parse_dispatch.attr,
119521 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
119522 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
119523 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
119524 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
119525 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
119526 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
119527 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
119528 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
119529 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
119530 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
119531 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
119532 + &dev_attr_pcd_prs_muram_read_cycles.attr,
119533 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
119534 + &dev_attr_pcd_prs_muram_write_cycles.attr,
119535 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
119536 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
119537 + NULL
119538 +};
119539 +
119540 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
119541 + &dev_attr_tnum_dbg_0.attr,
119542 + &dev_attr_tnum_dbg_16.attr,
119543 + &dev_attr_tnum_dbg_32.attr,
119544 + &dev_attr_tnum_dbg_48.attr,
119545 + &dev_attr_tnum_dbg_64.attr,
119546 + &dev_attr_tnum_dbg_80.attr,
119547 + &dev_attr_tnum_dbg_96.attr,
119548 + &dev_attr_tnum_dbg_112.attr,
119549 + NULL
119550 +};
119551 +
119552 +static struct attribute *fm_dev_cls_plans_attributes[] = {
119553 + &dev_attr_cls_plan_0.attr,
119554 + &dev_attr_cls_plan_1.attr,
119555 + &dev_attr_cls_plan_2.attr,
119556 + &dev_attr_cls_plan_3.attr,
119557 + &dev_attr_cls_plan_4.attr,
119558 + &dev_attr_cls_plan_5.attr,
119559 + &dev_attr_cls_plan_6.attr,
119560 + &dev_attr_cls_plan_7.attr,
119561 + &dev_attr_cls_plan_8.attr,
119562 + &dev_attr_cls_plan_9.attr,
119563 + &dev_attr_cls_plan_10.attr,
119564 + &dev_attr_cls_plan_11.attr,
119565 + &dev_attr_cls_plan_12.attr,
119566 + &dev_attr_cls_plan_13.attr,
119567 + &dev_attr_cls_plan_14.attr,
119568 + &dev_attr_cls_plan_15.attr,
119569 + &dev_attr_cls_plan_16.attr,
119570 + &dev_attr_cls_plan_17.attr,
119571 + &dev_attr_cls_plan_18.attr,
119572 + &dev_attr_cls_plan_19.attr,
119573 + &dev_attr_cls_plan_20.attr,
119574 + &dev_attr_cls_plan_21.attr,
119575 + &dev_attr_cls_plan_22.attr,
119576 + &dev_attr_cls_plan_23.attr,
119577 + &dev_attr_cls_plan_24.attr,
119578 + &dev_attr_cls_plan_25.attr,
119579 + &dev_attr_cls_plan_26.attr,
119580 + &dev_attr_cls_plan_27.attr,
119581 + &dev_attr_cls_plan_28.attr,
119582 + &dev_attr_cls_plan_29.attr,
119583 + &dev_attr_cls_plan_30.attr,
119584 + &dev_attr_cls_plan_31.attr,
119585 + NULL
119586 +};
119587 +
119588 +static struct attribute *fm_dev_profiles_attributes[] = {
119589 + &dev_attr_profile_0.attr,
119590 + &dev_attr_profile_1.attr,
119591 + &dev_attr_profile_2.attr,
119592 + &dev_attr_profile_3.attr,
119593 + &dev_attr_profile_4.attr,
119594 + &dev_attr_profile_5.attr,
119595 + &dev_attr_profile_6.attr,
119596 + &dev_attr_profile_7.attr,
119597 + &dev_attr_profile_8.attr,
119598 + &dev_attr_profile_9.attr,
119599 + &dev_attr_profile_10.attr,
119600 + &dev_attr_profile_11.attr,
119601 + &dev_attr_profile_12.attr,
119602 + &dev_attr_profile_13.attr,
119603 + &dev_attr_profile_14.attr,
119604 + &dev_attr_profile_15.attr,
119605 + &dev_attr_profile_16.attr,
119606 + &dev_attr_profile_17.attr,
119607 + &dev_attr_profile_18.attr,
119608 + &dev_attr_profile_19.attr,
119609 + &dev_attr_profile_20.attr,
119610 + &dev_attr_profile_21.attr,
119611 + &dev_attr_profile_22.attr,
119612 + &dev_attr_profile_23.attr,
119613 + &dev_attr_profile_24.attr,
119614 + &dev_attr_profile_25.attr,
119615 + &dev_attr_profile_26.attr,
119616 + &dev_attr_profile_27.attr,
119617 + &dev_attr_profile_28.attr,
119618 + &dev_attr_profile_29.attr,
119619 + &dev_attr_profile_30.attr,
119620 + &dev_attr_profile_31.attr,
119621 + NULL
119622 +};
119623 +
119624 +static struct attribute *fm_dev_schemes_attributes[] = {
119625 + &dev_attr_scheme_0.attr,
119626 + &dev_attr_scheme_1.attr,
119627 + &dev_attr_scheme_2.attr,
119628 + &dev_attr_scheme_3.attr,
119629 + &dev_attr_scheme_4.attr,
119630 + &dev_attr_scheme_5.attr,
119631 + &dev_attr_scheme_6.attr,
119632 + &dev_attr_scheme_7.attr,
119633 + &dev_attr_scheme_8.attr,
119634 + &dev_attr_scheme_9.attr,
119635 + &dev_attr_scheme_10.attr,
119636 + &dev_attr_scheme_11.attr,
119637 + &dev_attr_scheme_12.attr,
119638 + &dev_attr_scheme_13.attr,
119639 + &dev_attr_scheme_14.attr,
119640 + &dev_attr_scheme_15.attr,
119641 + &dev_attr_scheme_16.attr,
119642 + &dev_attr_scheme_17.attr,
119643 + &dev_attr_scheme_18.attr,
119644 + &dev_attr_scheme_19.attr,
119645 + &dev_attr_scheme_20.attr,
119646 + &dev_attr_scheme_21.attr,
119647 + &dev_attr_scheme_22.attr,
119648 + &dev_attr_scheme_23.attr,
119649 + &dev_attr_scheme_24.attr,
119650 + &dev_attr_scheme_25.attr,
119651 + &dev_attr_scheme_26.attr,
119652 + &dev_attr_scheme_27.attr,
119653 + &dev_attr_scheme_28.attr,
119654 + &dev_attr_scheme_29.attr,
119655 + &dev_attr_scheme_30.attr,
119656 + &dev_attr_scheme_31.attr,
119657 + NULL
119658 +};
119659 +
119660 +static const struct attribute_group fm_dev_stats_attr_grp = {
119661 + .name = "statistics",
119662 + .attrs = fm_dev_stats_attributes
119663 +};
119664 +
119665 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
119666 + .name = "tnums_dbg",
119667 + .attrs = fm_dev_tnums_dbg_attributes
119668 +};
119669 +
119670 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
119671 + .name = "cls_plans",
119672 + .attrs = fm_dev_cls_plans_attributes
119673 +};
119674 +
119675 +static const struct attribute_group fm_dev_schemes_attr_grp = {
119676 + .name = "schemes",
119677 + .attrs = fm_dev_schemes_attributes
119678 +};
119679 +
119680 +static const struct attribute_group fm_dev_profiles_attr_grp = {
119681 + .name = "profiles",
119682 + .attrs = fm_dev_profiles_attributes
119683 +};
119684 +
119685 +static ssize_t show_fm_regs(struct device *dev,
119686 + struct device_attribute *attr,
119687 + char *buf)
119688 +{
119689 + unsigned long flags;
119690 + unsigned n = 0;
119691 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119692 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119693 +#endif
119694 + if (attr == NULL || buf == NULL || dev == NULL)
119695 + return -EINVAL;
119696 +
119697 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119698 +
119699 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119700 + if (WARN_ON(p_wrp_fm_dev == NULL))
119701 + return -EINVAL;
119702 +
119703 + local_irq_save(flags);
119704 +
119705 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
119706 +
119707 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119708 + return -EIO;
119709 + else
119710 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
119711 +
119712 + local_irq_restore(flags);
119713 +#else
119714 +
119715 + local_irq_save(flags);
119716 + n = snprintf(buf, PAGE_SIZE,
119717 + "Debug level is too low to dump registers!!!\n");
119718 + local_irq_restore(flags);
119719 +#endif /* (defined(DEBUG_ERRORS) && ... */
119720 +
119721 + return n;
119722 +}
119723 +
119724 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
119725 + struct device_attribute *attr,
119726 + char *buf)
119727 +{
119728 + unsigned long flags;
119729 + unsigned n = 0;
119730 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119731 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119732 +#endif
119733 +
119734 + if (attr == NULL || buf == NULL || dev == NULL)
119735 + return -EINVAL;
119736 +
119737 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119738 +
119739 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119740 + if (WARN_ON(p_wrp_fm_dev == NULL))
119741 + return -EINVAL;
119742 +
119743 + local_irq_save(flags);
119744 +
119745 + n = snprintf(buf, PAGE_SIZE,
119746 + "\n FM-KG Port Partition Config registers dump.\n");
119747 +
119748 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119749 + return -EIO;
119750 + else
119751 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119752 +
119753 + local_irq_restore(flags);
119754 +#else
119755 +
119756 + local_irq_save(flags);
119757 + n = snprintf(buf, PAGE_SIZE,
119758 + "Debug level is too low to dump registers!!!\n");
119759 + local_irq_restore(flags);
119760 +#endif /* (defined(DEBUG_ERRORS) && ... */
119761 +
119762 + return n;
119763 +}
119764 +
119765 +static ssize_t show_fm_kg_regs(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 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
119787 +
119788 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119789 + return -EIO;
119790 + else
119791 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119792 +
119793 + local_irq_restore(flags);
119794 +#else
119795 +
119796 + local_irq_save(flags);
119797 + n = snprintf(buf, PAGE_SIZE,
119798 + "Debug level is too low to dump registers!!!\n");
119799 + local_irq_restore(flags);
119800 +#endif /* (defined(DEBUG_ERRORS) && ... */
119801 +
119802 + return n;
119803 +}
119804 +
119805 +
119806 +static ssize_t show_fm_fpm_regs(struct device *dev,
119807 + struct device_attribute *attr,
119808 + char *buf)
119809 +{
119810 + unsigned long flags;
119811 + unsigned n = 0;
119812 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119813 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119814 +#endif
119815 +
119816 + if (attr == NULL || buf == NULL || dev == NULL)
119817 + return -EINVAL;
119818 +
119819 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119820 +
119821 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119822 + if (WARN_ON(p_wrp_fm_dev == NULL))
119823 + return -EINVAL;
119824 +
119825 + local_irq_save(flags);
119826 +
119827 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
119828 +
119829 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119830 + return -EIO;
119831 + else
119832 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
119833 +
119834 + local_irq_restore(flags);
119835 +#else
119836 +
119837 + local_irq_save(flags);
119838 + n = snprintf(buf, PAGE_SIZE,
119839 + "Debug level is too low to dump registers!!!\n");
119840 + local_irq_restore(flags);
119841 +#endif /* (defined(DEBUG_ERRORS) && ... */
119842 +
119843 + return n;
119844 +}
119845 +
119846 +static ssize_t show_prs_regs(struct device *dev,
119847 + struct device_attribute *attr, char *buf)
119848 +{
119849 + unsigned long flags;
119850 + unsigned n = 0;
119851 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119852 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119853 +#endif
119854 +
119855 + if (attr == NULL || buf == NULL || dev == NULL)
119856 + return -EINVAL;
119857 +
119858 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119859 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119860 + if (WARN_ON(p_wrp_fm_dev == NULL))
119861 + return -EINVAL;
119862 +
119863 + local_irq_save(flags);
119864 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
119865 +
119866 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119867 + return -EIO;
119868 + else
119869 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119870 +
119871 + local_irq_restore(flags);
119872 +#else
119873 +
119874 + local_irq_save(flags);
119875 + n = snprintf(buf, PAGE_SIZE,
119876 + "Debug level is too low to dump registers!!!\n");
119877 + local_irq_restore(flags);
119878 +
119879 +#endif /* (defined(DEBUG_ERRORS) && ... */
119880 +
119881 + return n;
119882 +}
119883 +
119884 +static ssize_t show_plcr_regs(struct device *dev,
119885 + struct device_attribute *attr,
119886 + char *buf)
119887 +{
119888 + unsigned long flags;
119889 + unsigned n = 0;
119890 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119891 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119892 +#endif
119893 +
119894 + if (attr == NULL || buf == NULL || dev == NULL)
119895 + return -EINVAL;
119896 +
119897 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119898 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119899 + if (WARN_ON(p_wrp_fm_dev == NULL))
119900 + return -EINVAL;
119901 +
119902 + local_irq_save(flags);
119903 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
119904 +
119905 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119906 + return -EIO;
119907 + else
119908 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
119909 +
119910 + local_irq_restore(flags);
119911 +#else
119912 +
119913 + local_irq_save(flags);
119914 + n = snprintf(buf, PAGE_SIZE,
119915 + "Debug level is too low to dump registers!!!\n");
119916 + local_irq_restore(flags);
119917 +
119918 +#endif /* (defined(DEBUG_ERRORS) && ... */
119919 +
119920 + return n;
119921 +}
119922 +
119923 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
119924 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
119925 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
119926 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
119927 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
119928 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
119929 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
119930 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
119931 +
119932 +int fm_sysfs_create(struct device *dev)
119933 +{
119934 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119935 +
119936 + if (dev == NULL)
119937 + return -EIO;
119938 +
119939 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119940 +
119941 + /* store to remove them when module is disabled */
119942 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
119943 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
119944 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
119945 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
119946 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
119947 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
119948 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
119949 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
119950 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
119951 +
119952 + /* Create sysfs statistics group for FM module */
119953 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
119954 + return -EIO;
119955 +
119956 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
119957 + return -EIO;
119958 +
119959 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
119960 + return -EIO;
119961 +
119962 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
119963 + return -EIO;
119964 +
119965 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
119966 + return -EIO;
119967 +
119968 + /* Registers dump entry - in future will be moved to debugfs */
119969 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
119970 + return -EIO;
119971 +
119972 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
119973 + return -EIO;
119974 +
119975 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
119976 + return -EIO;
119977 +
119978 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
119979 + return -EIO;
119980 +
119981 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
119982 + return -EIO;
119983 +
119984 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
119985 + return -EIO;
119986 +
119987 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
119988 + return -EIO;
119989 +
119990 + /* muram free size */
119991 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
119992 + return -EIO;
119993 +
119994 + /* fm ctrl code version */
119995 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
119996 + return -EIO;
119997 +
119998 + return 0;
119999 +}
120000 +
120001 +void fm_sysfs_destroy(struct device *dev)
120002 +{
120003 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120004 +
120005 + if (WARN_ON(dev == NULL))
120006 + return;
120007 +
120008 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120009 + if (WARN_ON(p_wrp_fm_dev == NULL))
120010 + return;
120011 +
120012 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
120013 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
120014 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
120015 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
120016 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
120017 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
120018 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
120019 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
120020 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
120021 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
120022 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
120023 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
120024 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
120025 +}
120026 +
120027 +int fm_dump_regs(void *h_fm, char *buf, int nn)
120028 +{
120029 + t_Fm *p_Fm = (t_Fm *)h_fm;
120030 + uint8_t i = 0;
120031 + int n = nn;
120032 +
120033 + FM_DMP_SUBTITLE(buf, n, "\n");
120034 +
120035 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
120036 +
120037 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
120038 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
120039 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
120040 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
120041 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
120042 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
120043 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
120044 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
120045 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
120046 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
120047 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
120048 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
120049 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
120050 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
120051 +
120052 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
120053 +
120054 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
120055 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
120056 +
120057 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
120058 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
120059 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
120060 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
120061 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
120062 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
120063 +
120064 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
120065 + for (i = 0; i < 8 ; ++i)
120066 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
120067 +
120068 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
120069 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
120070 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
120071 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
120072 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
120073 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
120074 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
120075 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
120076 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
120077 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
120078 +
120079 + return n;
120080 +}
120081 +
120082 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
120083 +{
120084 + t_Fm *p_Fm = (t_Fm *)h_fm;
120085 + uint8_t i, j = 0;
120086 + int n = nn;
120087 +
120088 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
120089 + tn_s, tn_e);
120090 +
120091 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
120092 +
120093 + mb();
120094 +
120095 + for (j = tn_s; j <= tn_e; j++) {
120096 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
120097 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
120098 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
120099 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
120100 +
120101 + for (i = 0; i < 4 ; ++i)
120102 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
120103 +
120104 + FM_DMP_LN(buf, n, "\n");
120105 +
120106 + }
120107 +
120108 + return n;
120109 +}
120110 +
120111 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
120112 +{
120113 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120114 + int i = 0;
120115 + uint32_t tmp;
120116 + unsigned long i_flg;
120117 + int n = nn;
120118 + u_FmPcdKgIndirectAccessRegs *idac;
120119 + spinlock_t *p_lk;
120120 +
120121 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120122 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120123 +
120124 + spin_lock_irqsave(p_lk, i_flg);
120125 +
120126 + /* Read ClsPlan Block Action Regs */
120127 + tmp = (uint32_t)(FM_KG_KGAR_GO |
120128 + FM_KG_KGAR_READ |
120129 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
120130 + DUMMY_PORT_ID |
120131 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
120132 + FM_PCD_KG_KGAR_WSEL_MASK);
120133 +
120134 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
120135 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120136 + spin_unlock_irqrestore(p_lk, i_flg);
120137 + return nn;
120138 + }
120139 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
120140 + "ClsPlan %d Indirect Access Regs", cpn);
120141 +
120142 + for (i = 0; i < 8; i++)
120143 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
120144 +
120145 + spin_unlock_irqrestore(p_lk, i_flg);
120146 +
120147 + return n;
120148 +}
120149 +
120150 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
120151 +{
120152 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120153 + t_FmPcdPlcrProfileRegs *p_prof_regs;
120154 + t_FmPcdPlcrRegs *p_plcr_regs;
120155 + t_FmPcdPlcr *p_plcr;
120156 + uint32_t tmp;
120157 + unsigned long i_flg;
120158 + int n = nn;
120159 + int toc = 10;
120160 + spinlock_t *p_lk;
120161 +
120162 + p_plcr = p_pcd->p_FmPcdPlcr;
120163 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
120164 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
120165 +
120166 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
120167 +
120168 + FM_DMP_SUBTITLE(buf, n, "\n");
120169 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
120170 +
120171 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
120172 + FM_PCD_PLCR_PAR_R |
120173 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
120174 + FM_PCD_PLCR_PAR_PWSEL_MASK);
120175 +
120176 + spin_lock_irqsave(p_lk, i_flg);
120177 +
120178 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
120179 +
120180 + mb();
120181 +
120182 + /* wait for the porfile regs to be present */
120183 + do {
120184 + --toc;
120185 + udelay(10);
120186 + if (!toc) {
120187 + /* looks like PLCR_PAR_GO refuses to clear */
120188 + spin_unlock_irqrestore(p_lk, i_flg);
120189 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
120190 + FM_DMP_LN(buf, n, " check profile init process\n");
120191 + return n;
120192 + }
120193 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
120194 +
120195 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
120196 +
120197 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
120198 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
120199 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
120200 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
120201 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
120202 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
120203 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
120204 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
120205 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
120206 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
120207 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
120208 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
120209 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
120210 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
120211 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
120212 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
120213 +
120214 + spin_unlock_irqrestore(p_lk, i_flg);
120215 +
120216 + return n;
120217 +}
120218 +
120219 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
120220 +{
120221 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120222 + uint32_t tmp_ar;
120223 + unsigned long i_flg;
120224 + int i, n = nn;
120225 + spinlock_t *p_lk;
120226 + u_FmPcdKgIndirectAccessRegs *idac;
120227 +
120228 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120229 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120230 +
120231 + spin_lock_irqsave(p_lk, i_flg);
120232 +
120233 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
120234 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
120235 + FM_DMP_LN(buf, nn,
120236 + "Keygen scheme access violation or no such scheme");
120237 + spin_unlock_irqrestore(p_lk, i_flg);
120238 + return nn;
120239 + }
120240 +
120241 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
120242 + "Scheme %d Indirect Access Regs", scnum);
120243 +
120244 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
120245 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
120246 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
120247 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
120248 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
120249 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
120250 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
120251 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
120252 +
120253 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
120254 +
120255 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
120256 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
120257 +
120258 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
120259 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
120260 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
120261 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
120262 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
120263 +
120264 + FM_DMP_SUBTITLE(buf, n, "\n");
120265 +
120266 + spin_unlock_irqrestore(p_lk, i_flg);
120267 +
120268 + return n;
120269 +}
120270 +
120271 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
120272 +{
120273 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120274 + int i = 0;
120275 + uint8_t prt_id = 0;
120276 + uint32_t tmp_ar;
120277 + unsigned long i_flg;
120278 + int n = nn;
120279 + u_FmPcdKgIndirectAccessRegs *idac;
120280 + t_FmPcdKg *p_kg;
120281 + spinlock_t *p_lk;
120282 +
120283 + p_kg = p_pcd->p_FmPcdKg;
120284 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120285 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
120286 +
120287 + spin_lock_irqsave(p_lk, i_flg);
120288 +
120289 + FM_DMP_SUBTITLE(buf, n, "\n");
120290 +
120291 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
120292 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
120293 +
120294 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
120295 +
120296 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
120297 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120298 + spin_unlock_irqrestore(p_lk, i_flg);
120299 + return nn;
120300 + }
120301 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
120302 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
120303 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
120304 + }
120305 +
120306 + FM_DMP_SUBTITLE(buf, n, "\n");
120307 +
120308 + spin_unlock_irqrestore(p_lk, i_flg);
120309 +
120310 + return n;
120311 +}
120312 +
120313 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
120314 +{
120315 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120316 + int n = nn;
120317 +
120318 + FM_DMP_SUBTITLE(buf, n, "\n");
120319 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
120320 + "FmPcdKgRegs Regs");
120321 +
120322 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
120323 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
120324 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
120325 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
120326 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
120327 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
120328 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
120329 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
120330 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
120331 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
120332 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
120333 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
120334 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
120335 +
120336 + FM_DMP_SUBTITLE(buf, n, "\n");
120337 +
120338 + return n;
120339 +}
120340 +
120341 +
120342 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
120343 +{
120344 + t_Fm *p_fm = (t_Fm *)h_fm;
120345 + uint8_t i;
120346 + int n = nn;
120347 +
120348 + FM_DMP_SUBTITLE(buf, n, "\n");
120349 +
120350 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
120351 +
120352 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
120353 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
120354 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
120355 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
120356 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
120357 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
120358 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
120359 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
120360 +
120361 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
120362 + for (i = 0; i < 4; ++i)
120363 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
120364 +
120365 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
120366 + for (i = 0; i < 4; ++i)
120367 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
120368 +
120369 + FM_DMP_SUBTITLE(buf, n, "\n");
120370 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
120371 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
120372 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
120373 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
120374 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
120375 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
120376 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
120377 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
120378 +
120379 + FM_DMP_SUBTITLE(buf, n, "\n");
120380 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
120381 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
120382 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
120383 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
120384 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
120385 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
120386 +
120387 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
120388 + for (i = 0; i < 4; ++i)
120389 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
120390 +
120391 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
120392 + for (i = 0; i < 64; ++i)
120393 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
120394 +
120395 + return n;
120396 +}
120397 +
120398 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
120399 +{
120400 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120401 + int n = nn;
120402 +
120403 + FM_DMP_SUBTITLE(buf, n, "\n");
120404 +
120405 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
120406 + "FM-PCD parser regs");
120407 +
120408 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
120409 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
120410 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
120411 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
120412 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
120413 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
120414 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
120415 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
120416 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
120417 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
120418 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
120419 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
120420 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
120421 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
120422 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
120423 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
120424 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
120425 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
120426 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
120427 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
120428 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
120429 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
120430 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
120431 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
120432 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
120433 +
120434 + return n;
120435 +}
120436 +
120437 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
120438 +{
120439 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120440 + int i = 0;
120441 + int n = nn;
120442 +
120443 + FM_DMP_SUBTITLE(buf, n, "\n");
120444 +
120445 + FM_DMP_TITLE(buf, n,
120446 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
120447 + "FM policer regs");
120448 +
120449 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
120450 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
120451 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
120452 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
120453 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
120454 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
120455 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
120456 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
120457 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
120458 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
120459 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
120460 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
120461 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
120462 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
120463 +
120464 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
120465 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
120466 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
120467 +
120468 + FM_DMP_TITLE(buf, n,
120469 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
120470 + "fmpl_pmr");
120471 +
120472 + for (i = 0; i < 63; ++i)
120473 + FM_DMP_MEM_32(buf, n,
120474 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
120475 +
120476 + return n;
120477 +}
120478 +
120479 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
120480 +{
120481 + t_Fm *p_fm = (t_Fm *)h_fm;
120482 +
120483 + /* When applicable (when there is an "enable counters" bit),
120484 + check that counters are enabled */
120485 +
120486 + switch (cnt_e) {
120487 + case (e_FM_COUNTERS_DEQ_1):
120488 + case (e_FM_COUNTERS_DEQ_2):
120489 + case (e_FM_COUNTERS_DEQ_3):
120490 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
120491 + return -EINVAL; /* counter not available */
120492 +
120493 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120494 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120495 + case (e_FM_COUNTERS_DEQ_0):
120496 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120497 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120498 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120499 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120500 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
120501 + QMI_CFG_EN_COUNTERS))
120502 + return -EINVAL; /* Requested counter not available */
120503 + break;
120504 + default:
120505 + break;
120506 + }
120507 +
120508 + switch (cnt_e) {
120509 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120510 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
120511 + return 0;
120512 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120513 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
120514 + return 0;
120515 + case (e_FM_COUNTERS_DEQ_0):
120516 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
120517 + return 0;
120518 + case (e_FM_COUNTERS_DEQ_1):
120519 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
120520 + return 0;
120521 + case (e_FM_COUNTERS_DEQ_2):
120522 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
120523 + return 0;
120524 + case (e_FM_COUNTERS_DEQ_3):
120525 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
120526 + return 0;
120527 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120528 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
120529 + return 0;
120530 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120531 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
120532 + return 0;
120533 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120534 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
120535 + return 0;
120536 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120537 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
120538 + return 0;
120539 + }
120540 + /* should never get here */
120541 + return -EINVAL; /* counter not available */
120542 +}
120543 --- /dev/null
120544 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
120545 @@ -0,0 +1,136 @@
120546 +/*
120547 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120548 + *
120549 + * Redistribution and use in source and binary forms, with or without
120550 + * modification, are permitted provided that the following conditions are met:
120551 + * * Redistributions of source code must retain the above copyright
120552 + * notice, this list of conditions and the following disclaimer.
120553 + * * Redistributions in binary form must reproduce the above copyright
120554 + * notice, this list of conditions and the following disclaimer in the
120555 + * documentation and/or other materials provided with the distribution.
120556 + * * Neither the name of Freescale Semiconductor nor the
120557 + * names of its contributors may be used to endorse or promote products
120558 + * derived from this software without specific prior written permission.
120559 + *
120560 + *
120561 + * ALTERNATIVELY, this software may be distributed under the terms of the
120562 + * GNU General Public License ("GPL") as published by the Free Software
120563 + * Foundation, either version 2 of that License or (at your option) any
120564 + * later version.
120565 + *
120566 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120567 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120568 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120569 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120570 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120571 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120572 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120573 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120574 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120575 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120576 + */
120577 +
120578 +
120579 +#ifndef LNXWRP_SYSFS_FM_H_
120580 +#define LNXWRP_SYSFS_FM_H_
120581 +
120582 +#include "lnxwrp_sysfs.h"
120583 +
120584 +int fm_sysfs_create(struct device *dev);
120585 +void fm_sysfs_destroy(struct device *dev);
120586 +int fm_dump_regs(void *h_dev, char *buf, int nn);
120587 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
120588 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
120589 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
120590 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
120591 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
120592 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
120593 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
120594 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
120595 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
120596 +
120597 +#define FM_DMP_PGSZ_ERR { \
120598 + snprintf(&buf[PAGE_SIZE - 80], 70, \
120599 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
120600 + n = PAGE_SIZE - 2; \
120601 + }
120602 +
120603 +#define FM_DMP_LN(buf, n, ...) \
120604 + do { \
120605 + int k, m = n; \
120606 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120607 + if (k < 0 || m > PAGE_SIZE - 90) \
120608 + FM_DMP_PGSZ_ERR \
120609 + n = m; \
120610 + } while (0)
120611 +
120612 +#define FM_DMP_TITLE(buf, n, addr, ...) \
120613 + do { \
120614 + int k, m = n; \
120615 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
120616 + if (k < 0 || m > PAGE_SIZE - 90) \
120617 + FM_DMP_PGSZ_ERR \
120618 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120619 + if (k < 0 || m > PAGE_SIZE - 90) \
120620 + FM_DMP_PGSZ_ERR \
120621 + if (addr) { \
120622 + phys_addr_t pa; \
120623 + pa = virt_to_phys(addr); \
120624 + m += k = \
120625 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
120626 + (long unsigned int)(pa)); \
120627 + if (k < 0 || m > PAGE_SIZE - 90) \
120628 + FM_DMP_PGSZ_ERR \
120629 + } \
120630 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
120631 + "\n----------------------------------------\n\n"); \
120632 + if (k < 0 || m > PAGE_SIZE - 90) \
120633 + FM_DMP_PGSZ_ERR \
120634 + n = m; \
120635 + } while (0)
120636 +
120637 +#define FM_DMP_SUBTITLE(buf, n, ...) \
120638 + do { \
120639 + int k, m = n; \
120640 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
120641 + if (k < 0 || m > PAGE_SIZE - 90) \
120642 + FM_DMP_PGSZ_ERR \
120643 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
120644 + if (k < 0 || m > PAGE_SIZE - 90) \
120645 + FM_DMP_PGSZ_ERR \
120646 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
120647 + if (k < 0 || m > PAGE_SIZE - 90) \
120648 + FM_DMP_PGSZ_ERR \
120649 + n = m; \
120650 + } while (0)
120651 +
120652 +#define FM_DMP_MEM_32(buf, n, addr) \
120653 + { \
120654 + uint32_t val; \
120655 + phys_addr_t pa; \
120656 + int k, m = n; \
120657 + pa = virt_to_phys(addr); \
120658 + val = ioread32be((addr)); \
120659 + do { \
120660 + m += k = snprintf(&buf[m], \
120661 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
120662 + pa, val); \
120663 + if (k < 0 || m > PAGE_SIZE - 90) \
120664 + FM_DMP_PGSZ_ERR \
120665 + n += k; \
120666 + } while (0) ;\
120667 + }
120668 +
120669 +#define FM_DMP_V32(buf, n, st, phrase) \
120670 + do { \
120671 + int k, m = n; \
120672 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
120673 + k = snprintf(&buf[m], PAGE_SIZE - m, \
120674 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
120675 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
120676 + if (k < 0 || m > PAGE_SIZE - 90) \
120677 + FM_DMP_PGSZ_ERR \
120678 + n += k; \
120679 + } while (0)
120680 +
120681 +#endif /* LNXWRP_SYSFS_FM_H_ */
120682 --- /dev/null
120683 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
120684 @@ -0,0 +1,1268 @@
120685 +/*
120686 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120687 + *
120688 + * Redistribution and use in source and binary forms, with or without
120689 + * modification, are permitted provided that the following conditions are met:
120690 + * * Redistributions of source code must retain the above copyright
120691 + * notice, this list of conditions and the following disclaimer.
120692 + * * Redistributions in binary form must reproduce the above copyright
120693 + * notice, this list of conditions and the following disclaimer in the
120694 + * documentation and/or other materials provided with the distribution.
120695 + * * Neither the name of Freescale Semiconductor nor the
120696 + * names of its contributors may be used to endorse or promote products
120697 + * derived from this software without specific prior written permission.
120698 + *
120699 + *
120700 + * ALTERNATIVELY, this software may be distributed under the terms of the
120701 + * GNU General Public License ("GPL") as published by the Free Software
120702 + * Foundation, either version 2 of that License or (at your option) any
120703 + * later version.
120704 + *
120705 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120706 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120707 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120708 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120709 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120710 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120711 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120712 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120713 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120714 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120715 + */
120716 +
120717 +#include "lnxwrp_sysfs.h"
120718 +#include "lnxwrp_fm.h"
120719 +#include "debug_ext.h"
120720 +#include "lnxwrp_sysfs_fm_port.h"
120721 +#include "lnxwrp_sysfs_fm.h"
120722 +
120723 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
120724 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
120725 +
120726 +#if defined(__ERR_MODULE__)
120727 +#undef __ERR_MODULE__
120728 +#endif
120729 +
120730 +#include "../../sdk_fman/Peripherals/FM/fm.h"
120731 +
120732 +static const struct sysfs_stats_t portSysfsStats[] = {
120733 + /* RX/TX/OH common statistics */
120734 + {
120735 + .stat_name = "port_frame",
120736 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
120737 + },
120738 + {
120739 + .stat_name = "port_discard_frame",
120740 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
120741 + },
120742 + {
120743 + .stat_name = "port_dealloc_buf",
120744 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
120745 + },
120746 + {
120747 + .stat_name = "port_enq_total",
120748 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
120749 + },
120750 + /* TX/OH */
120751 + {
120752 + .stat_name = "port_length_err",
120753 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
120754 + },
120755 + {
120756 + .stat_name = "port_unsupprted_format",
120757 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
120758 + },
120759 + {
120760 + .stat_name = "port_deq_total",
120761 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
120762 + },
120763 + {
120764 + .stat_name = "port_deq_from_default",
120765 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
120766 + },
120767 + {
120768 + .stat_name = "port_deq_confirm",
120769 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
120770 + },
120771 + /* RX/OH */
120772 + {
120773 + .stat_name = "port_rx_bad_frame",
120774 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
120775 + },
120776 + {
120777 + .stat_name = "port_rx_large_frame",
120778 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
120779 + },
120780 + {
120781 + .stat_name = "port_rx_out_of_buffers_discard",
120782 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
120783 + },
120784 + {
120785 + .stat_name = "port_rx_filter_frame",
120786 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
120787 + },
120788 + /* TODO: Particular statistics for OH ports */
120789 + {}
120790 +};
120791 +
120792 +static ssize_t show_fm_port_stats(struct device *dev,
120793 + struct device_attribute *attr, char *buf)
120794 +{
120795 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
120796 + t_LnxWrpFmDev *p_LnxWrpFmDev;
120797 + unsigned long flags;
120798 + int n = 0;
120799 + uint8_t counter = 0;
120800 +
120801 + if (attr == NULL || buf == NULL || dev == NULL)
120802 + return -EINVAL;
120803 +
120804 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
120805 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
120806 + return -EINVAL;
120807 +
120808 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
120809 + if (WARN_ON(p_LnxWrpFmDev == NULL))
120810 + return -EINVAL;
120811 +
120812 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
120813 + return -EIO;
120814 +
120815 + if (!p_LnxWrpFmPortDev->h_Dev) {
120816 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
120817 + return n;
120818 + }
120819 +
120820 + counter = fm_find_statistic_counter_by_name(
120821 + attr->attr.name,
120822 + portSysfsStats, NULL);
120823 +
120824 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
120825 + uint32_t fmRev = 0;
120826 + fmRev = 0xffff &
120827 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
120828 + 0x000c30c4));
120829 +
120830 + if (fmRev == 0x0100) {
120831 + local_irq_save(flags);
120832 + n = snprintf(buf, PAGE_SIZE,
120833 + "counter not available for revision 1\n");
120834 + local_irq_restore(flags);
120835 + }
120836 + return n;
120837 + }
120838 +
120839 + local_irq_save(flags);
120840 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
120841 + p_LnxWrpFmPortDev->name,
120842 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
120843 + (e_FmPortCounters) counter));
120844 + local_irq_restore(flags);
120845 +
120846 + return n;
120847 +}
120848 +
120849 +/* FM PORT RX/TX/OH statistics */
120850 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
120851 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
120852 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
120853 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
120854 +/* FM PORT TX/OH statistics */
120855 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
120856 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
120857 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
120858 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
120859 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
120860 +/* FM PORT RX/OH statistics */
120861 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
120862 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
120863 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
120864 + show_fm_port_stats, NULL);
120865 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
120866 +
120867 +/* FM PORT TX statistics */
120868 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
120869 + &dev_attr_port_frame.attr,
120870 + &dev_attr_port_discard_frame.attr,
120871 + &dev_attr_port_dealloc_buf.attr,
120872 + &dev_attr_port_enq_total.attr,
120873 + &dev_attr_port_length_err.attr,
120874 + &dev_attr_port_unsupprted_format.attr,
120875 + &dev_attr_port_deq_total.attr,
120876 + &dev_attr_port_deq_from_default.attr,
120877 + &dev_attr_port_deq_confirm.attr,
120878 + NULL
120879 +};
120880 +
120881 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
120882 + .name = "statistics",
120883 + .attrs = fm_tx_port_dev_stats_attributes
120884 +};
120885 +
120886 +/* FM PORT RX statistics */
120887 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
120888 + &dev_attr_port_frame.attr,
120889 + &dev_attr_port_discard_frame.attr,
120890 + &dev_attr_port_dealloc_buf.attr,
120891 + &dev_attr_port_enq_total.attr,
120892 + &dev_attr_port_rx_bad_frame.attr,
120893 + &dev_attr_port_rx_large_frame.attr,
120894 + &dev_attr_port_rx_out_of_buffers_discard.attr,
120895 + &dev_attr_port_rx_filter_frame.attr,
120896 + NULL
120897 +};
120898 +
120899 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
120900 + .name = "statistics",
120901 + .attrs = fm_rx_port_dev_stats_attributes
120902 +};
120903 +
120904 +/* TODO: add particular OH ports statistics */
120905 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
120906 + &dev_attr_port_frame.attr,
120907 + &dev_attr_port_discard_frame.attr,
120908 + &dev_attr_port_dealloc_buf.attr,
120909 + &dev_attr_port_enq_total.attr,
120910 + /*TX*/ &dev_attr_port_length_err.attr,
120911 + &dev_attr_port_unsupprted_format.attr,
120912 + &dev_attr_port_deq_total.attr,
120913 + &dev_attr_port_deq_from_default.attr,
120914 + &dev_attr_port_deq_confirm.attr,
120915 + /* &dev_attr_port_rx_bad_frame.attr, */
120916 + /* &dev_attr_port_rx_large_frame.attr, */
120917 + &dev_attr_port_rx_out_of_buffers_discard.attr,
120918 + /*&dev_attr_port_rx_filter_frame.attr, */
120919 + NULL
120920 +};
120921 +
120922 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
120923 + .name = "statistics",
120924 + .attrs = fm_oh_port_dev_stats_attributes
120925 +};
120926 +
120927 +static ssize_t show_fm_port_regs(struct device *dev,
120928 + struct device_attribute *attr, char *buf)
120929 +{
120930 + unsigned long flags;
120931 + unsigned n = 0;
120932 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120933 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
120934 +#endif
120935 + if (attr == NULL || buf == NULL || dev == NULL)
120936 + return -EINVAL;
120937 +
120938 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120939 + p_LnxWrpFmPortDev =
120940 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
120941 +
120942 +
120943 + local_irq_save(flags);
120944 +
120945 + if (!p_LnxWrpFmPortDev->h_Dev) {
120946 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
120947 + return n;
120948 + } else {
120949 + n = snprintf(buf, PAGE_SIZE,
120950 + "FM port driver registers dump.\n");
120951 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
120952 + }
120953 +
120954 + local_irq_restore(flags);
120955 +
120956 + return n;
120957 +#else
120958 +
120959 + local_irq_save(flags);
120960 + n = snprintf(buf, PAGE_SIZE,
120961 + "Debug level is too low to dump registers!!!\n");
120962 + local_irq_restore(flags);
120963 +
120964 + return n;
120965 +#endif
120966 +}
120967 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
120968 +{
120969 + t_FmPort *p_FmPort;
120970 + t_Fm *p_Fm;
120971 + uint8_t hardwarePortId;
120972 + uint32_t *param_page;
120973 + t_ArCommonDesc *ArCommonDescPtr;
120974 + uint32_t *mem;
120975 + int i, n = nn;
120976 +
120977 + p_FmPort = (t_FmPort *)h_dev;
120978 + hardwarePortId = p_FmPort->hardwarePortId;
120979 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
120980 +
120981 + if (!FM_PORT_IsInDsar(p_FmPort))
120982 + {
120983 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
120984 + hardwarePortId);
120985 + return n;
120986 + }
120987 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
120988 + FM_DMP_LN(buf, n, "========================\n");
120989 +
120990 + /* do I need request_mem_region here? */
120991 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
120992 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
120993 + mem = (uint32_t*)ArCommonDescPtr;
120994 + for (i = 0; i < 300; i+=4)
120995 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
120996 + iounmap(ArCommonDescPtr);
120997 + iounmap(param_page);
120998 + return n;
120999 +}
121000 +
121001 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
121002 +{
121003 + t_FmPort *p_FmPort;
121004 + t_Fm *p_Fm;
121005 + uint8_t hardwarePortId;
121006 + uint32_t *param_page;
121007 + t_ArCommonDesc *ArCommonDescPtr;
121008 + int i, n = nn;
121009 +
121010 + p_FmPort = (t_FmPort *)h_dev;
121011 + hardwarePortId = p_FmPort->hardwarePortId;
121012 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121013 +
121014 + if (!FM_PORT_IsInDsar(p_FmPort))
121015 + {
121016 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121017 + hardwarePortId);
121018 + return n;
121019 + }
121020 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
121021 + FM_DMP_LN(buf, n, "========================\n");
121022 +
121023 + /* do I need request_mem_region here? */
121024 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121025 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
121026 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
121027 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
121028 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
121029 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
121030 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
121031 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
121032 + ArCommonDescPtr->macStationAddr[5]);
121033 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
121034 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
121035 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
121036 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
121037 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
121038 + if (ArCommonDescPtr->p_ArStats)
121039 + {
121040 + t_ArStatistics *arStatistics = (t_ArStatistics*)
121041 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
121042 + p_FmPort->fmMuramPhysBaseAddr,
121043 + sizeof (t_ArStatistics));
121044 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
121045 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
121046 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
121047 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
121048 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
121049 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
121050 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
121051 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
121052 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
121053 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
121054 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
121055 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
121056 +
121057 + iounmap(arStatistics);
121058 + }
121059 + if (ArCommonDescPtr->p_ArpDescriptor)
121060 + {
121061 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
121062 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
121063 + p_FmPort->fmMuramPhysBaseAddr,
121064 + sizeof (t_DsarArpDescriptor));
121065 + FM_DMP_LN(buf, n, "\nARP\n");
121066 + FM_DMP_LN(buf, n, "===\n");
121067 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
121068 + if (ArpDescriptor->numOfBindings)
121069 + {
121070 + char ip_str[100];
121071 + t_DsarArpBindingEntry* bindings = ioremap(
121072 + ioread32be(&ArpDescriptor->p_Bindings) +
121073 + p_FmPort->fmMuramPhysBaseAddr,
121074 + ArpDescriptor->numOfBindings *
121075 + sizeof(t_DsarArpBindingEntry));
121076 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121077 + FM_DMP_LN(buf, n, " ip vlan id\n");
121078 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
121079 + {
121080 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121081 + ip_addr[0], ip_addr[1],
121082 + ip_addr[2], ip_addr[3]);
121083 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121084 + ip_str, bindings->vlanId);
121085 + }
121086 + iounmap(bindings);
121087 + }
121088 + if (ArpDescriptor->p_Statistics)
121089 + {
121090 + t_DsarArpStatistics* arpStats = ioremap(
121091 + ioread32be(&ArpDescriptor->p_Statistics) +
121092 + p_FmPort->fmMuramPhysBaseAddr,
121093 + sizeof(t_DsarArpStatistics));
121094 + FM_DMP_LN(buf, n, "statistics\n");
121095 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
121096 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
121097 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
121098 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
121099 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
121100 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
121101 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
121102 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
121103 + iounmap(arpStats);
121104 + }
121105 +
121106 + iounmap(ArpDescriptor);
121107 + }
121108 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
121109 + {
121110 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
121111 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
121112 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
121113 + p_FmPort->fmMuramPhysBaseAddr,
121114 + sizeof (t_DsarIcmpV4Descriptor));
121115 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
121116 + FM_DMP_LN(buf, n, "===========\n");
121117 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
121118 + if (ICMPV4Descriptor->numOfBindings)
121119 + {
121120 + char ip_str[100];
121121 + t_DsarArpBindingEntry* bindings = ioremap(
121122 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
121123 + p_FmPort->fmMuramPhysBaseAddr,
121124 + ICMPV4Descriptor->numOfBindings *
121125 + sizeof(t_DsarArpBindingEntry));
121126 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121127 + FM_DMP_LN(buf, n, " ip vlan id\n");
121128 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
121129 + {
121130 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121131 + ip_addr[0], ip_addr[1],
121132 + ip_addr[2], ip_addr[3]);
121133 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121134 + ip_str, bindings->vlanId);
121135 + }
121136 + iounmap(bindings);
121137 + }
121138 + if (ICMPV4Descriptor->p_Statistics)
121139 + {
121140 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
121141 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
121142 + p_FmPort->fmMuramPhysBaseAddr,
121143 + sizeof(t_DsarIcmpV4Statistics));
121144 + FM_DMP_LN(buf, n, "statistics\n");
121145 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
121146 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
121147 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
121148 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
121149 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
121150 + iounmap(icmpv4Stats);
121151 + }
121152 + iounmap(ICMPV4Descriptor);
121153 + }
121154 + if (ArCommonDescPtr->p_NdDescriptor)
121155 + {
121156 + t_DsarNdDescriptor *NDDescriptor =
121157 + (t_DsarNdDescriptor*)ioremap(ioread32be(
121158 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
121159 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
121160 + FM_DMP_LN(buf, n, "\nNDP\n");
121161 + FM_DMP_LN(buf, n, "===\n");
121162 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
121163 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
121164 + if (NDDescriptor->numOfBindings)
121165 + {
121166 + char ip_str[100];
121167 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121168 + ioread32be(&NDDescriptor->p_Bindings) +
121169 + p_FmPort->fmMuramPhysBaseAddr,
121170 + NDDescriptor->numOfBindings *
121171 + sizeof(t_DsarIcmpV6BindingEntry));
121172 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121173 + FM_DMP_LN(buf, n, " ip vlan id\n");
121174 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
121175 + {
121176 + n += snprintf(ip_str, 100,
121177 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121178 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121179 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121180 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121181 + }
121182 + iounmap(bindings);
121183 + }
121184 + if (NDDescriptor->p_Statistics)
121185 + {
121186 + t_NdStatistics* ndStats = ioremap(
121187 + ioread32be(&NDDescriptor->p_Statistics) +
121188 + p_FmPort->fmMuramPhysBaseAddr,
121189 + sizeof(t_NdStatistics));
121190 + FM_DMP_LN(buf, n, "statistics\n");
121191 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
121192 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
121193 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
121194 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
121195 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
121196 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
121197 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
121198 + iounmap(ndStats);
121199 + }
121200 + iounmap(NDDescriptor);
121201 + }
121202 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
121203 + {
121204 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
121205 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
121206 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
121207 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
121208 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
121209 + FM_DMP_LN(buf, n, "===========\n");
121210 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
121211 + if (ICMPV6Descriptor->numOfBindings)
121212 + {
121213 + char ip_str[100];
121214 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121215 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
121216 + p_FmPort->fmMuramPhysBaseAddr,
121217 + ICMPV6Descriptor->numOfBindings *
121218 + sizeof(t_DsarIcmpV6BindingEntry));
121219 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121220 + FM_DMP_LN(buf, n, " ip vlan id\n");
121221 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
121222 + {
121223 + n += snprintf(ip_str, 100,
121224 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121225 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121226 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121227 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121228 + }
121229 + iounmap(bindings);
121230 + }
121231 + if (ICMPV6Descriptor->p_Statistics)
121232 + {
121233 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
121234 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
121235 + p_FmPort->fmMuramPhysBaseAddr,
121236 + sizeof(t_DsarIcmpV6Statistics));
121237 + FM_DMP_LN(buf, n, "statistics\n");
121238 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
121239 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
121240 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
121241 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
121242 + iounmap(icmpv6Stats);
121243 + }
121244 + iounmap(ICMPV6Descriptor);
121245 + }
121246 + if (ArCommonDescPtr->p_SnmpDescriptor)
121247 + {
121248 + t_DsarSnmpDescriptor *SnmpDescriptor =
121249 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
121250 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
121251 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
121252 + FM_DMP_LN(buf, n, "\nSNMP\n");
121253 + FM_DMP_LN(buf, n, "===========\n");
121254 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
121255 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
121256 + if (SnmpDescriptor->numOfIpv4Addresses)
121257 + {
121258 + char ip_str[100];
121259 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
121260 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
121261 + p_FmPort->fmMuramPhysBaseAddr,
121262 + SnmpDescriptor->numOfIpv4Addresses *
121263 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
121264 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
121265 + FM_DMP_LN(buf, n, " ip vlan id\n");
121266 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
121267 + {
121268 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121269 + ip_addr[0], ip_addr[1],
121270 + ip_addr[2], ip_addr[3]);
121271 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
121272 + }
121273 + iounmap(addrs);
121274 + }
121275 + if (SnmpDescriptor->p_Statistics)
121276 + {
121277 + t_DsarSnmpStatistics* snmpStats = ioremap(
121278 + ioread32be(&SnmpDescriptor->p_Statistics) +
121279 + p_FmPort->fmMuramPhysBaseAddr,
121280 + sizeof(t_DsarSnmpStatistics));
121281 + FM_DMP_LN(buf, n, "statistics\n");
121282 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
121283 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
121284 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
121285 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
121286 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
121287 + iounmap(snmpStats);
121288 + }
121289 + iounmap(SnmpDescriptor);
121290 + }
121291 + iounmap(ArCommonDescPtr);
121292 + iounmap(param_page);
121293 + return n;
121294 +}
121295 +
121296 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
121297 + struct device_attribute *attr, char *buf)
121298 +{
121299 + unsigned long flags;
121300 + unsigned n = 0;
121301 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121302 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121303 +#endif
121304 + if (attr == NULL || buf == NULL || dev == NULL)
121305 + return -EINVAL;
121306 +
121307 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121308 + p_LnxWrpFmPortDev =
121309 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121310 +
121311 + local_irq_save(flags);
121312 +
121313 + if (!p_LnxWrpFmPortDev->h_Dev) {
121314 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121315 + return n;
121316 + } else {
121317 + n = snprintf(buf, PAGE_SIZE,
121318 + "FM port driver registers dump.\n");
121319 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
121320 + }
121321 +
121322 + local_irq_restore(flags);
121323 +
121324 + return n;
121325 +#else
121326 +
121327 + local_irq_save(flags);
121328 + n = snprintf(buf, PAGE_SIZE,
121329 + "Debug level is too low to dump registers!!!\n");
121330 + local_irq_restore(flags);
121331 +
121332 + return n;
121333 +#endif
121334 +}
121335 +
121336 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
121337 + struct device_attribute *attr, char *buf)
121338 +{
121339 + unsigned long flags;
121340 + unsigned n = 0;
121341 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121342 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121343 +#endif
121344 + if (attr == NULL || buf == NULL || dev == NULL)
121345 + return -EINVAL;
121346 +
121347 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121348 + p_LnxWrpFmPortDev =
121349 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121350 +
121351 + local_irq_save(flags);
121352 +
121353 + if (!p_LnxWrpFmPortDev->h_Dev) {
121354 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121355 + return n;
121356 + } else {
121357 + n = snprintf(buf, PAGE_SIZE,
121358 + "FM port driver registers dump.\n");
121359 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121360 + }
121361 +
121362 + local_irq_restore(flags);
121363 +
121364 + return n;
121365 +#else
121366 +
121367 + local_irq_save(flags);
121368 + n = snprintf(buf, PAGE_SIZE,
121369 + "Debug level is too low to dump registers!!!\n");
121370 + local_irq_restore(flags);
121371 +
121372 + return n;
121373 +#endif
121374 +}
121375 +
121376 +#if (DPAA_VERSION >= 11)
121377 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
121378 + struct device_attribute *attr, char *buf)
121379 +{
121380 + unsigned long flags;
121381 + unsigned n = 0;
121382 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121383 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121384 +#endif
121385 +
121386 + if (attr == NULL || buf == NULL || dev == NULL)
121387 + return -EINVAL;
121388 +
121389 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121390 + p_LnxWrpFmPortDev =
121391 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121392 +
121393 + local_irq_save(flags);
121394 +
121395 + if (!p_LnxWrpFmPortDev->h_Dev) {
121396 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121397 + return n;
121398 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
121399 + == NULL) {
121400 + n = snprintf(buf, PAGE_SIZE,
121401 + "\tPort: FMan-controller params page not set\n");
121402 + return n;
121403 + } else {
121404 + n = snprintf(buf, PAGE_SIZE,
121405 + "Counter for fragmented pkt with IP header options\n");
121406 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
121407 + }
121408 +
121409 + local_irq_restore(flags);
121410 +
121411 + return n;
121412 +#else
121413 +
121414 + local_irq_save(flags);
121415 + n = snprintf(buf, PAGE_SIZE,
121416 + "Debug level is too low to dump registers!!!\n");
121417 + local_irq_restore(flags);
121418 +
121419 + return n;
121420 +#endif
121421 +}
121422 +
121423 +#endif
121424 +
121425 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
121426 + struct device_attribute *attr, char *buf)
121427 +{
121428 + unsigned long flags;
121429 + unsigned n = 0;
121430 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121431 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121432 +#endif
121433 +
121434 + if (attr == NULL || buf == NULL || dev == NULL)
121435 + return -EINVAL;
121436 +
121437 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121438 + p_LnxWrpFmPortDev =
121439 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121440 +
121441 + local_irq_save(flags);
121442 +
121443 + if (!p_LnxWrpFmPortDev->h_Dev) {
121444 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121445 + return n;
121446 + } else {
121447 + n = snprintf(buf, PAGE_SIZE,
121448 + "FM port driver registers dump.\n");
121449 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121450 + }
121451 +
121452 + local_irq_restore(flags);
121453 +
121454 + return n;
121455 +#else
121456 +
121457 + local_irq_save(flags);
121458 + n = snprintf(buf, PAGE_SIZE,
121459 + "Debug level is too low to dump registers!!!\n");
121460 + local_irq_restore(flags);
121461 +
121462 + return n;
121463 +#endif
121464 +}
121465 +
121466 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
121467 + struct device_attribute *attr, char *buf)
121468 +{
121469 + unsigned long flags;
121470 + unsigned n = 0;
121471 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121472 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121473 +#endif
121474 +
121475 + if (attr == NULL || buf == NULL || dev == NULL)
121476 + return -EINVAL;
121477 +
121478 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121479 + p_LnxWrpFmPortDev =
121480 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121481 +
121482 + local_irq_save(flags);
121483 +
121484 + if (!p_LnxWrpFmPortDev->h_Dev) {
121485 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121486 + return n;
121487 + } else {
121488 + n = snprintf(buf, PAGE_SIZE,
121489 + "FM port driver registers dump.\n");
121490 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121491 + }
121492 +
121493 + local_irq_restore(flags);
121494 +
121495 + return n;
121496 +#else
121497 +
121498 + local_irq_save(flags);
121499 + n = snprintf(buf, PAGE_SIZE,
121500 + "Debug level is too low to dump registers!!!\n");
121501 + local_irq_restore(flags);
121502 +
121503 + return n;
121504 +#endif
121505 +}
121506 +
121507 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
121508 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
121509 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
121510 +#if (DPAA_VERSION >= 11)
121511 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
121512 +#endif
121513 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
121514 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
121515 +
121516 +int fm_port_sysfs_create(struct device *dev)
121517 +{
121518 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121519 +
121520 + if (dev == NULL)
121521 + return -EINVAL;
121522 +
121523 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121524 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121525 + return -EINVAL;
121526 +
121527 + /* store to remove them when module is disabled */
121528 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
121529 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
121530 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
121531 +#if (DPAA_VERSION >= 11)
121532 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
121533 +#endif
121534 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
121535 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
121536 + /* Registers dump entry - in future will be moved to debugfs */
121537 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
121538 + return -EIO;
121539 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
121540 + return -EIO;
121541 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
121542 + return -EIO;
121543 +#if (DPAA_VERSION >= 11)
121544 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
121545 + return -EIO;
121546 +#endif
121547 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
121548 + return -EIO;
121549 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
121550 + return -EIO;
121551 +
121552 + /* FM Ports statistics */
121553 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
121554 + case e_FM_PORT_TYPE_TX:
121555 + case e_FM_PORT_TYPE_TX_10G:
121556 + if (sysfs_create_group
121557 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
121558 + return -EIO;
121559 + break;
121560 + case e_FM_PORT_TYPE_RX:
121561 + case e_FM_PORT_TYPE_RX_10G:
121562 + if (sysfs_create_group
121563 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
121564 + return -EIO;
121565 + break;
121566 + case e_FM_PORT_TYPE_DUMMY:
121567 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
121568 + if (sysfs_create_group
121569 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
121570 + return -EIO;
121571 + break;
121572 + default:
121573 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121574 + __func__);
121575 + return -EINVAL;
121576 + break;
121577 + };
121578 +
121579 + return 0;
121580 +}
121581 +
121582 +void fm_port_sysfs_destroy(struct device *dev)
121583 +{
121584 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
121585 +
121586 + /* this function has never been tested !!! */
121587 +
121588 + if (WARN_ON(dev == NULL))
121589 + return;
121590 +
121591 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121592 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121593 + return;
121594 +
121595 + /* The name attribute will be freed also by these 2 functions? */
121596 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
121597 + case e_FM_PORT_TYPE_TX:
121598 + case e_FM_PORT_TYPE_TX_10G:
121599 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
121600 + break;
121601 + case e_FM_PORT_TYPE_RX:
121602 + case e_FM_PORT_TYPE_RX_10G:
121603 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
121604 + break;
121605 + case e_FM_PORT_TYPE_DUMMY:
121606 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
121607 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
121608 + break;
121609 + default:
121610 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121611 + __func__);
121612 + break;
121613 + };
121614 +
121615 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
121616 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
121617 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
121618 +#if (DPAA_VERSION >= 11)
121619 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
121620 +#endif
121621 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
121622 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
121623 +}
121624 +
121625 +
121626 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
121627 +{
121628 + t_FmPort *p_FmPort;
121629 + t_Fm *p_Fm;
121630 + uint8_t hardwarePortId;
121631 + int n = nn;
121632 +
121633 + p_FmPort = (t_FmPort *)h_dev;
121634 + hardwarePortId = p_FmPort->hardwarePortId;
121635 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121636 +
121637 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
121638 + "fmbm_pp for port %u", hardwarePortId);
121639 + FM_DMP_MEM_32(buf, n,
121640 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
121641 +
121642 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
121643 + "fmbm_pfs for port %u", hardwarePortId);
121644 + FM_DMP_MEM_32(buf, n,
121645 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
121646 +
121647 + FM_DMP_TITLE(buf, n,
121648 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
121649 + "fmbm_spliodn for port %u", hardwarePortId);
121650 + FM_DMP_MEM_32(buf, n,
121651 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
121652 +
121653 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
121654 + "fmfp_psfor port %u", hardwarePortId);
121655 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
121656 +
121657 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
121658 + "fmdmplrfor port %u", hardwarePortId);
121659 + FM_DMP_MEM_32(buf, n,
121660 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
121661 + return n;
121662 +}
121663 +
121664 +#if (DPAA_VERSION >= 11)
121665 +
121666 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
121667 +{
121668 + t_FmPort *p_FmPort;
121669 + int n = nn;
121670 +
121671 + p_FmPort = (t_FmPort *)h_dev;
121672 +
121673 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
121674 +
121675 + FM_DMP_SUBTITLE(buf, n, "\n");
121676 +
121677 + return n;
121678 +}
121679 +#endif
121680 +
121681 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
121682 +{
121683 + t_FmPort *p_FmPort;
121684 + u_FmPortBmiRegs *p_bmi;
121685 +
121686 + char arr[20];
121687 + uint8_t flag;
121688 + int i = 0;
121689 + int n = nn;
121690 +
121691 + p_FmPort = (t_FmPort *)h_dev;
121692 + p_bmi = p_FmPort->p_FmPortBmiRegs;
121693 +
121694 + memset(arr, 0, sizeof(arr));
121695 + switch (p_FmPort->portType) {
121696 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
121697 + strcpy(arr, "OFFLINE-PARSING");
121698 + flag = 0;
121699 + break;
121700 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
121701 + strcpy(arr, "HOST-COMMAND");
121702 + flag = 0;
121703 + break;
121704 + case (e_FM_PORT_TYPE_RX):
121705 + strcpy(arr, "RX");
121706 + flag = 1;
121707 + break;
121708 + case (e_FM_PORT_TYPE_RX_10G):
121709 + strcpy(arr, "RX-10G");
121710 + flag = 1;
121711 + break;
121712 + case (e_FM_PORT_TYPE_TX):
121713 + strcpy(arr, "TX");
121714 + flag = 2;
121715 + break;
121716 + case (e_FM_PORT_TYPE_TX_10G):
121717 + strcpy(arr, "TX-10G");
121718 + flag = 2;
121719 + break;
121720 + default:
121721 + return -EINVAL;
121722 + }
121723 +
121724 + FM_DMP_TITLE(buf, n, NULL,
121725 + "FMan-Port (%s #%d) registers:",
121726 + arr, p_FmPort->portId);
121727 +
121728 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
121729 +
121730 + switch (flag) {
121731 + case (0):
121732 + FM_DMP_SUBTITLE(buf, n, "\n");
121733 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
121734 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
121735 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
121736 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
121737 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
121738 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
121739 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
121740 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
121741 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
121742 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
121743 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
121744 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
121745 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
121746 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
121747 +
121748 + FM_DMP_TITLE(buf, n,
121749 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
121750 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
121751 + FM_DMP_MEM_32(buf, n,
121752 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
121753 + }
121754 + FM_DMP_SUBTITLE(buf, n, "\n");
121755 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
121756 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
121757 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
121758 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
121759 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
121760 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
121761 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
121762 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
121763 + {
121764 +#ifndef FM_NO_OP_OBSERVED_POOLS
121765 + if (p_FmPort->fmRevInfo.majorRev == 4) {
121766 + FM_DMP_TITLE(buf, n,
121767 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
121768 + "fmbm_oebmpi");
121769 +
121770 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
121771 + FM_DMP_MEM_32(buf, n,
121772 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
121773 + }
121774 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
121775 + }
121776 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
121777 + }
121778 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
121779 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
121780 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
121781 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
121782 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
121783 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
121784 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
121785 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
121786 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
121787 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
121788 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
121789 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
121790 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
121791 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
121792 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
121793 + "fmbm_odcfg");
121794 + for (i = 0; i < 3; ++i) {
121795 + FM_DMP_MEM_32(buf, n,
121796 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
121797 + }
121798 + FM_DMP_SUBTITLE(buf, n, "\n");
121799 +
121800 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
121801 + break;
121802 + case (1):
121803 + FM_DMP_SUBTITLE(buf, n, "\n");
121804 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
121805 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
121806 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
121807 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
121808 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
121809 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
121810 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
121811 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
121812 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
121813 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
121814 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
121815 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
121816 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
121817 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
121818 + "fmbm_rprai");
121819 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
121820 + FM_DMP_MEM_32(buf, n,
121821 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
121822 + }
121823 + FM_DMP_SUBTITLE(buf, n, "\n");
121824 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
121825 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
121826 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
121827 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
121828 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
121829 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
121830 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
121831 + "fmbm_ebmpi");
121832 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
121833 + FM_DMP_MEM_32(buf, n,
121834 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
121835 + }
121836 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
121837 + "fmbm_acnt");
121838 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
121839 + FM_DMP_MEM_32(buf, n,
121840 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
121841 + }
121842 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
121843 + "fmbm_rcgm");
121844 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
121845 + FM_DMP_MEM_32(buf, n,
121846 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
121847 + }
121848 +
121849 + FM_DMP_SUBTITLE(buf, n, "\n");
121850 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
121851 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
121852 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
121853 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
121854 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
121855 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
121856 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
121857 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
121858 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
121859 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
121860 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
121861 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
121862 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
121863 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
121864 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
121865 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
121866 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
121867 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
121868 + "fmbm_rdcfg");
121869 + for (i = 0; i < 3; ++i) {
121870 + FM_DMP_MEM_32(buf, n,
121871 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
121872 + }
121873 + FM_DMP_SUBTITLE(buf, n, "\n");
121874 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
121875 + break;
121876 + case (2):
121877 + FM_DMP_SUBTITLE(buf, n, "\n");
121878 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
121879 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
121880 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
121881 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
121882 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
121883 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
121884 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
121885 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
121886 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
121887 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
121888 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
121889 +#if (DPAA_VERSION >= 11)
121890 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
121891 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
121892 +#endif /* (DPAA_VERSION >= 11) */
121893 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
121894 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
121895 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
121896 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
121897 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
121898 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
121899 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
121900 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
121901 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
121902 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
121903 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
121904 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
121905 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
121906 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
121907 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
121908 + "fmbm_tdcfg");
121909 + for (i = 0; i < 3 ; ++i) {
121910 + FM_DMP_MEM_32(buf, n,
121911 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
121912 + }
121913 + FM_DMP_SUBTITLE(buf, n, "\n");
121914 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
121915 + break;
121916 + }
121917 +
121918 + FM_DMP_SUBTITLE(buf, n, "\n");
121919 +
121920 + return n;
121921 +}
121922 +
121923 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
121924 +{
121925 + t_FmPort *p_FmPort;
121926 + int n = nn;
121927 +
121928 + p_FmPort = (t_FmPort *)h_dev;
121929 +
121930 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
121931 +
121932 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
121933 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
121934 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
121935 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
121936 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
121937 + FM_DMP_V32(buf, n,
121938 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
121939 + FM_DMP_V32(buf, n,
121940 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
121941 + FM_DMP_V32(buf, n,
121942 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
121943 + FM_DMP_V32(buf, n,
121944 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
121945 + FM_DMP_V32(buf, n,
121946 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
121947 +
121948 + FM_DMP_SUBTITLE(buf, n, "\n");
121949 +
121950 + return n;
121951 +}
121952 +
121953 --- /dev/null
121954 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
121955 @@ -0,0 +1,56 @@
121956 +/*
121957 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121958 + *
121959 + * Redistribution and use in source and binary forms, with or without
121960 + * modification, are permitted provided that the following conditions are met:
121961 + * * Redistributions of source code must retain the above copyright
121962 + * notice, this list of conditions and the following disclaimer.
121963 + * * Redistributions in binary form must reproduce the above copyright
121964 + * notice, this list of conditions and the following disclaimer in the
121965 + * documentation and/or other materials provided with the distribution.
121966 + * * Neither the name of Freescale Semiconductor nor the
121967 + * names of its contributors may be used to endorse or promote products
121968 + * derived from this software without specific prior written permission.
121969 + *
121970 + *
121971 + * ALTERNATIVELY, this software may be distributed under the terms of the
121972 + * GNU General Public License ("GPL") as published by the Free Software
121973 + * Foundation, either version 2 of that License or (at your option) any
121974 + * later version.
121975 + *
121976 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121977 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121978 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121979 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121980 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121981 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121982 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121983 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121984 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121985 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121986 + */
121987 +
121988 +/*
121989 + @File lnxwrp_sysfs_fm_port.h
121990 +
121991 + @Description FM port sysfs functions.
121992 +
121993 +*/
121994 +
121995 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
121996 +#define LNXWRP_SYSFS_FM_PORT_H_
121997 +
121998 +#include "lnxwrp_sysfs.h"
121999 +
122000 +int fm_port_sysfs_create(struct device *dev);
122001 +void fm_port_sysfs_destroy(struct device *dev);
122002 +
122003 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
122004 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
122005 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
122006 +
122007 +#if (DPAA_VERSION >= 11)
122008 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
122009 +#endif
122010 +
122011 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
122012 --- /dev/null
122013 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122014 @@ -0,0 +1,18 @@
122015 +#
122016 +# Makefile for the Freescale Ethernet controllers
122017 +#
122018 +ccflags-y += -DVERSION=\"\"
122019 +#
122020 +#Include netcomm SW specific definitions
122021 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
122022 +
122023 +obj-y += fsl-ncsw-xx.o
122024 +
122025 +ifneq ($(CONFIG_FMAN_ARM),y)
122026 +fsl-ncsw-xx-objs := xx_linux.o \
122027 + module_strings.o
122028 +else
122029 +fsl-ncsw-xx-objs := xx_arm_linux.o \
122030 + module_strings.o
122031 +endif
122032 +
122033 --- /dev/null
122034 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122035 @@ -0,0 +1,46 @@
122036 +/*
122037 + * Copyright 2012 Freescale Semiconductor Inc.
122038 + *
122039 + * Redistribution and use in source and binary forms, with or without
122040 + * modification, are permitted provided that the following conditions are met:
122041 + * * Redistributions of source code must retain the above copyright
122042 + * notice, this list of conditions and the following disclaimer.
122043 + * * Redistributions in binary form must reproduce the above copyright
122044 + * notice, this list of conditions and the following disclaimer in the
122045 + * documentation and/or other materials provided with the distribution.
122046 + * * Neither the name of Freescale Semiconductor nor the
122047 + * names of its contributors may be used to endorse or promote products
122048 + * derived from this software without specific prior written permission.
122049 + *
122050 + *
122051 + * ALTERNATIVELY, this software may be distributed under the terms of the
122052 + * GNU General Public License ("GPL") as published by the Free Software
122053 + * Foundation, either version 2 of that License or (at your option) any
122054 + * later version.
122055 + *
122056 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122057 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122058 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122059 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122060 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122061 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122062 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122063 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122064 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122065 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122066 + */
122067 +
122068 +/* Module names for debug messages */
122069 +const char *moduleStrings[] =
122070 +{
122071 + "", /* MODULE_UNKNOWN */
122072 + "FM", /* MODULE_FM */
122073 + "FM-MURAM", /* MODULE_FM_MURAM */
122074 + "FM-PCD", /* MODULE_FM_PCD */
122075 + "FM-RTC", /* MODULE_FM_RTC */
122076 + "FM-MAC", /* MODULE_FM_MAC */
122077 + "FM-Port", /* MODULE_FM_PORT */
122078 + "MM", /* MODULE_MM */
122079 + "FM-SP", /* MODULE_FM_SP */
122080 + "FM-MACSEC" /* MODULE_FM_MACSEC */
122081 +};
122082 --- /dev/null
122083 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122084 @@ -0,0 +1,905 @@
122085 +/*
122086 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122087 + *
122088 + * Redistribution and use in source and binary forms, with or without
122089 + * modification, are permitted provided that the following conditions are met:
122090 + * * Redistributions of source code must retain the above copyright
122091 + * notice, this list of conditions and the following disclaimer.
122092 + * * Redistributions in binary form must reproduce the above copyright
122093 + * notice, this list of conditions and the following disclaimer in the
122094 + * documentation and/or other materials provided with the distribution.
122095 + * * Neither the name of Freescale Semiconductor nor the
122096 + * names of its contributors may be used to endorse or promote products
122097 + * derived from this software without specific prior written permission.
122098 + *
122099 + *
122100 + * ALTERNATIVELY, this software may be distributed under the terms of the
122101 + * GNU General Public License ("GPL") as published by the Free Software
122102 + * Foundation, either version 2 of that License or (at your option) any
122103 + * later version.
122104 + *
122105 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122106 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122107 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122108 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122109 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122110 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122111 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122112 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122113 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122114 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122115 + */
122116 +
122117 +/**************************************************************************//**
122118 + @File xx_arm_linux.c
122119 +
122120 + @Description XX routines implementation for Linux.
122121 +*//***************************************************************************/
122122 +#include <linux/version.h>
122123 +
122124 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
122125 +#define MODVERSIONS
122126 +#endif
122127 +#ifdef MODVERSIONS
122128 +#include <config/modversions.h>
122129 +#endif /* MODVERSIONS */
122130 +
122131 +#include <linux/module.h>
122132 +#include <linux/kernel.h>
122133 +#include <linux/sched.h>
122134 +#include <linux/string.h>
122135 +#include <linux/ptrace.h>
122136 +#include <linux/errno.h>
122137 +#include <linux/ioport.h>
122138 +#include <linux/slab.h>
122139 +#include <linux/interrupt.h>
122140 +#include <linux/fs.h>
122141 +#include <linux/vmalloc.h>
122142 +#include <linux/init.h>
122143 +#include <linux/timer.h>
122144 +#include <linux/spinlock.h>
122145 +#include <linux/delay.h>
122146 +#include <linux/proc_fs.h>
122147 +#include <linux/smp.h>
122148 +#include <linux/of.h>
122149 +#include <linux/irqdomain.h>
122150 +
122151 +#include <linux/workqueue.h>
122152 +
122153 +#ifdef BIGPHYSAREA_ENABLE
122154 +#include <linux/bigphysarea.h>
122155 +#endif /* BIGPHYSAREA_ENABLE */
122156 +
122157 +//#include <sysdev/fsl_soc.h>
122158 +#include <asm/pgtable.h>
122159 +#include <asm/irq.h>
122160 +#include <asm/bitops.h>
122161 +#include <asm/uaccess.h>
122162 +#include <asm/io.h>
122163 +#include <asm/atomic.h>
122164 +#include <asm/string.h>
122165 +#include <asm/byteorder.h>
122166 +#include <asm/page.h>
122167 +
122168 +#include "error_ext.h"
122169 +#include "std_ext.h"
122170 +#include "list_ext.h"
122171 +#include "mm_ext.h"
122172 +#include "sys_io_ext.h"
122173 +#include "xx.h"
122174 +
122175 +
122176 +#define __ERR_MODULE__ MODULE_UNKNOWN
122177 +
122178 +#ifdef BIGPHYSAREA_ENABLE
122179 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
122180 +
122181 +
122182 +/* TODO: large allocations => use big phys area */
122183 +/******************************************************************************
122184 + * routine: get_nr_pages
122185 + *
122186 + * description:
122187 + * calculates the number of memory pages for a given size (in bytes)
122188 + *
122189 + * arguments:
122190 + * size - the number of bytes
122191 + *
122192 + * return code:
122193 + * The number of pages
122194 + *
122195 + *****************************************************************************/
122196 +static __inline__ uint32_t get_nr_pages (uint32_t size)
122197 +{
122198 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
122199 +}
122200 +
122201 +static bool in_big_phys_area (uint32_t addr)
122202 +{
122203 + uint32_t base, size;
122204 +
122205 + bigphysarea_get_details (&base, &size);
122206 + return ((addr >= base) && (addr < base + size));
122207 +}
122208 +#endif /* BIGPHYSAREA_ENABLE */
122209 +
122210 +void * xx_Malloc(uint32_t n)
122211 +{
122212 + void *a;
122213 + uint32_t flags;
122214 +
122215 + flags = XX_DisableAllIntr();
122216 +#ifdef BIGPHYSAREA_ENABLE
122217 + if (n >= MAX_ALLOCATION_SIZE)
122218 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
122219 + else
122220 +#endif /* BIGPHYSAREA_ENABLE */
122221 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
122222 + if (!a)
122223 + XX_Print("No memory for XX_Malloc\n");
122224 + XX_RestoreAllIntr(flags);
122225 +
122226 + return a;
122227 +}
122228 +
122229 +void xx_Free(void *p)
122230 +{
122231 +#ifdef BIGPHYSAREA_ENABLE
122232 + if (in_big_phys_area ((uint32_t)p))
122233 + bigphysarea_free_pages(p);
122234 + else
122235 +#endif /* BIGPHYSAREA_ENABLE */
122236 + kfree(p);
122237 +}
122238 +
122239 +void XX_Exit(int status)
122240 +{
122241 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
122242 +}
122243 +
122244 +#define BUF_SIZE 512
122245 +void XX_Print(char *str, ...)
122246 +{
122247 + va_list args;
122248 +#ifdef CONFIG_SMP
122249 + char buf[BUF_SIZE];
122250 +#endif /* CONFIG_SMP */
122251 +
122252 + va_start(args, str);
122253 +#ifdef CONFIG_SMP
122254 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122255 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122256 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
122257 +#else
122258 + vprintk(str, args);
122259 +#endif /* CONFIG_SMP */
122260 + va_end(args);
122261 +}
122262 +
122263 +void XX_Fprint(void *file, char *str, ...)
122264 +{
122265 + va_list args;
122266 +#ifdef CONFIG_SMP
122267 + char buf[BUF_SIZE];
122268 +#endif /* CONFIG_SMP */
122269 +
122270 + va_start(args, str);
122271 +#ifdef CONFIG_SMP
122272 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122273 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122274 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
122275 +
122276 +#else
122277 + vprintk(str, args);
122278 +#endif /* CONFIG_SMP */
122279 + va_end(args);
122280 +}
122281 +
122282 +#ifdef DEBUG_XX_MALLOC
122283 +typedef void (*t_ffn)(void *);
122284 +typedef struct {
122285 + t_ffn f_free;
122286 + void *mem;
122287 + char *fname;
122288 + int fline;
122289 + uint32_t size;
122290 + t_List node;
122291 +} t_MemDebug;
122292 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
122293 +
122294 +LIST(memDbgLst);
122295 +
122296 +
122297 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
122298 +{
122299 + void *mem;
122300 + t_MemDebug *p_MemDbg;
122301 +
122302 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
122303 + if (p_MemDbg == NULL)
122304 + return NULL;
122305 +
122306 + mem = xx_Malloc(size);
122307 + if (mem == NULL)
122308 + {
122309 + XX_Free(p_MemDbg);
122310 + return NULL;
122311 + }
122312 +
122313 + INIT_LIST(&p_MemDbg->node);
122314 + p_MemDbg->f_free = xx_Free;
122315 + p_MemDbg->mem = mem;
122316 + p_MemDbg->fname = fname;
122317 + p_MemDbg->fline = line;
122318 + p_MemDbg->size = size+sizeof(t_MemDebug);
122319 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122320 +
122321 + return mem;
122322 +}
122323 +
122324 +void * XX_MallocSmartDebug(uint32_t size,
122325 + int memPartitionId,
122326 + uint32_t align,
122327 + char *fname,
122328 + int line)
122329 +{
122330 + void *mem;
122331 + t_MemDebug *p_MemDbg;
122332 +
122333 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
122334 + if (p_MemDbg == NULL)
122335 + return NULL;
122336 +
122337 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
122338 + if (mem == NULL)
122339 + {
122340 + XX_Free(p_MemDbg);
122341 + return NULL;
122342 + }
122343 +
122344 + INIT_LIST(&p_MemDbg->node);
122345 + p_MemDbg->f_free = xx_FreeSmart;
122346 + p_MemDbg->mem = mem;
122347 + p_MemDbg->fname = fname;
122348 + p_MemDbg->fline = line;
122349 + p_MemDbg->size = size+sizeof(t_MemDebug);
122350 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122351 +
122352 + return mem;
122353 +}
122354 +
122355 +static void debug_free(void *mem)
122356 +{
122357 + t_List *p_MemDbgLh = NULL;
122358 + t_MemDebug *p_MemDbg;
122359 + bool found = FALSE;
122360 +
122361 + if (LIST_IsEmpty(&memDbgLst))
122362 + {
122363 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
122364 + return;
122365 + }
122366 +
122367 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
122368 + {
122369 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
122370 + if (p_MemDbg->mem == mem)
122371 + {
122372 + found = TRUE;
122373 + break;
122374 + }
122375 + }
122376 +
122377 + if (!found)
122378 + {
122379 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
122380 + ("Attempt to free unallocated address (0x%08x)",mem));
122381 + dump_stack();
122382 + return;
122383 + }
122384 +
122385 + LIST_Del(p_MemDbgLh);
122386 + p_MemDbg->f_free(mem);
122387 + p_MemDbg->f_free(p_MemDbg);
122388 +}
122389 +
122390 +void XX_FreeSmart(void *p)
122391 +{
122392 + debug_free(p);
122393 +}
122394 +
122395 +
122396 +void XX_Free(void *p)
122397 +{
122398 + debug_free(p);
122399 +}
122400 +
122401 +#else /* not DEBUG_XX_MALLOC */
122402 +void * XX_Malloc(uint32_t size)
122403 +{
122404 + return xx_Malloc(size);
122405 +}
122406 +
122407 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
122408 +{
122409 + return xx_MallocSmart(size,memPartitionId, alignment);
122410 +}
122411 +
122412 +void XX_FreeSmart(void *p)
122413 +{
122414 + xx_FreeSmart(p);
122415 +}
122416 +
122417 +
122418 +void XX_Free(void *p)
122419 +{
122420 + xx_Free(p);
122421 +}
122422 +#endif /* not DEBUG_XX_MALLOC */
122423 +
122424 +
122425 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
122426 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
122427 +{
122428 + e_Event eventCode = (e_Event)event;
122429 +
122430 + UNUSED(eventCode);
122431 + UNUSED(appId);
122432 + UNUSED(flags);
122433 + UNUSED(msg);
122434 +}
122435 +#endif /* (defined(REPORT_EVENTS) && ... */
122436 +
122437 +
122438 +uint32_t XX_DisableAllIntr(void)
122439 +{
122440 + unsigned long flags;
122441 +
122442 +#ifdef local_irq_save_nort
122443 + local_irq_save_nort(flags);
122444 +#else
122445 + local_irq_save(flags);
122446 +#endif
122447 +
122448 + return (uint32_t)flags;
122449 +}
122450 +
122451 +void XX_RestoreAllIntr(uint32_t flags)
122452 +{
122453 +#ifdef local_irq_restore_nort
122454 + local_irq_restore_nort((unsigned long)flags);
122455 +#else
122456 + local_irq_restore((unsigned long)flags);
122457 +#endif
122458 +}
122459 +
122460 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
122461 +{
122462 + UNUSED(qid);
122463 + UNUSED(appId);
122464 + UNUSED(flags);
122465 +
122466 + return f(id);
122467 +}
122468 +
122469 +int XX_IsICacheEnable(void)
122470 +{
122471 + return TRUE;
122472 +}
122473 +
122474 +int XX_IsDCacheEnable(void)
122475 +{
122476 + return TRUE;
122477 +}
122478 +
122479 +
122480 +typedef struct {
122481 + t_Isr *f_Isr;
122482 + t_Handle handle;
122483 +} t_InterruptHandler;
122484 +
122485 +
122486 +t_Handle interruptHandlers[0x00010000];
122487 +
122488 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
122489 +{
122490 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
122491 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
122492 + return IRQ_HANDLED;
122493 +}
122494 +
122495 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
122496 +{
122497 + const char *device;
122498 + t_InterruptHandler *p_IntrHndl;
122499 +
122500 + device = GetDeviceName(irq);
122501 + if (device == NULL)
122502 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
122503 +
122504 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
122505 + if (p_IntrHndl == NULL)
122506 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
122507 + p_IntrHndl->f_Isr = f_Isr;
122508 + p_IntrHndl->handle = handle;
122509 + interruptHandlers[irq] = p_IntrHndl;
122510 +
122511 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
122512 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
122513 + disable_irq(GetDeviceIrqNum(irq));
122514 +
122515 + return E_OK;
122516 +}
122517 +
122518 +t_Error XX_FreeIntr(int irq)
122519 +{
122520 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
122521 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
122522 + XX_Free(p_IntrHndl);
122523 + interruptHandlers[irq] = 0;
122524 + return E_OK;
122525 +}
122526 +
122527 +t_Error XX_EnableIntr(int irq)
122528 +{
122529 + enable_irq(GetDeviceIrqNum(irq));
122530 + return E_OK;
122531 +}
122532 +
122533 +t_Error XX_DisableIntr(int irq)
122534 +{
122535 + disable_irq(GetDeviceIrqNum(irq));
122536 + return E_OK;
122537 +}
122538 +
122539 +
122540 +/*****************************************************************************/
122541 +/* Tasklet Service Routines */
122542 +/*****************************************************************************/
122543 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
122544 +typedef struct
122545 +{
122546 + t_Handle h_Data;
122547 + void (*f_Callback) (void *);
122548 + struct delayed_work dwork;
122549 +} t_Tasklet;
122550 +
122551 +static void GenericTaskletCallback(struct work_struct *p_Work)
122552 +{
122553 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
122554 +
122555 + p_Task->f_Callback(p_Task->h_Data);
122556 +}
122557 +#endif /* LINUX_VERSION_CODE */
122558 +
122559 +
122560 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
122561 +{
122562 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122563 + struct work_struct *p_Task;
122564 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
122565 + INIT_WORK(p_Task, routine, data);
122566 +#else
122567 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
122568 + p_Task->h_Data = data;
122569 + p_Task->f_Callback = routine;
122570 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
122571 +#endif /* LINUX_VERSION_CODE */
122572 +
122573 + return (t_TaskletHandle)p_Task;
122574 +}
122575 +
122576 +
122577 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
122578 +{
122579 + if (h_Tasklet)
122580 + XX_Free(h_Tasklet);
122581 +}
122582 +
122583 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
122584 +{
122585 + int ans;
122586 +
122587 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122588 + if (immediate)
122589 + ans = schedule_work(h_Tasklet);
122590 + else
122591 + ans = schedule_delayed_work(h_Tasklet, 1);
122592 +#else
122593 + if (immediate)
122594 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
122595 + else
122596 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
122597 +#endif /* LINUX_VERSION_CODE */
122598 +
122599 + return ans;
122600 +}
122601 +
122602 +void XX_FlushScheduledTasks(void)
122603 +{
122604 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
122605 + flush_scheduled_tasks();
122606 +#else
122607 + flush_scheduled_work();
122608 +#endif /* LINUX_VERSION_CODE */
122609 +}
122610 +
122611 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
122612 +{
122613 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122614 + return (int)(((struct work_struct *)h_Tasklet)->pending);
122615 +#else
122616 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
122617 +#endif /* LINUX_VERSION_CODE */
122618 +}
122619 +
122620 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
122621 +{
122622 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
122623 + ((struct tq_struct *)h_Tasklet)->data = data;
122624 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122625 + ((struct work_struct *)h_Tasklet)->data = data;
122626 +#else
122627 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
122628 +#endif /* LINUX_VERSION_CODE */
122629 +}
122630 +
122631 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
122632 +{
122633 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
122634 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
122635 +#else
122636 + return ((t_Tasklet *)h_Tasklet)->h_Data;
122637 +#endif /* LINUX_VERSION_CODE */
122638 +}
122639 +
122640 +
122641 +/*****************************************************************************/
122642 +/* Spinlock Service Routines */
122643 +/*****************************************************************************/
122644 +
122645 +t_Handle XX_InitSpinlock(void)
122646 +{
122647 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
122648 + if (!p_Spinlock)
122649 + return NULL;
122650 +
122651 + spin_lock_init(p_Spinlock);
122652 +
122653 + return (t_Handle)p_Spinlock;
122654 +}
122655 +
122656 +void XX_FreeSpinlock(t_Handle h_Spinlock)
122657 +{
122658 + if (h_Spinlock)
122659 + XX_Free(h_Spinlock);
122660 +}
122661 +
122662 +void XX_LockSpinlock(t_Handle h_Spinlock)
122663 +{
122664 + spin_lock((spinlock_t *)h_Spinlock);
122665 +}
122666 +
122667 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
122668 +{
122669 + spin_unlock((spinlock_t *)h_Spinlock);
122670 +}
122671 +
122672 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
122673 +{
122674 + unsigned long intrFlags;
122675 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
122676 + return intrFlags;
122677 +}
122678 +
122679 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
122680 +{
122681 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
122682 +}
122683 +
122684 +
122685 +/*****************************************************************************/
122686 +/* Timers Service Routines */
122687 +/*****************************************************************************/
122688 +/* The time now is in mili sec. resolution */
122689 +uint32_t XX_CurrentTime(void)
122690 +{
122691 + return (jiffies*1000)/HZ;
122692 +}
122693 +
122694 +
122695 +t_Handle XX_CreateTimer(void)
122696 +{
122697 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
122698 + if (p_Timer)
122699 + {
122700 + memset(p_Timer, 0, sizeof(struct timer_list));
122701 + init_timer(p_Timer);
122702 + }
122703 + return (t_Handle)p_Timer;
122704 +}
122705 +
122706 +void XX_FreeTimer(t_Handle h_Timer)
122707 +{
122708 + if (h_Timer)
122709 + XX_Free(h_Timer);
122710 +}
122711 +
122712 +void XX_StartTimer(t_Handle h_Timer,
122713 + uint32_t msecs,
122714 + bool periodic,
122715 + void (*f_TimerExpired)(t_Handle),
122716 + t_Handle h_Arg)
122717 +{
122718 + int tmp_jiffies = (msecs*HZ)/1000;
122719 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122720 +
122721 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
122722 +
122723 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
122724 + p_Timer->data = (unsigned long)h_Arg;
122725 + if ((msecs*HZ)%1000)
122726 + tmp_jiffies++;
122727 + p_Timer->expires = (jiffies + tmp_jiffies);
122728 +
122729 + add_timer((struct timer_list *)h_Timer);
122730 +}
122731 +
122732 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
122733 +{
122734 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122735 +
122736 + p_Timer->data = (unsigned long)data;
122737 +}
122738 +
122739 +t_Handle XX_GetTimerData(t_Handle h_Timer)
122740 +{
122741 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122742 +
122743 + return (t_Handle)p_Timer->data;
122744 +}
122745 +
122746 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
122747 +{
122748 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
122749 +
122750 + return (uint32_t)p_Timer->expires;
122751 +}
122752 +
122753 +void XX_StopTimer(t_Handle h_Timer)
122754 +{
122755 + del_timer((struct timer_list *)h_Timer);
122756 +}
122757 +
122758 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
122759 +{
122760 + int tmp_jiffies = (msecs*HZ)/1000;
122761 +
122762 + if ((msecs*HZ)%1000)
122763 + tmp_jiffies++;
122764 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
122765 +}
122766 +
122767 +int XX_TimerIsActive(t_Handle h_Timer)
122768 +{
122769 + return timer_pending((struct timer_list *)h_Timer);
122770 +}
122771 +
122772 +uint32_t XX_Sleep(uint32_t msecs)
122773 +{
122774 + int tmp_jiffies = (msecs*HZ)/1000;
122775 +
122776 + if ((msecs*HZ)%1000)
122777 + tmp_jiffies++;
122778 + return schedule_timeout(tmp_jiffies);
122779 +}
122780 +
122781 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
122782 +void XX_UDelay(uint32_t usecs)
122783 +{
122784 + udelay(usecs);
122785 +}
122786 +
122787 +/* TODO: verify that these are correct */
122788 +#define MSG_BODY_SIZE 512
122789 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
122790 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
122791 +t_Error XX_SendMessage(char *p_DestAddr,
122792 + uint32_t msgId,
122793 + uint8_t msgBody[MSG_BODY_SIZE],
122794 + t_MsgCompletionCB *f_CompletionCB,
122795 + t_Handle h_CBArg);
122796 +
122797 +typedef struct {
122798 + char *p_Addr;
122799 + t_MsgHandler *f_MsgHandlerCB;
122800 + t_Handle h_Mod;
122801 + t_List node;
122802 +} t_MsgHndlr;
122803 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
122804 +
122805 +LIST(msgHndlrList);
122806 +
122807 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
122808 +{
122809 + uint32_t intFlags;
122810 +
122811 + intFlags = XX_DisableAllIntr();
122812 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
122813 + XX_RestoreAllIntr(intFlags);
122814 +}
122815 +/* TODO: add this for multi-platform support
122816 +static t_MsgHndlr * DequeueMsgHndlr(void)
122817 +{
122818 + t_MsgHndlr *p_MsgHndlr = NULL;
122819 + uint32_t intFlags;
122820 +
122821 + intFlags = XX_DisableAllIntr();
122822 + if (!LIST_IsEmpty(&msgHndlrList))
122823 + {
122824 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
122825 + LIST_DelAndInit(&p_MsgHndlr->node);
122826 + }
122827 + XX_RestoreAllIntr(intFlags);
122828 +
122829 + return p_MsgHndlr;
122830 +}
122831 +*/
122832 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
122833 +{
122834 + t_MsgHndlr *p_MsgHndlr;
122835 + t_List *p_Pos;
122836 +
122837 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
122838 + {
122839 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
122840 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
122841 + return p_MsgHndlr;
122842 + }
122843 +
122844 + return NULL;
122845 +}
122846 +
122847 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
122848 +{
122849 + t_MsgHndlr *p_MsgHndlr;
122850 + uint32_t len;
122851 +
122852 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
122853 + if (!p_MsgHndlr)
122854 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
122855 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
122856 +
122857 + len = strlen(p_Addr);
122858 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
122859 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
122860 +
122861 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
122862 + p_MsgHndlr->h_Mod = h_Mod;
122863 + INIT_LIST(&p_MsgHndlr->node);
122864 + EnqueueMsgHndlr(p_MsgHndlr);
122865 +
122866 + return E_OK;
122867 +}
122868 +
122869 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
122870 +{
122871 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
122872 + if (!p_MsgHndlr)
122873 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
122874 +
122875 + LIST_Del(&p_MsgHndlr->node);
122876 + XX_Free(p_MsgHndlr->p_Addr);
122877 + XX_Free(p_MsgHndlr);
122878 +
122879 + return E_OK;
122880 +}
122881 +
122882 +t_Error XX_SendMessage(char *p_DestAddr,
122883 + uint32_t msgId,
122884 + uint8_t msgBody[MSG_BODY_SIZE],
122885 + t_MsgCompletionCB *f_CompletionCB,
122886 + t_Handle h_CBArg)
122887 +{
122888 + t_Error ans;
122889 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
122890 + if (!p_MsgHndlr)
122891 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
122892 +
122893 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
122894 +
122895 + if (f_CompletionCB)
122896 + f_CompletionCB(h_CBArg, msgBody);
122897 +
122898 + return ans;
122899 +}
122900 +
122901 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
122902 + t_IpcMsgHandler *f_MsgHandler,
122903 + t_Handle h_Module,
122904 + uint32_t replyLength)
122905 +{
122906 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
122907 + return E_OK;
122908 +}
122909 +
122910 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
122911 +{
122912 + UNUSED(addr);
122913 + return E_OK;
122914 +}
122915 +
122916 +
122917 +t_Error XX_IpcSendMessage(t_Handle h_Session,
122918 + uint8_t *p_Msg,
122919 + uint32_t msgLength,
122920 + uint8_t *p_Reply,
122921 + uint32_t *p_ReplyLength,
122922 + t_IpcMsgCompletion *f_Completion,
122923 + t_Handle h_Arg)
122924 +{
122925 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
122926 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
122927 + return E_OK;
122928 +}
122929 +
122930 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
122931 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
122932 +{
122933 + UNUSED(destAddr); UNUSED(srcAddr);
122934 + return E_OK;
122935 +}
122936 +
122937 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
122938 +int GetDeviceIrqNum(int irq)
122939 +{
122940 + struct device_node *iPar;
122941 + struct irq_domain *irqHost;
122942 + uint32_t hwIrq;
122943 +
122944 + /* Get the interrupt controller */
122945 + iPar = of_find_node_by_name(NULL, "mpic");
122946 + hwIrq = 0;
122947 +
122948 + ASSERT_COND(iPar != NULL);
122949 + /* Get the irq host */
122950 + irqHost = irq_find_host(iPar);
122951 + of_node_put(iPar);
122952 +
122953 + /* Create irq mapping */
122954 + return irq_create_mapping(irqHost, hwIrq);
122955 +}
122956 +#else
122957 +#error "kernel not supported!!!"
122958 +#endif /* LINUX_VERSION_CODE */
122959 +
122960 +void * XX_PhysToVirt(physAddress_t addr)
122961 +{
122962 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
122963 +}
122964 +
122965 +physAddress_t XX_VirtToPhys(void * addr)
122966 +{
122967 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
122968 +}
122969 +
122970 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
122971 +{
122972 + uintptr_t *returnCode, tmp;
122973 +
122974 + if (alignment < sizeof(uintptr_t))
122975 + alignment = sizeof(uintptr_t);
122976 + size += alignment + sizeof(returnCode);
122977 + tmp = (uintptr_t)xx_Malloc(size);
122978 + if (tmp == 0)
122979 + return NULL;
122980 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
122981 + *(returnCode - 1) = tmp;
122982 +
122983 + return (void*)returnCode;
122984 +}
122985 +
122986 +void xx_FreeSmart(void *p)
122987 +{
122988 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
122989 +}
122990 --- /dev/null
122991 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
122992 @@ -0,0 +1,918 @@
122993 +/*
122994 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122995 + *
122996 + * Redistribution and use in source and binary forms, with or without
122997 + * modification, are permitted provided that the following conditions are met:
122998 + * * Redistributions of source code must retain the above copyright
122999 + * notice, this list of conditions and the following disclaimer.
123000 + * * Redistributions in binary form must reproduce the above copyright
123001 + * notice, this list of conditions and the following disclaimer in the
123002 + * documentation and/or other materials provided with the distribution.
123003 + * * Neither the name of Freescale Semiconductor nor the
123004 + * names of its contributors may be used to endorse or promote products
123005 + * derived from this software without specific prior written permission.
123006 + *
123007 + *
123008 + * ALTERNATIVELY, this software may be distributed under the terms of the
123009 + * GNU General Public License ("GPL") as published by the Free Software
123010 + * Foundation, either version 2 of that License or (at your option) any
123011 + * later version.
123012 + *
123013 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123014 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123015 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123016 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123017 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123018 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123019 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123020 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123021 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123022 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123023 + */
123024 +
123025 +/**************************************************************************//**
123026 + @File xx_linux.c
123027 +
123028 + @Description XX routines implementation for Linux.
123029 +*//***************************************************************************/
123030 +#include <linux/version.h>
123031 +
123032 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123033 +#define MODVERSIONS
123034 +#endif
123035 +#ifdef MODVERSIONS
123036 +#include <config/modversions.h>
123037 +#endif /* MODVERSIONS */
123038 +
123039 +#include <linux/module.h>
123040 +#include <linux/kernel.h>
123041 +#include <linux/sched.h>
123042 +#include <linux/string.h>
123043 +#include <linux/ptrace.h>
123044 +#include <linux/errno.h>
123045 +#include <linux/ioport.h>
123046 +#include <linux/slab.h>
123047 +#include <linux/interrupt.h>
123048 +#include <linux/fs.h>
123049 +#include <linux/vmalloc.h>
123050 +#include <linux/init.h>
123051 +#include <linux/timer.h>
123052 +#include <linux/spinlock.h>
123053 +#include <linux/delay.h>
123054 +#include <linux/proc_fs.h>
123055 +#include <linux/smp.h>
123056 +#include <linux/of.h>
123057 +#ifdef CONFIG_FMAN_ARM
123058 +#include <linux/irqdomain.h>
123059 +#endif
123060 +
123061 +#include <linux/workqueue.h>
123062 +
123063 +#ifdef BIGPHYSAREA_ENABLE
123064 +#include <linux/bigphysarea.h>
123065 +#endif /* BIGPHYSAREA_ENABLE */
123066 +
123067 +#ifndef CONFIG_FMAN_ARM
123068 +#include <sysdev/fsl_soc.h>
123069 +#endif
123070 +#include <asm/pgtable.h>
123071 +#include <asm/irq.h>
123072 +#include <asm/bitops.h>
123073 +#include <asm/uaccess.h>
123074 +#include <asm/io.h>
123075 +#include <asm/atomic.h>
123076 +#include <asm/string.h>
123077 +#include <asm/byteorder.h>
123078 +#include <asm/page.h>
123079 +
123080 +#include "error_ext.h"
123081 +#include "std_ext.h"
123082 +#include "list_ext.h"
123083 +#include "mm_ext.h"
123084 +#include "sys_io_ext.h"
123085 +#include "xx.h"
123086 +
123087 +
123088 +#define __ERR_MODULE__ MODULE_UNKNOWN
123089 +
123090 +#ifdef BIGPHYSAREA_ENABLE
123091 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123092 +
123093 +
123094 +/* TODO: large allocations => use big phys area */
123095 +/******************************************************************************
123096 + * routine: get_nr_pages
123097 + *
123098 + * description:
123099 + * calculates the number of memory pages for a given size (in bytes)
123100 + *
123101 + * arguments:
123102 + * size - the number of bytes
123103 + *
123104 + * return code:
123105 + * The number of pages
123106 + *
123107 + *****************************************************************************/
123108 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123109 +{
123110 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123111 +}
123112 +
123113 +static bool in_big_phys_area (uint32_t addr)
123114 +{
123115 + uint32_t base, size;
123116 +
123117 + bigphysarea_get_details (&base, &size);
123118 + return ((addr >= base) && (addr < base + size));
123119 +}
123120 +#endif /* BIGPHYSAREA_ENABLE */
123121 +
123122 +void * xx_Malloc(uint32_t n)
123123 +{
123124 + void *a;
123125 + uint32_t flags;
123126 +
123127 + flags = XX_DisableAllIntr();
123128 +#ifdef BIGPHYSAREA_ENABLE
123129 + if (n >= MAX_ALLOCATION_SIZE)
123130 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123131 + else
123132 +#endif /* BIGPHYSAREA_ENABLE */
123133 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123134 + if (!a)
123135 + XX_Print("No memory for XX_Malloc\n");
123136 + XX_RestoreAllIntr(flags);
123137 +
123138 + return a;
123139 +}
123140 +
123141 +void xx_Free(void *p)
123142 +{
123143 +#ifdef BIGPHYSAREA_ENABLE
123144 + if (in_big_phys_area ((uint32_t)p))
123145 + bigphysarea_free_pages(p);
123146 + else
123147 +#endif /* BIGPHYSAREA_ENABLE */
123148 + kfree(p);
123149 +}
123150 +
123151 +void XX_Exit(int status)
123152 +{
123153 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123154 +}
123155 +
123156 +#define BUF_SIZE 512
123157 +void XX_Print(char *str, ...)
123158 +{
123159 + va_list args;
123160 +#ifdef CONFIG_SMP
123161 + char buf[BUF_SIZE];
123162 +#endif /* CONFIG_SMP */
123163 +
123164 + va_start(args, str);
123165 +#ifdef CONFIG_SMP
123166 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123167 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123168 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123169 +#else
123170 + vprintk(str, args);
123171 +#endif /* CONFIG_SMP */
123172 + va_end(args);
123173 +}
123174 +
123175 +void XX_Fprint(void *file, char *str, ...)
123176 +{
123177 + va_list args;
123178 +#ifdef CONFIG_SMP
123179 + char buf[BUF_SIZE];
123180 +#endif /* CONFIG_SMP */
123181 +
123182 + va_start(args, str);
123183 +#ifdef CONFIG_SMP
123184 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123185 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123186 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123187 +
123188 +#else
123189 + vprintk(str, args);
123190 +#endif /* CONFIG_SMP */
123191 + va_end(args);
123192 +}
123193 +
123194 +#ifdef DEBUG_XX_MALLOC
123195 +typedef void (*t_ffn)(void *);
123196 +typedef struct {
123197 + t_ffn f_free;
123198 + void *mem;
123199 + char *fname;
123200 + int fline;
123201 + uint32_t size;
123202 + t_List node;
123203 +} t_MemDebug;
123204 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
123205 +
123206 +LIST(memDbgLst);
123207 +
123208 +
123209 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
123210 +{
123211 + void *mem;
123212 + t_MemDebug *p_MemDbg;
123213 +
123214 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
123215 + if (p_MemDbg == NULL)
123216 + return NULL;
123217 +
123218 + mem = xx_Malloc(size);
123219 + if (mem == NULL)
123220 + {
123221 + XX_Free(p_MemDbg);
123222 + return NULL;
123223 + }
123224 +
123225 + INIT_LIST(&p_MemDbg->node);
123226 + p_MemDbg->f_free = xx_Free;
123227 + p_MemDbg->mem = mem;
123228 + p_MemDbg->fname = fname;
123229 + p_MemDbg->fline = line;
123230 + p_MemDbg->size = size+sizeof(t_MemDebug);
123231 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123232 +
123233 + return mem;
123234 +}
123235 +
123236 +void * XX_MallocSmartDebug(uint32_t size,
123237 + int memPartitionId,
123238 + uint32_t align,
123239 + char *fname,
123240 + int line)
123241 +{
123242 + void *mem;
123243 + t_MemDebug *p_MemDbg;
123244 +
123245 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
123246 + if (p_MemDbg == NULL)
123247 + return NULL;
123248 +
123249 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
123250 + if (mem == NULL)
123251 + {
123252 + XX_Free(p_MemDbg);
123253 + return NULL;
123254 + }
123255 +
123256 + INIT_LIST(&p_MemDbg->node);
123257 + p_MemDbg->f_free = xx_FreeSmart;
123258 + p_MemDbg->mem = mem;
123259 + p_MemDbg->fname = fname;
123260 + p_MemDbg->fline = line;
123261 + p_MemDbg->size = size+sizeof(t_MemDebug);
123262 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123263 +
123264 + return mem;
123265 +}
123266 +
123267 +static void debug_free(void *mem)
123268 +{
123269 + t_List *p_MemDbgLh = NULL;
123270 + t_MemDebug *p_MemDbg;
123271 + bool found = FALSE;
123272 +
123273 + if (LIST_IsEmpty(&memDbgLst))
123274 + {
123275 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
123276 + return;
123277 + }
123278 +
123279 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123280 + {
123281 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123282 + if (p_MemDbg->mem == mem)
123283 + {
123284 + found = TRUE;
123285 + break;
123286 + }
123287 + }
123288 +
123289 + if (!found)
123290 + {
123291 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123292 + ("Attempt to free unallocated address (0x%08x)",mem));
123293 + dump_stack();
123294 + return;
123295 + }
123296 +
123297 + LIST_Del(p_MemDbgLh);
123298 + p_MemDbg->f_free(mem);
123299 + p_MemDbg->f_free(p_MemDbg);
123300 +}
123301 +
123302 +void XX_FreeSmart(void *p)
123303 +{
123304 + debug_free(p);
123305 +}
123306 +
123307 +
123308 +void XX_Free(void *p)
123309 +{
123310 + debug_free(p);
123311 +}
123312 +
123313 +#else /* not DEBUG_XX_MALLOC */
123314 +void * XX_Malloc(uint32_t size)
123315 +{
123316 + return xx_Malloc(size);
123317 +}
123318 +
123319 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123320 +{
123321 + return xx_MallocSmart(size,memPartitionId, alignment);
123322 +}
123323 +
123324 +void XX_FreeSmart(void *p)
123325 +{
123326 + xx_FreeSmart(p);
123327 +}
123328 +
123329 +
123330 +void XX_Free(void *p)
123331 +{
123332 + xx_Free(p);
123333 +}
123334 +#endif /* not DEBUG_XX_MALLOC */
123335 +
123336 +
123337 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123338 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123339 +{
123340 + e_Event eventCode = (e_Event)event;
123341 +
123342 + UNUSED(eventCode);
123343 + UNUSED(appId);
123344 + UNUSED(flags);
123345 + UNUSED(msg);
123346 +}
123347 +#endif /* (defined(REPORT_EVENTS) && ... */
123348 +
123349 +
123350 +uint32_t XX_DisableAllIntr(void)
123351 +{
123352 + unsigned long flags;
123353 +
123354 +#ifdef local_irq_save_nort
123355 + local_irq_save_nort(flags);
123356 +#else
123357 + local_irq_save(flags);
123358 +#endif
123359 +
123360 + return (uint32_t)flags;
123361 +}
123362 +
123363 +void XX_RestoreAllIntr(uint32_t flags)
123364 +{
123365 +#ifdef local_irq_restore_nort
123366 + local_irq_restore_nort((unsigned long)flags);
123367 +#else
123368 + local_irq_restore((unsigned long)flags);
123369 +#endif
123370 +}
123371 +
123372 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
123373 +{
123374 + UNUSED(qid);
123375 + UNUSED(appId);
123376 + UNUSED(flags);
123377 +
123378 + return f(id);
123379 +}
123380 +
123381 +int XX_IsICacheEnable(void)
123382 +{
123383 + return TRUE;
123384 +}
123385 +
123386 +int XX_IsDCacheEnable(void)
123387 +{
123388 + return TRUE;
123389 +}
123390 +
123391 +
123392 +typedef struct {
123393 + t_Isr *f_Isr;
123394 + t_Handle handle;
123395 +} t_InterruptHandler;
123396 +
123397 +
123398 +t_Handle interruptHandlers[0x00010000];
123399 +
123400 +#ifdef CONFIG_FMAN_ARM
123401 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
123402 +{
123403 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
123404 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
123405 + return IRQ_HANDLED;
123406 +}
123407 +#endif
123408 +
123409 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
123410 +{
123411 +#ifdef CONFIG_FMAN_ARM
123412 + const char *device;
123413 + t_InterruptHandler *p_IntrHndl;
123414 +
123415 + device = GetDeviceName(irq);
123416 + if (device == NULL)
123417 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
123418 +
123419 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
123420 + if (p_IntrHndl == NULL)
123421 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
123422 + p_IntrHndl->f_Isr = f_Isr;
123423 + p_IntrHndl->handle = handle;
123424 + interruptHandlers[irq] = p_IntrHndl;
123425 +
123426 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
123427 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
123428 + disable_irq(GetDeviceIrqNum(irq));
123429 +#endif
123430 + return E_OK;
123431 +}
123432 +
123433 +t_Error XX_FreeIntr(int irq)
123434 +{
123435 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
123436 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
123437 + XX_Free(p_IntrHndl);
123438 + interruptHandlers[irq] = 0;
123439 + return E_OK;
123440 +}
123441 +
123442 +t_Error XX_EnableIntr(int irq)
123443 +{
123444 + enable_irq(GetDeviceIrqNum(irq));
123445 + return E_OK;
123446 +}
123447 +
123448 +t_Error XX_DisableIntr(int irq)
123449 +{
123450 + disable_irq(GetDeviceIrqNum(irq));
123451 + return E_OK;
123452 +}
123453 +
123454 +
123455 +/*****************************************************************************/
123456 +/* Tasklet Service Routines */
123457 +/*****************************************************************************/
123458 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123459 +typedef struct
123460 +{
123461 + t_Handle h_Data;
123462 + void (*f_Callback) (void *);
123463 + struct delayed_work dwork;
123464 +} t_Tasklet;
123465 +
123466 +static void GenericTaskletCallback(struct work_struct *p_Work)
123467 +{
123468 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123469 +
123470 + p_Task->f_Callback(p_Task->h_Data);
123471 +}
123472 +#endif /* LINUX_VERSION_CODE */
123473 +
123474 +
123475 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123476 +{
123477 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123478 + struct work_struct *p_Task;
123479 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123480 + INIT_WORK(p_Task, routine, data);
123481 +#else
123482 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123483 + p_Task->h_Data = data;
123484 + p_Task->f_Callback = routine;
123485 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123486 +#endif /* LINUX_VERSION_CODE */
123487 +
123488 + return (t_TaskletHandle)p_Task;
123489 +}
123490 +
123491 +
123492 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123493 +{
123494 + if (h_Tasklet)
123495 + XX_Free(h_Tasklet);
123496 +}
123497 +
123498 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123499 +{
123500 + int ans;
123501 +
123502 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123503 + if (immediate)
123504 + ans = schedule_work(h_Tasklet);
123505 + else
123506 + ans = schedule_delayed_work(h_Tasklet, 1);
123507 +#else
123508 + if (immediate)
123509 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123510 + else
123511 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123512 +#endif /* LINUX_VERSION_CODE */
123513 +
123514 + return ans;
123515 +}
123516 +
123517 +void XX_FlushScheduledTasks(void)
123518 +{
123519 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123520 + flush_scheduled_tasks();
123521 +#else
123522 + flush_scheduled_work();
123523 +#endif /* LINUX_VERSION_CODE */
123524 +}
123525 +
123526 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123527 +{
123528 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123529 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123530 +#else
123531 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123532 +#endif /* LINUX_VERSION_CODE */
123533 +}
123534 +
123535 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
123536 +{
123537 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123538 + ((struct tq_struct *)h_Tasklet)->data = data;
123539 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123540 + ((struct work_struct *)h_Tasklet)->data = data;
123541 +#else
123542 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
123543 +#endif /* LINUX_VERSION_CODE */
123544 +}
123545 +
123546 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
123547 +{
123548 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123549 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
123550 +#else
123551 + return ((t_Tasklet *)h_Tasklet)->h_Data;
123552 +#endif /* LINUX_VERSION_CODE */
123553 +}
123554 +
123555 +
123556 +/*****************************************************************************/
123557 +/* Spinlock Service Routines */
123558 +/*****************************************************************************/
123559 +
123560 +t_Handle XX_InitSpinlock(void)
123561 +{
123562 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
123563 + if (!p_Spinlock)
123564 + return NULL;
123565 +
123566 + spin_lock_init(p_Spinlock);
123567 +
123568 + return (t_Handle)p_Spinlock;
123569 +}
123570 +
123571 +void XX_FreeSpinlock(t_Handle h_Spinlock)
123572 +{
123573 + if (h_Spinlock)
123574 + XX_Free(h_Spinlock);
123575 +}
123576 +
123577 +void XX_LockSpinlock(t_Handle h_Spinlock)
123578 +{
123579 + spin_lock((spinlock_t *)h_Spinlock);
123580 +}
123581 +
123582 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
123583 +{
123584 + spin_unlock((spinlock_t *)h_Spinlock);
123585 +}
123586 +
123587 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
123588 +{
123589 + unsigned long intrFlags;
123590 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
123591 + return intrFlags;
123592 +}
123593 +
123594 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
123595 +{
123596 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
123597 +}
123598 +
123599 +
123600 +/*****************************************************************************/
123601 +/* Timers Service Routines */
123602 +/*****************************************************************************/
123603 +/* The time now is in mili sec. resolution */
123604 +uint32_t XX_CurrentTime(void)
123605 +{
123606 + return (jiffies*1000)/HZ;
123607 +}
123608 +
123609 +
123610 +t_Handle XX_CreateTimer(void)
123611 +{
123612 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
123613 + if (p_Timer)
123614 + {
123615 + memset(p_Timer, 0, sizeof(struct timer_list));
123616 + init_timer(p_Timer);
123617 + }
123618 + return (t_Handle)p_Timer;
123619 +}
123620 +
123621 +void XX_FreeTimer(t_Handle h_Timer)
123622 +{
123623 + if (h_Timer)
123624 + XX_Free(h_Timer);
123625 +}
123626 +
123627 +void XX_StartTimer(t_Handle h_Timer,
123628 + uint32_t msecs,
123629 + bool periodic,
123630 + void (*f_TimerExpired)(t_Handle),
123631 + t_Handle h_Arg)
123632 +{
123633 + int tmp_jiffies = (msecs*HZ)/1000;
123634 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123635 +
123636 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
123637 +
123638 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
123639 + p_Timer->data = (unsigned long)h_Arg;
123640 + if ((msecs*HZ)%1000)
123641 + tmp_jiffies++;
123642 + p_Timer->expires = (jiffies + tmp_jiffies);
123643 +
123644 + add_timer((struct timer_list *)h_Timer);
123645 +}
123646 +
123647 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
123648 +{
123649 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123650 +
123651 + p_Timer->data = (unsigned long)data;
123652 +}
123653 +
123654 +t_Handle XX_GetTimerData(t_Handle h_Timer)
123655 +{
123656 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123657 +
123658 + return (t_Handle)p_Timer->data;
123659 +}
123660 +
123661 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
123662 +{
123663 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123664 +
123665 + return (uint32_t)p_Timer->expires;
123666 +}
123667 +
123668 +void XX_StopTimer(t_Handle h_Timer)
123669 +{
123670 + del_timer((struct timer_list *)h_Timer);
123671 +}
123672 +
123673 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123674 +{
123675 + int tmp_jiffies = (msecs*HZ)/1000;
123676 +
123677 + if ((msecs*HZ)%1000)
123678 + tmp_jiffies++;
123679 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123680 +}
123681 +
123682 +int XX_TimerIsActive(t_Handle h_Timer)
123683 +{
123684 + return timer_pending((struct timer_list *)h_Timer);
123685 +}
123686 +
123687 +uint32_t XX_Sleep(uint32_t msecs)
123688 +{
123689 + int tmp_jiffies = (msecs*HZ)/1000;
123690 +
123691 + if ((msecs*HZ)%1000)
123692 + tmp_jiffies++;
123693 + return schedule_timeout(tmp_jiffies);
123694 +}
123695 +
123696 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123697 +void XX_UDelay(uint32_t usecs)
123698 +{
123699 + udelay(usecs);
123700 +}
123701 +
123702 +/* TODO: verify that these are correct */
123703 +#define MSG_BODY_SIZE 512
123704 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123705 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123706 +t_Error XX_SendMessage(char *p_DestAddr,
123707 + uint32_t msgId,
123708 + uint8_t msgBody[MSG_BODY_SIZE],
123709 + t_MsgCompletionCB *f_CompletionCB,
123710 + t_Handle h_CBArg);
123711 +
123712 +typedef struct {
123713 + char *p_Addr;
123714 + t_MsgHandler *f_MsgHandlerCB;
123715 + t_Handle h_Mod;
123716 + t_List node;
123717 +} t_MsgHndlr;
123718 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123719 +
123720 +LIST(msgHndlrList);
123721 +
123722 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123723 +{
123724 + uint32_t intFlags;
123725 +
123726 + intFlags = XX_DisableAllIntr();
123727 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123728 + XX_RestoreAllIntr(intFlags);
123729 +}
123730 +/* TODO: add this for multi-platform support
123731 +static t_MsgHndlr * DequeueMsgHndlr(void)
123732 +{
123733 + t_MsgHndlr *p_MsgHndlr = NULL;
123734 + uint32_t intFlags;
123735 +
123736 + intFlags = XX_DisableAllIntr();
123737 + if (!LIST_IsEmpty(&msgHndlrList))
123738 + {
123739 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123740 + LIST_DelAndInit(&p_MsgHndlr->node);
123741 + }
123742 + XX_RestoreAllIntr(intFlags);
123743 +
123744 + return p_MsgHndlr;
123745 +}
123746 +*/
123747 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123748 +{
123749 + t_MsgHndlr *p_MsgHndlr;
123750 + t_List *p_Pos;
123751 +
123752 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123753 + {
123754 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123755 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123756 + return p_MsgHndlr;
123757 + }
123758 +
123759 + return NULL;
123760 +}
123761 +
123762 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123763 +{
123764 + t_MsgHndlr *p_MsgHndlr;
123765 + uint32_t len;
123766 +
123767 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123768 + if (!p_MsgHndlr)
123769 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123770 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123771 +
123772 + len = strlen(p_Addr);
123773 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123774 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123775 +
123776 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123777 + p_MsgHndlr->h_Mod = h_Mod;
123778 + INIT_LIST(&p_MsgHndlr->node);
123779 + EnqueueMsgHndlr(p_MsgHndlr);
123780 +
123781 + return E_OK;
123782 +}
123783 +
123784 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123785 +{
123786 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123787 + if (!p_MsgHndlr)
123788 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123789 +
123790 + LIST_Del(&p_MsgHndlr->node);
123791 + XX_Free(p_MsgHndlr->p_Addr);
123792 + XX_Free(p_MsgHndlr);
123793 +
123794 + return E_OK;
123795 +}
123796 +
123797 +t_Error XX_SendMessage(char *p_DestAddr,
123798 + uint32_t msgId,
123799 + uint8_t msgBody[MSG_BODY_SIZE],
123800 + t_MsgCompletionCB *f_CompletionCB,
123801 + t_Handle h_CBArg)
123802 +{
123803 + t_Error ans;
123804 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
123805 + if (!p_MsgHndlr)
123806 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123807 +
123808 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
123809 +
123810 + if (f_CompletionCB)
123811 + f_CompletionCB(h_CBArg, msgBody);
123812 +
123813 + return ans;
123814 +}
123815 +
123816 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123817 + t_IpcMsgHandler *f_MsgHandler,
123818 + t_Handle h_Module,
123819 + uint32_t replyLength)
123820 +{
123821 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
123822 + return E_OK;
123823 +}
123824 +
123825 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123826 +{
123827 + UNUSED(addr);
123828 + return E_OK;
123829 +}
123830 +
123831 +
123832 +t_Error XX_IpcSendMessage(t_Handle h_Session,
123833 + uint8_t *p_Msg,
123834 + uint32_t msgLength,
123835 + uint8_t *p_Reply,
123836 + uint32_t *p_ReplyLength,
123837 + t_IpcMsgCompletion *f_Completion,
123838 + t_Handle h_Arg)
123839 +{
123840 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
123841 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
123842 + return E_OK;
123843 +}
123844 +
123845 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123846 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123847 +{
123848 + UNUSED(destAddr); UNUSED(srcAddr);
123849 + return E_OK;
123850 +}
123851 +
123852 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
123853 +uint32_t E500_GetId(void)
123854 +{
123855 + return raw_smp_processor_id();
123856 +}
123857 +
123858 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
123859 +int GetDeviceIrqNum(int irq)
123860 +{
123861 + struct device_node *iPar;
123862 + struct irq_domain *irqHost;
123863 + uint32_t hwIrq;
123864 +
123865 + /* Get the interrupt controller */
123866 + iPar = of_find_node_by_name(NULL, "mpic");
123867 + hwIrq = 0;
123868 +
123869 + ASSERT_COND(iPar != NULL);
123870 + /* Get the irq host */
123871 + irqHost = irq_find_host(iPar);
123872 + of_node_put(iPar);
123873 +
123874 + /* Create irq mapping */
123875 + return irq_create_mapping(irqHost, hwIrq);
123876 +}
123877 +#else
123878 +#error "kernel not supported!!!"
123879 +#endif /* LINUX_VERSION_CODE */
123880 +
123881 +void * XX_PhysToVirt(physAddress_t addr)
123882 +{
123883 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
123884 +}
123885 +
123886 +physAddress_t XX_VirtToPhys(void * addr)
123887 +{
123888 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
123889 +}
123890 +
123891 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123892 +{
123893 + uintptr_t *returnCode, tmp;
123894 +
123895 + if (alignment < sizeof(uintptr_t))
123896 + alignment = sizeof(uintptr_t);
123897 + size += alignment + sizeof(returnCode);
123898 + tmp = (uintptr_t)xx_Malloc(size);
123899 + if (tmp == 0)
123900 + return NULL;
123901 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
123902 + *(returnCode - 1) = tmp;
123903 +
123904 + return (void*)returnCode;
123905 +}
123906 +
123907 +void xx_FreeSmart(void *p)
123908 +{
123909 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
123910 +}
123911 --- /dev/null
123912 +++ b/drivers/staging/fsl_qbman/Kconfig
123913 @@ -0,0 +1,228 @@
123914 +config FSL_SDK_DPA
123915 + bool "Freescale Datapath Queue and Buffer management"
123916 + depends on !FSL_DPAA
123917 + select FSL_QMAN_FQ_LOOKUP if PPC64
123918 + select FSL_QMAN_FQ_LOOKUP if ARM64
123919 +
123920 +
123921 +menu "Freescale Datapath QMan/BMan options"
123922 + depends on FSL_SDK_DPA
123923 +
123924 +config FSL_DPA_CHECKING
123925 + bool "additional driver checking"
123926 + default n
123927 + ---help---
123928 + Compiles in additional checks to sanity-check the drivers and any
123929 + use of it by other code. Not recommended for performance.
123930 +
123931 +config FSL_DPA_CAN_WAIT
123932 + bool
123933 + default y
123934 +
123935 +config FSL_DPA_CAN_WAIT_SYNC
123936 + bool
123937 + default y
123938 +
123939 +config FSL_DPA_PIRQ_FAST
123940 + bool
123941 + default y
123942 +
123943 +config FSL_DPA_PIRQ_SLOW
123944 + bool
123945 + default y
123946 +
123947 +config FSL_DPA_PORTAL_SHARE
123948 + bool
123949 + default y
123950 +
123951 +config FSL_SDK_BMAN
123952 + bool "Freescale Buffer Manager (BMan) support"
123953 + default y
123954 +
123955 +if FSL_SDK_BMAN
123956 +
123957 +config FSL_BMAN_CONFIG
123958 + bool "BMan device management"
123959 + default y
123960 + ---help---
123961 + If this linux image is running natively, you need this option. If this
123962 + linux image is running as a guest OS under the hypervisor, only one
123963 + guest OS ("the control plane") needs this option.
123964 +
123965 +config FSL_BMAN_TEST
123966 + tristate "BMan self-tests"
123967 + default n
123968 + ---help---
123969 + This option compiles self-test code for BMan.
123970 +
123971 +config FSL_BMAN_TEST_HIGH
123972 + bool "BMan high-level self-test"
123973 + depends on FSL_BMAN_TEST
123974 + default y
123975 + ---help---
123976 + This requires the presence of cpu-affine portals, and performs
123977 + high-level API testing with them (whichever portal(s) are affine to
123978 + the cpu(s) the test executes on).
123979 +
123980 +config FSL_BMAN_TEST_THRESH
123981 + bool "BMan threshold test"
123982 + depends on FSL_BMAN_TEST
123983 + default y
123984 + ---help---
123985 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
123986 + before multiple threads (one per cpu) create pool objects to track
123987 + depletion state changes. The pool is then drained to empty by a
123988 + "drainer" thread, and the other threads that they observe exactly
123989 + the depletion state changes that are expected.
123990 +
123991 +config FSL_BMAN_DEBUGFS
123992 + tristate "BMan debugfs interface"
123993 + depends on DEBUG_FS
123994 + default y
123995 + ---help---
123996 + This option compiles debugfs code for BMan.
123997 +
123998 +endif # FSL_SDK_BMAN
123999 +
124000 +config FSL_SDK_QMAN
124001 + bool "Freescale Queue Manager (QMan) support"
124002 + default y
124003 +
124004 +if FSL_SDK_QMAN
124005 +
124006 +config FSL_QMAN_POLL_LIMIT
124007 + int
124008 + default 32
124009 +
124010 +config FSL_QMAN_CONFIG
124011 + bool "QMan device management"
124012 + default y
124013 + ---help---
124014 + If this linux image is running natively, you need this option. If this
124015 + linux image is running as a guest OS under the hypervisor, only one
124016 + guest OS ("the control plane") needs this option.
124017 +
124018 +config FSL_QMAN_TEST
124019 + tristate "QMan self-tests"
124020 + default n
124021 + ---help---
124022 + This option compiles self-test code for QMan.
124023 +
124024 +config FSL_QMAN_TEST_STASH_POTATO
124025 + bool "QMan 'hot potato' data-stashing self-test"
124026 + depends on FSL_QMAN_TEST
124027 + default y
124028 + ---help---
124029 + This performs a "hot potato" style test enqueuing/dequeuing a frame
124030 + across a series of FQs scheduled to different portals (and cpus), with
124031 + DQRR, data and context stashing always on.
124032 +
124033 +config FSL_QMAN_TEST_HIGH
124034 + bool "QMan high-level self-test"
124035 + depends on FSL_QMAN_TEST
124036 + default y
124037 + ---help---
124038 + This requires the presence of cpu-affine portals, and performs
124039 + high-level API testing with them (whichever portal(s) are affine to
124040 + the cpu(s) the test executes on).
124041 +
124042 +config FSL_QMAN_DEBUGFS
124043 + tristate "QMan debugfs interface"
124044 + depends on DEBUG_FS
124045 + default y
124046 + ---help---
124047 + This option compiles debugfs code for QMan.
124048 +
124049 +# H/w settings that can be hard-coded for now.
124050 +config FSL_QMAN_FQD_SZ
124051 + int "size of Frame Queue Descriptor region"
124052 + default 10
124053 + ---help---
124054 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
124055 + ex: 10 => PAGE_SIZE * (2^10)
124056 + Note: Default device-trees now require minimum Kconfig setting of 10.
124057 +
124058 +config FSL_QMAN_PFDR_SZ
124059 + int "size of the PFDR pool"
124060 + default 13
124061 + ---help---
124062 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
124063 + ex: 13 => PAGE_SIZE * (2^13)
124064 +
124065 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
124066 +# ability to snart. Stash priority is 3, other priorities are 2.
124067 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
124068 + int
124069 + depends on FSL_QMAN_CONFIG
124070 + default 4
124071 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
124072 + int
124073 + depends on FSL_QMAN_CONFIG
124074 + default 3
124075 +config FSL_QMAN_CI_SCHED_CFG_RW_W
124076 + int
124077 + depends on FSL_QMAN_CONFIG
124078 + default 2
124079 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
124080 + int
124081 + depends on FSL_QMAN_CONFIG
124082 + default 2
124083 +
124084 +# portal interrupt settings
124085 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
124086 + int
124087 + default 12
124088 +config FSL_QMAN_PIRQ_MR_ITHRESH
124089 + int
124090 + default 4
124091 +config FSL_QMAN_PIRQ_IPERIOD
124092 + int
124093 + default 100
124094 +
124095 +# 64 bit kernel support
124096 +config FSL_QMAN_FQ_LOOKUP
124097 + bool
124098 + default n
124099 +
124100 +config QMAN_CEETM_UPDATE_PERIOD
124101 + int "Token update period for shaping, in nanoseconds"
124102 + default 1000
124103 + ---help---
124104 + Traffic shaping works by performing token calculations (using
124105 + credits) on shaper instances periodically. This update period
124106 + sets the granularity for how often those token rate credit
124107 + updates are performed, and thus determines the accuracy and
124108 + range of traffic rates that can be configured by users. The
124109 + reference manual recommends a 1 microsecond period as providing
124110 + a good balance between granularity and range.
124111 +
124112 + Unless you know what you are doing, leave this value at its default.
124113 +
124114 +config FSL_QMAN_INIT_TIMEOUT
124115 + int "timeout for qman init stage, in seconds"
124116 + default 10
124117 + ---help---
124118 + The timeout setting to quit the initialization loop for non-control
124119 + partition in case the control partition fails to boot-up.
124120 +
124121 +endif # FSL_SDK_QMAN
124122 +
124123 +config FSL_USDPAA
124124 + bool "Freescale USDPAA process driver"
124125 + depends on FSL_SDK_DPA
124126 + default y
124127 + ---help---
124128 + This driver provides user-space access to kernel-managed
124129 + resource interfaces for USDPAA applications, on the assumption
124130 + that each process will open this device once. Specifically, this
124131 + device exposes functionality that would be awkward if exposed
124132 + via the portal devices - ie. this device exposes functionality
124133 + that is inherently process-wide rather than portal-specific.
124134 + This device is necessary for obtaining access to DMA memory and
124135 + for allocation of Qman and Bman resources. In short, if you wish
124136 + to use USDPAA applications, you need this.
124137 +
124138 + If unsure, say Y.
124139 +
124140 +
124141 +endmenu
124142 --- /dev/null
124143 +++ b/drivers/staging/fsl_qbman/Makefile
124144 @@ -0,0 +1,28 @@
124145 +subdir-ccflags-y := -Werror
124146 +
124147 +# Common
124148 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
124149 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
124150 +
124151 +# Bman
124152 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
124153 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
124154 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
124155 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
124156 +bman_tester-y = bman_test.o
124157 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
124158 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
124159 +bman_debugfs_interface-y = bman_debugfs.o
124160 +
124161 +# Qman
124162 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
124163 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
124164 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
124165 +qman_tester-y = qman_test.o
124166 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
124167 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
124168 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
124169 +qman_debugfs_interface-y = qman_debugfs.o
124170 +
124171 +# USDPAA
124172 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
124173 --- /dev/null
124174 +++ b/drivers/staging/fsl_qbman/bman_config.c
124175 @@ -0,0 +1,720 @@
124176 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
124177 + *
124178 + * Redistribution and use in source and binary forms, with or without
124179 + * modification, are permitted provided that the following conditions are met:
124180 + * * Redistributions of source code must retain the above copyright
124181 + * notice, this list of conditions and the following disclaimer.
124182 + * * Redistributions in binary form must reproduce the above copyright
124183 + * notice, this list of conditions and the following disclaimer in the
124184 + * documentation and/or other materials provided with the distribution.
124185 + * * Neither the name of Freescale Semiconductor nor the
124186 + * names of its contributors may be used to endorse or promote products
124187 + * derived from this software without specific prior written permission.
124188 + *
124189 + *
124190 + * ALTERNATIVELY, this software may be distributed under the terms of the
124191 + * GNU General Public License ("GPL") as published by the Free Software
124192 + * Foundation, either version 2 of that License or (at your option) any
124193 + * later version.
124194 + *
124195 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124196 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124197 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124198 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124199 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124200 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124201 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124202 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124203 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124204 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124205 + */
124206 +
124207 +#include <asm/cacheflush.h>
124208 +#include "bman_private.h"
124209 +#include <linux/of_reserved_mem.h>
124210 +
124211 +/* Last updated for v00.79 of the BG */
124212 +
124213 +struct bman;
124214 +
124215 +/* Register offsets */
124216 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
124217 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
124218 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
124219 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
124220 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
124221 +#define REG_FBPR_FPC 0x0800
124222 +#define REG_STATE_IDLE 0x960
124223 +#define REG_STATE_STOP 0x964
124224 +#define REG_ECSR 0x0a00
124225 +#define REG_ECIR 0x0a04
124226 +#define REG_EADR 0x0a08
124227 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
124228 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
124229 +#define REG_IP_REV_1 0x0bf8
124230 +#define REG_IP_REV_2 0x0bfc
124231 +#define REG_FBPR_BARE 0x0c00
124232 +#define REG_FBPR_BAR 0x0c04
124233 +#define REG_FBPR_AR 0x0c10
124234 +#define REG_SRCIDR 0x0d04
124235 +#define REG_LIODNR 0x0d08
124236 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
124237 +
124238 +/* Used by all error interrupt registers except 'inhibit' */
124239 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
124240 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
124241 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
124242 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
124243 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
124244 +
124245 +/* BMAN_ECIR valid error bit */
124246 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
124247 +
124248 +union bman_ecir {
124249 + u32 ecir_raw;
124250 + struct {
124251 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124252 + u32 __reserved1:4;
124253 + u32 portal_num:4;
124254 + u32 __reserved2:12;
124255 + u32 numb:4;
124256 + u32 __reserved3:2;
124257 + u32 pid:6;
124258 +#else
124259 + u32 pid:6;
124260 + u32 __reserved3:2;
124261 + u32 numb:4;
124262 + u32 __reserved2:12;
124263 + u32 portal_num:4;
124264 + u32 __reserved1:4;
124265 +#endif
124266 + } __packed info;
124267 +};
124268 +
124269 +union bman_eadr {
124270 + u32 eadr_raw;
124271 + struct {
124272 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124273 + u32 __reserved1:5;
124274 + u32 memid:3;
124275 + u32 __reserved2:14;
124276 + u32 eadr:10;
124277 +#else
124278 + u32 eadr:10;
124279 + u32 __reserved2:14;
124280 + u32 memid:3;
124281 + u32 __reserved1:5;
124282 +#endif
124283 + } __packed info;
124284 +};
124285 +
124286 +struct bman_hwerr_txt {
124287 + u32 mask;
124288 + const char *txt;
124289 +};
124290 +
124291 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
124292 +
124293 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
124294 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
124295 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
124296 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
124297 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
124298 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
124299 +};
124300 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
124301 +
124302 +struct bman_error_info_mdata {
124303 + u16 addr_mask;
124304 + u16 bits;
124305 + const char *txt;
124306 +};
124307 +
124308 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
124309 +static const struct bman_error_info_mdata error_mdata[] = {
124310 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
124311 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
124312 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
124313 +};
124314 +#define BMAN_ERR_MDATA_COUNT \
124315 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
124316 +
124317 +/* Add this in Kconfig */
124318 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
124319 +
124320 +/**
124321 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
124322 + * @v: for accessors that write values, this is the 32-bit value
124323 + *
124324 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
124325 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
124326 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
124327 + * "write the enable register" rather than "enable the write register"!
124328 + */
124329 +#define bm_err_isr_status_read(bm) \
124330 + __bm_err_isr_read(bm, bm_isr_status)
124331 +#define bm_err_isr_status_clear(bm, m) \
124332 + __bm_err_isr_write(bm, bm_isr_status, m)
124333 +#define bm_err_isr_enable_read(bm) \
124334 + __bm_err_isr_read(bm, bm_isr_enable)
124335 +#define bm_err_isr_enable_write(bm, v) \
124336 + __bm_err_isr_write(bm, bm_isr_enable, v)
124337 +#define bm_err_isr_disable_read(bm) \
124338 + __bm_err_isr_read(bm, bm_isr_disable)
124339 +#define bm_err_isr_disable_write(bm, v) \
124340 + __bm_err_isr_write(bm, bm_isr_disable, v)
124341 +#define bm_err_isr_inhibit(bm) \
124342 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
124343 +#define bm_err_isr_uninhibit(bm) \
124344 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
124345 +
124346 +/*
124347 + * TODO: unimplemented registers
124348 + *
124349 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
124350 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
124351 + */
124352 +
124353 +/* Encapsulate "struct bman *" as a cast of the register space address. */
124354 +
124355 +static struct bman *bm_create(void *regs)
124356 +{
124357 + return (struct bman *)regs;
124358 +}
124359 +
124360 +static inline u32 __bm_in(struct bman *bm, u32 offset)
124361 +{
124362 + return in_be32((void *)bm + offset);
124363 +}
124364 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
124365 +{
124366 + out_be32((void *)bm + offset, val);
124367 +}
124368 +#define bm_in(reg) __bm_in(bm, REG_##reg)
124369 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
124370 +
124371 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
124372 +{
124373 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
124374 +}
124375 +
124376 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
124377 +{
124378 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
124379 +}
124380 +
124381 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
124382 +{
124383 + u32 v = bm_in(IP_REV_1);
124384 + *id = (v >> 16);
124385 + *major = (v >> 8) & 0xff;
124386 + *minor = v & 0xff;
124387 +}
124388 +
124389 +static u32 __generate_thresh(u32 val, int roundup)
124390 +{
124391 + u32 e = 0; /* co-efficient, exponent */
124392 + int oddbit = 0;
124393 + while (val > 0xff) {
124394 + oddbit = val & 1;
124395 + val >>= 1;
124396 + e++;
124397 + if (roundup && oddbit)
124398 + val++;
124399 + }
124400 + DPA_ASSERT(e < 0x10);
124401 + return val | (e << 8);
124402 +}
124403 +
124404 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
124405 + u32 hwdet, u32 hwdxt)
124406 +{
124407 + DPA_ASSERT(pool < bman_pool_max);
124408 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
124409 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
124410 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
124411 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
124412 +}
124413 +
124414 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
124415 +{
124416 + u32 exp = ilog2(size);
124417 + /* choke if size isn't within range */
124418 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
124419 + is_power_of_2(size));
124420 + /* choke if '[e]ba' has lower-alignment than 'size' */
124421 + DPA_ASSERT(!(ba & (size - 1)));
124422 + bm_out(FBPR_BARE, upper_32_bits(ba));
124423 + bm_out(FBPR_BAR, lower_32_bits(ba));
124424 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
124425 +}
124426 +
124427 +/*****************/
124428 +/* Config driver */
124429 +/*****************/
124430 +
124431 +/* TODO: Kconfig these? */
124432 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
124433 +
124434 +/* We support only one of these. */
124435 +static struct bman *bm;
124436 +static struct device_node *bm_node;
124437 +
124438 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
124439 + * during bman_init_ccsr(). */
124440 +static dma_addr_t fbpr_a;
124441 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
124442 +
124443 +static int bman_fbpr(struct reserved_mem *rmem)
124444 +{
124445 + fbpr_a = rmem->base;
124446 + fbpr_sz = rmem->size;
124447 +
124448 + WARN_ON(!(fbpr_a && fbpr_sz));
124449 +
124450 + return 0;
124451 +}
124452 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
124453 +
124454 +static int __init fsl_bman_init(struct device_node *node)
124455 +{
124456 + struct resource res;
124457 + u32 __iomem *regs;
124458 + const char *s;
124459 + int ret, standby = 0;
124460 + u16 id;
124461 + u8 major, minor;
124462 +
124463 + ret = of_address_to_resource(node, 0, &res);
124464 + if (ret) {
124465 + pr_err("Can't get %s property 'reg'\n",
124466 + node->full_name);
124467 + return ret;
124468 + }
124469 + s = of_get_property(node, "fsl,hv-claimable", &ret);
124470 + if (s && !strcmp(s, "standby"))
124471 + standby = 1;
124472 + /* Global configuration */
124473 + regs = ioremap(res.start, res.end - res.start + 1);
124474 + bm = bm_create(regs);
124475 + BUG_ON(!bm);
124476 + bm_node = node;
124477 + bm_get_version(bm, &id, &major, &minor);
124478 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
124479 + if ((major == 1) && (minor == 0)) {
124480 + bman_ip_rev = BMAN_REV10;
124481 + bman_pool_max = 64;
124482 + } else if ((major == 2) && (minor == 0)) {
124483 + bman_ip_rev = BMAN_REV20;
124484 + bman_pool_max = 8;
124485 + } else if ((major == 2) && (minor == 1)) {
124486 + bman_ip_rev = BMAN_REV21;
124487 + bman_pool_max = 64;
124488 + } else {
124489 + pr_warn("unknown Bman version, default to rev1.0\n");
124490 + }
124491 +
124492 + if (standby) {
124493 + pr_info(" -> in standby mode\n");
124494 + return 0;
124495 + }
124496 + return 0;
124497 +}
124498 +
124499 +int bman_have_ccsr(void)
124500 +{
124501 + return bm ? 1 : 0;
124502 +}
124503 +
124504 +int bm_pool_set(u32 bpid, const u32 *thresholds)
124505 +{
124506 + if (!bm)
124507 + return -ENODEV;
124508 + bm_set_pool(bm, bpid, thresholds[0],
124509 + thresholds[1], thresholds[2],
124510 + thresholds[3]);
124511 + return 0;
124512 +}
124513 +EXPORT_SYMBOL(bm_pool_set);
124514 +
124515 +__init int bman_init_early(void)
124516 +{
124517 + struct device_node *dn;
124518 + int ret;
124519 +
124520 + for_each_compatible_node(dn, NULL, "fsl,bman") {
124521 + if (bm)
124522 + pr_err("%s: only one 'fsl,bman' allowed\n",
124523 + dn->full_name);
124524 + else {
124525 + if (!of_device_is_available(dn))
124526 + continue;
124527 +
124528 + ret = fsl_bman_init(dn);
124529 + BUG_ON(ret);
124530 + }
124531 + }
124532 + return 0;
124533 +}
124534 +postcore_initcall_sync(bman_init_early);
124535 +
124536 +
124537 +static void log_edata_bits(u32 bit_count)
124538 +{
124539 + u32 i, j, mask = 0xffffffff;
124540 +
124541 + pr_warn("Bman ErrInt, EDATA:\n");
124542 + i = bit_count/32;
124543 + if (bit_count%32) {
124544 + i++;
124545 + mask = ~(mask << bit_count%32);
124546 + }
124547 + j = 16-i;
124548 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
124549 + j++;
124550 + for (; j < 16; j++)
124551 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
124552 +}
124553 +
124554 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
124555 +{
124556 + union bman_ecir ecir_val;
124557 + union bman_eadr eadr_val;
124558 +
124559 + ecir_val.ecir_raw = bm_in(ECIR);
124560 + /* Is portal info valid */
124561 + if (ecsr_val & PORTAL_ECSR_ERR) {
124562 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
124563 + ecir_val.info.portal_num, ecir_val.info.numb,
124564 + ecir_val.info.pid);
124565 + }
124566 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
124567 + eadr_val.eadr_raw = bm_in(EADR);
124568 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
124569 + error_mdata[eadr_val.info.memid].txt,
124570 + error_mdata[eadr_val.info.memid].addr_mask
124571 + & eadr_val.info.eadr);
124572 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
124573 + }
124574 +}
124575 +
124576 +/* Bman interrupt handler */
124577 +static irqreturn_t bman_isr(int irq, void *ptr)
124578 +{
124579 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
124580 +
124581 + ier_val = bm_err_isr_enable_read(bm);
124582 + isr_val = bm_err_isr_status_read(bm);
124583 + ecsr_val = bm_in(ECSR);
124584 + isr_mask = isr_val & ier_val;
124585 +
124586 + if (!isr_mask)
124587 + return IRQ_NONE;
124588 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
124589 + if (bman_hwerr_txts[i].mask & isr_mask) {
124590 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
124591 + if (bman_hwerr_txts[i].mask & ecsr_val) {
124592 + log_additional_error_info(isr_mask, ecsr_val);
124593 + /* Re-arm error capture registers */
124594 + bm_out(ECSR, ecsr_val);
124595 + }
124596 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
124597 + pr_devel("Bman un-enabling error 0x%x\n",
124598 + bman_hwerr_txts[i].mask);
124599 + ier_val &= ~bman_hwerr_txts[i].mask;
124600 + bm_err_isr_enable_write(bm, ier_val);
124601 + }
124602 + }
124603 + }
124604 + bm_err_isr_status_clear(bm, isr_val);
124605 + return IRQ_HANDLED;
124606 +}
124607 +
124608 +static int __bind_irq(void)
124609 +{
124610 + int ret, err_irq;
124611 +
124612 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
124613 + if (err_irq == 0) {
124614 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
124615 + "interrupts");
124616 + return -ENODEV;
124617 + }
124618 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
124619 + if (ret) {
124620 + pr_err("request_irq() failed %d for '%s'\n", ret,
124621 + bm_node->full_name);
124622 + return -ENODEV;
124623 + }
124624 + /* Disable Buffer Pool State Change */
124625 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
124626 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
124627 + * to resource allocation during driver init). */
124628 + bm_err_isr_status_clear(bm, 0xffffffff);
124629 + /* Enable Error Interrupts */
124630 + bm_err_isr_enable_write(bm, 0xffffffff);
124631 + return 0;
124632 +}
124633 +
124634 +int bman_init_ccsr(struct device_node *node)
124635 +{
124636 + int ret;
124637 + if (!bman_have_ccsr())
124638 + return 0;
124639 + if (node != bm_node)
124640 + return -EINVAL;
124641 + /* FBPR memory */
124642 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
124643 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
124644 +
124645 + ret = __bind_irq();
124646 + if (ret)
124647 + return ret;
124648 + return 0;
124649 +}
124650 +
124651 +u32 bm_pool_free_buffers(u32 bpid)
124652 +{
124653 + return bm_in(POOL_CONTENT(bpid));
124654 +}
124655 +
124656 +#ifdef CONFIG_SYSFS
124657 +
124658 +#define DRV_NAME "fsl-bman"
124659 +#define SBEC_MAX_ID 1
124660 +#define SBEC_MIN_ID 0
124661 +
124662 +static ssize_t show_fbpr_fpc(struct device *dev,
124663 + struct device_attribute *dev_attr, char *buf)
124664 +{
124665 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
124666 +};
124667 +
124668 +static ssize_t show_pool_count(struct device *dev,
124669 + struct device_attribute *dev_attr, char *buf)
124670 +{
124671 + u32 data;
124672 + int i;
124673 +
124674 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
124675 + return -EINVAL;
124676 + data = bm_in(POOL_CONTENT(i));
124677 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
124678 +};
124679 +
124680 +static ssize_t show_err_isr(struct device *dev,
124681 + struct device_attribute *dev_attr, char *buf)
124682 +{
124683 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
124684 +};
124685 +
124686 +static ssize_t show_sbec(struct device *dev,
124687 + struct device_attribute *dev_attr, char *buf)
124688 +{
124689 + int i;
124690 +
124691 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
124692 + return -EINVAL;
124693 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
124694 + return -EINVAL;
124695 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
124696 +};
124697 +
124698 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
124699 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
124700 +
124701 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
124702 + * Initialize them when needed. */
124703 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
124704 +static struct device_attribute *dev_attr_buffer_pool_count;
124705 +
124706 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
124707 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
124708 +
124709 +static struct attribute *bman_dev_attributes[] = {
124710 + &dev_attr_fbpr_fpc.attr,
124711 + &dev_attr_err_isr.attr,
124712 + NULL
124713 +};
124714 +
124715 +static struct attribute *bman_dev_ecr_attributes[] = {
124716 + &dev_attr_sbec_0.attr,
124717 + &dev_attr_sbec_1.attr,
124718 + NULL
124719 +};
124720 +
124721 +static struct attribute **bman_dev_pool_count_attributes;
124722 +
124723 +
124724 +/* root level */
124725 +static const struct attribute_group bman_dev_attr_grp = {
124726 + .name = NULL,
124727 + .attrs = bman_dev_attributes
124728 +};
124729 +static const struct attribute_group bman_dev_ecr_grp = {
124730 + .name = "error_capture",
124731 + .attrs = bman_dev_ecr_attributes
124732 +};
124733 +static struct attribute_group bman_dev_pool_countent_grp = {
124734 + .name = "pool_count",
124735 +};
124736 +
124737 +static int of_fsl_bman_remove(struct platform_device *ofdev)
124738 +{
124739 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124740 + return 0;
124741 +};
124742 +
124743 +static int of_fsl_bman_probe(struct platform_device *ofdev)
124744 +{
124745 + int ret, i;
124746 +
124747 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124748 + if (ret)
124749 + goto done;
124750 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
124751 + if (ret)
124752 + goto del_group_0;
124753 +
124754 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
124755 + GFP_KERNEL);
124756 + if (!name_attrs_pool_count) {
124757 + pr_err("Can't alloc name_attrs_pool_count\n");
124758 + goto del_group_1;
124759 + }
124760 +
124761 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
124762 + bman_pool_max, GFP_KERNEL);
124763 + if (!dev_attr_buffer_pool_count) {
124764 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
124765 + goto del_group_2;
124766 + }
124767 +
124768 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
124769 + (bman_pool_max + 1), GFP_KERNEL);
124770 + if (!bman_dev_pool_count_attributes) {
124771 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
124772 + goto del_group_3;
124773 + }
124774 +
124775 + for (i = 0; i < bman_pool_max; i++) {
124776 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
124777 + if (!ret)
124778 + goto del_group_4;
124779 + dev_attr_buffer_pool_count[i].attr.name =
124780 + (name_attrs_pool_count + i * 3);
124781 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
124782 + dev_attr_buffer_pool_count[i].show = show_pool_count;
124783 + bman_dev_pool_count_attributes[i] =
124784 + &dev_attr_buffer_pool_count[i].attr;
124785 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
124786 + }
124787 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
124788 +
124789 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
124790 +
124791 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
124792 + if (ret)
124793 + goto del_group_4;
124794 +
124795 + goto done;
124796 +
124797 +del_group_4:
124798 + kfree(bman_dev_pool_count_attributes);
124799 +del_group_3:
124800 + kfree(dev_attr_buffer_pool_count);
124801 +del_group_2:
124802 + kfree(name_attrs_pool_count);
124803 +del_group_1:
124804 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
124805 +del_group_0:
124806 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
124807 +done:
124808 + if (ret)
124809 + dev_err(&ofdev->dev,
124810 + "Cannot create dev attributes ret=%d\n", ret);
124811 + return ret;
124812 +};
124813 +
124814 +static struct of_device_id of_fsl_bman_ids[] = {
124815 + {
124816 + .compatible = "fsl,bman",
124817 + },
124818 + {}
124819 +};
124820 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
124821 +
124822 +#ifdef CONFIG_SUSPEND
124823 +static u32 saved_isdr;
124824 +
124825 +static int bman_pm_suspend_noirq(struct device *dev)
124826 +{
124827 + uint32_t idle_state;
124828 +
124829 + suspend_unused_bportal();
124830 + /* save isdr, disable all, clear isr */
124831 + saved_isdr = bm_err_isr_disable_read(bm);
124832 + bm_err_isr_disable_write(bm, 0xffffffff);
124833 + bm_err_isr_status_clear(bm, 0xffffffff);
124834 +
124835 + if (bman_ip_rev < BMAN_REV21) {
124836 +#ifdef CONFIG_PM_DEBUG
124837 + pr_info("Bman version doesn't have STATE_IDLE\n");
124838 +#endif
124839 + return 0;
124840 + }
124841 + idle_state = bm_in(STATE_IDLE);
124842 + if (!(idle_state & 0x1)) {
124843 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
124844 + bm_err_isr_disable_write(bm, saved_isdr);
124845 + resume_unused_bportal();
124846 + return -EBUSY;
124847 + }
124848 +#ifdef CONFIG_PM_DEBUG
124849 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
124850 +#endif
124851 + return 0;
124852 +}
124853 +
124854 +static int bman_pm_resume_noirq(struct device *dev)
124855 +{
124856 + /* restore isdr */
124857 + bm_err_isr_disable_write(bm, saved_isdr);
124858 + resume_unused_bportal();
124859 + return 0;
124860 +}
124861 +#else
124862 +#define bman_pm_suspend_noirq NULL
124863 +#define bman_pm_resume_noirq NULL
124864 +#endif
124865 +
124866 +static const struct dev_pm_ops bman_pm_ops = {
124867 + .suspend_noirq = bman_pm_suspend_noirq,
124868 + .resume_noirq = bman_pm_resume_noirq,
124869 +};
124870 +
124871 +static struct platform_driver of_fsl_bman_driver = {
124872 + .driver = {
124873 + .owner = THIS_MODULE,
124874 + .name = DRV_NAME,
124875 + .of_match_table = of_fsl_bman_ids,
124876 + .pm = &bman_pm_ops,
124877 + },
124878 + .probe = of_fsl_bman_probe,
124879 + .remove = of_fsl_bman_remove,
124880 +};
124881 +
124882 +static int bman_ctrl_init(void)
124883 +{
124884 + return platform_driver_register(&of_fsl_bman_driver);
124885 +}
124886 +
124887 +static void bman_ctrl_exit(void)
124888 +{
124889 + platform_driver_unregister(&of_fsl_bman_driver);
124890 +}
124891 +
124892 +module_init(bman_ctrl_init);
124893 +module_exit(bman_ctrl_exit);
124894 +
124895 +#endif /* CONFIG_SYSFS */
124896 --- /dev/null
124897 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
124898 @@ -0,0 +1,119 @@
124899 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
124900 + *
124901 + * Redistribution and use in source and binary forms, with or without
124902 + * modification, are permitted provided that the following conditions are met:
124903 + * * Redistributions of source code must retain the above copyright
124904 + * notice, this list of conditions and the following disclaimer.
124905 + * * Redistributions in binary form must reproduce the above copyright
124906 + * notice, this list of conditions and the following disclaimer in the
124907 + * documentation and/or other materials provided with the distribution.
124908 + * * Neither the name of Freescale Semiconductor nor the
124909 + * names of its contributors may be used to endorse or promote products
124910 + * derived from this software without specific prior written permission.
124911 + *
124912 + *
124913 + * ALTERNATIVELY, this software may be distributed under the terms of the
124914 + * GNU General Public License ("GPL") as published by the Free Software
124915 + * Foundation, either version 2 of that License or (at your option) any
124916 + * later version.
124917 + *
124918 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124919 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124920 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124921 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124922 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124923 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124924 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124925 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124926 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124927 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124928 + */
124929 +#include <linux/module.h>
124930 +#include <linux/fsl_bman.h>
124931 +#include <linux/debugfs.h>
124932 +#include <linux/seq_file.h>
124933 +#include <linux/uaccess.h>
124934 +
124935 +static struct dentry *dfs_root; /* debugfs root directory */
124936 +
124937 +/*******************************************************************************
124938 + * Query Buffer Pool State
124939 + ******************************************************************************/
124940 +static int query_bp_state_show(struct seq_file *file, void *offset)
124941 +{
124942 + int ret;
124943 + struct bm_pool_state state;
124944 + int i, j;
124945 + u32 mask;
124946 +
124947 + memset(&state, 0, sizeof(struct bm_pool_state));
124948 + ret = bman_query_pools(&state);
124949 + if (ret) {
124950 + seq_printf(file, "Error %d\n", ret);
124951 + return 0;
124952 + }
124953 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
124954 + for (i = 0; i < 2; i++) {
124955 + mask = 0x80000000;
124956 + for (j = 0; j < 32; j++) {
124957 + seq_printf(file,
124958 + " %-2u %-3s %-3s\n",
124959 + (i*32)+j,
124960 + (state.as.state.__state[i] & mask) ? "no" : "yes",
124961 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
124962 + mask >>= 1;
124963 + }
124964 + }
124965 + return 0;
124966 +}
124967 +
124968 +static int query_bp_state_open(struct inode *inode, struct file *file)
124969 +{
124970 + return single_open(file, query_bp_state_show, NULL);
124971 +}
124972 +
124973 +static const struct file_operations query_bp_state_fops = {
124974 + .owner = THIS_MODULE,
124975 + .open = query_bp_state_open,
124976 + .read = seq_read,
124977 + .release = single_release,
124978 +};
124979 +
124980 +static int __init bman_debugfs_module_init(void)
124981 +{
124982 + int ret = 0;
124983 + struct dentry *d;
124984 +
124985 + dfs_root = debugfs_create_dir("bman", NULL);
124986 +
124987 + if (dfs_root == NULL) {
124988 + ret = -ENOMEM;
124989 + pr_err("Cannot create bman debugfs dir\n");
124990 + goto _return;
124991 + }
124992 + d = debugfs_create_file("query_bp_state",
124993 + S_IRUGO,
124994 + dfs_root,
124995 + NULL,
124996 + &query_bp_state_fops);
124997 + if (d == NULL) {
124998 + ret = -ENOMEM;
124999 + pr_err("Cannot create query_bp_state\n");
125000 + goto _return;
125001 + }
125002 + return 0;
125003 +
125004 +_return:
125005 + debugfs_remove_recursive(dfs_root);
125006 + return ret;
125007 +}
125008 +
125009 +static void __exit bman_debugfs_module_exit(void)
125010 +{
125011 + debugfs_remove_recursive(dfs_root);
125012 +}
125013 +
125014 +
125015 +module_init(bman_debugfs_module_init);
125016 +module_exit(bman_debugfs_module_exit);
125017 +MODULE_LICENSE("Dual BSD/GPL");
125018 --- /dev/null
125019 +++ b/drivers/staging/fsl_qbman/bman_driver.c
125020 @@ -0,0 +1,575 @@
125021 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125022 + *
125023 + * Redistribution and use in source and binary forms, with or without
125024 + * modification, are permitted provided that the following conditions are met:
125025 + * * Redistributions of source code must retain the above copyright
125026 + * notice, this list of conditions and the following disclaimer.
125027 + * * Redistributions in binary form must reproduce the above copyright
125028 + * notice, this list of conditions and the following disclaimer in the
125029 + * documentation and/or other materials provided with the distribution.
125030 + * * Neither the name of Freescale Semiconductor nor the
125031 + * names of its contributors may be used to endorse or promote products
125032 + * derived from this software without specific prior written permission.
125033 + *
125034 + *
125035 + * ALTERNATIVELY, this software may be distributed under the terms of the
125036 + * GNU General Public License ("GPL") as published by the Free Software
125037 + * Foundation, either version 2 of that License or (at your option) any
125038 + * later version.
125039 + *
125040 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125041 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125042 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125043 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125044 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125045 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125046 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125047 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125048 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125049 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125050 + */
125051 +#include "bman_low.h"
125052 +#ifdef CONFIG_HOTPLUG_CPU
125053 +#include <linux/cpu.h>
125054 +#endif
125055 +/*
125056 + * Global variables of the max portal/pool number this bman version supported
125057 + */
125058 +u16 bman_ip_rev;
125059 +EXPORT_SYMBOL(bman_ip_rev);
125060 +u16 bman_pool_max;
125061 +EXPORT_SYMBOL(bman_pool_max);
125062 +static u16 bman_portal_max;
125063 +
125064 +/* After initialising cpus that own shared portal configs, we cache the
125065 + * resulting portals (ie. not just the configs) in this array. Then we
125066 + * initialise slave cpus that don't have their own portals, redirecting them to
125067 + * portals from this cache in a round-robin assignment. */
125068 +static struct bman_portal *shared_portals[NR_CPUS];
125069 +static int num_shared_portals;
125070 +static int shared_portals_idx;
125071 +static LIST_HEAD(unused_pcfgs);
125072 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
125073 +static void *affine_bportals[NR_CPUS];
125074 +
125075 +static int __init fsl_bpool_init(struct device_node *node)
125076 +{
125077 + int ret;
125078 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
125079 + if (!bpid || (ret != 4)) {
125080 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
125081 + return -ENODEV;
125082 + }
125083 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
125084 + if (thresh) {
125085 + if (ret != 16) {
125086 + pr_err("Invalid %s property '%s'\n",
125087 + node->full_name, "fsl,bpool-thresholds");
125088 + return -ENODEV;
125089 + }
125090 + }
125091 + if (thresh) {
125092 +#ifdef CONFIG_FSL_BMAN_CONFIG
125093 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
125094 + if (ret)
125095 + pr_err("No CCSR node for %s property '%s'\n",
125096 + node->full_name, "fsl,bpool-thresholds");
125097 + return ret;
125098 +#else
125099 + pr_err("Ignoring %s property '%s', no CCSR support\n",
125100 + node->full_name, "fsl,bpool-thresholds");
125101 +#endif
125102 + }
125103 + return 0;
125104 +}
125105 +
125106 +static int __init fsl_bpid_range_init(struct device_node *node)
125107 +{
125108 + int ret;
125109 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
125110 + if (!range) {
125111 + pr_err("No 'fsl,bpid-range' property in node %s\n",
125112 + node->full_name);
125113 + return -EINVAL;
125114 + }
125115 + if (ret != 8) {
125116 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
125117 + node->full_name);
125118 + return -EINVAL;
125119 + }
125120 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125121 + pr_info("Bman: BPID allocator includes range %d:%d\n",
125122 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125123 + return 0;
125124 +}
125125 +
125126 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
125127 +{
125128 + struct bm_portal_config *pcfg;
125129 + const u32 *index;
125130 + int irq, ret;
125131 + resource_size_t len;
125132 +
125133 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
125134 + if (!pcfg) {
125135 + pr_err("can't allocate portal config");
125136 + return NULL;
125137 + }
125138 +
125139 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
125140 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
125141 + bman_ip_rev = BMAN_REV10;
125142 + bman_pool_max = 64;
125143 + bman_portal_max = 10;
125144 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
125145 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
125146 + bman_ip_rev = BMAN_REV20;
125147 + bman_pool_max = 8;
125148 + bman_portal_max = 3;
125149 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
125150 + bman_ip_rev = BMAN_REV21;
125151 + bman_pool_max = 64;
125152 + bman_portal_max = 50;
125153 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
125154 + bman_ip_rev = BMAN_REV21;
125155 + bman_pool_max = 64;
125156 + bman_portal_max = 25;
125157 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
125158 + bman_ip_rev = BMAN_REV21;
125159 + bman_pool_max = 64;
125160 + bman_portal_max = 18;
125161 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
125162 + bman_ip_rev = BMAN_REV21;
125163 + bman_pool_max = 64;
125164 + bman_portal_max = 10;
125165 + } else {
125166 + pr_warn("unknown BMan version in portal node,"
125167 + "default to rev1.0\n");
125168 + bman_ip_rev = BMAN_REV10;
125169 + bman_pool_max = 64;
125170 + bman_portal_max = 10;
125171 + }
125172 +
125173 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
125174 + &pcfg->addr_phys[DPA_PORTAL_CE]);
125175 + if (ret) {
125176 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
125177 + goto err;
125178 + }
125179 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
125180 + &pcfg->addr_phys[DPA_PORTAL_CI]);
125181 + if (ret) {
125182 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
125183 + goto err;
125184 + }
125185 +
125186 + index = of_get_property(node, "cell-index", &ret);
125187 + if (!index || (ret != 4)) {
125188 + pr_err("Can't get %s property '%s'\n", node->full_name,
125189 + "cell-index");
125190 + goto err;
125191 + }
125192 + if (be32_to_cpu(*index) >= bman_portal_max) {
125193 + pr_err("BMan portal cell index %d out of range, max %d\n",
125194 + be32_to_cpu(*index), bman_portal_max);
125195 + goto err;
125196 + }
125197 +
125198 + pcfg->public_cfg.cpu = -1;
125199 +
125200 + irq = irq_of_parse_and_map(node, 0);
125201 + if (irq == 0) {
125202 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
125203 + goto err;
125204 + }
125205 + pcfg->public_cfg.irq = irq;
125206 + pcfg->public_cfg.index = be32_to_cpu(*index);
125207 + bman_depletion_fill(&pcfg->public_cfg.mask);
125208 +
125209 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
125210 + if (len != (unsigned long)len)
125211 + goto err;
125212 +
125213 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
125214 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
125215 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125216 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
125217 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
125218 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125219 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
125220 +
125221 +#else
125222 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
125223 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125224 + (unsigned long)len,
125225 + 0);
125226 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
125227 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125228 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
125229 + _PAGE_GUARDED | _PAGE_NO_CACHE);
125230 +#endif
125231 + /* disable bp depletion */
125232 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
125233 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
125234 + return pcfg;
125235 +err:
125236 + kfree(pcfg);
125237 + return NULL;
125238 +}
125239 +
125240 +static struct bm_portal_config *get_pcfg(struct list_head *list)
125241 +{
125242 + struct bm_portal_config *pcfg;
125243 + if (list_empty(list))
125244 + return NULL;
125245 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
125246 + list_del(&pcfg->list);
125247 + return pcfg;
125248 +}
125249 +
125250 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
125251 + uint32_t idx)
125252 +{
125253 + struct bm_portal_config *pcfg;
125254 + if (list_empty(list))
125255 + return NULL;
125256 + list_for_each_entry(pcfg, list, list) {
125257 + if (pcfg->public_cfg.index == idx) {
125258 + list_del(&pcfg->list);
125259 + return pcfg;
125260 + }
125261 + }
125262 + return NULL;
125263 +}
125264 +
125265 +struct bm_portal_config *bm_get_unused_portal(void)
125266 +{
125267 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
125268 +}
125269 +
125270 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
125271 +{
125272 + struct bm_portal_config *ret;
125273 + spin_lock(&unused_pcfgs_lock);
125274 + if (idx == QBMAN_ANY_PORTAL_IDX)
125275 + ret = get_pcfg(&unused_pcfgs);
125276 + else
125277 + ret = get_pcfg_idx(&unused_pcfgs, idx);
125278 + spin_unlock(&unused_pcfgs_lock);
125279 + return ret;
125280 +}
125281 +
125282 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
125283 +{
125284 + spin_lock(&unused_pcfgs_lock);
125285 + list_add(&pcfg->list, &unused_pcfgs);
125286 + spin_unlock(&unused_pcfgs_lock);
125287 +}
125288 +
125289 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
125290 +{
125291 + struct bman_portal *p;
125292 + p = bman_create_affine_portal(pcfg);
125293 + if (p) {
125294 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
125295 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
125296 +#endif
125297 + pr_info("Bman portal %sinitialised, cpu %d\n",
125298 + pcfg->public_cfg.is_shared ? "(shared) " : "",
125299 + pcfg->public_cfg.cpu);
125300 + affine_bportals[pcfg->public_cfg.cpu] = p;
125301 + } else
125302 + pr_crit("Bman portal failure on cpu %d\n",
125303 + pcfg->public_cfg.cpu);
125304 + return p;
125305 +}
125306 +
125307 +static void init_slave(int cpu)
125308 +{
125309 + struct bman_portal *p;
125310 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
125311 + if (!p)
125312 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
125313 + else
125314 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
125315 + if (shared_portals_idx >= num_shared_portals)
125316 + shared_portals_idx = 0;
125317 + affine_bportals[cpu] = p;
125318 +}
125319 +
125320 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
125321 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
125322 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
125323 + * explicitly mark it or them for sharing.
125324 + * Eg;
125325 + * bportals=s0,1-3,s4
125326 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
125327 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
125328 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
125329 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
125330 + * 0's portal.) */
125331 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
125332 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
125333 +
125334 +static int __init parse_bportals(char *str)
125335 +{
125336 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
125337 + "bportals");
125338 +}
125339 +__setup("bportals=", parse_bportals);
125340 +
125341 +static int bman_offline_cpu(unsigned int cpu)
125342 +{
125343 + struct bman_portal *p;
125344 + const struct bm_portal_config *pcfg;
125345 + p = (struct bman_portal *)affine_bportals[cpu];
125346 + if (p) {
125347 + pcfg = bman_get_bm_portal_config(p);
125348 + if (pcfg)
125349 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
125350 + }
125351 + return 0;
125352 +}
125353 +
125354 +#ifdef CONFIG_HOTPLUG_CPU
125355 +static int bman_online_cpu(unsigned int cpu)
125356 +{
125357 + struct bman_portal *p;
125358 + const struct bm_portal_config *pcfg;
125359 + p = (struct bman_portal *)affine_bportals[cpu];
125360 + if (p) {
125361 + pcfg = bman_get_bm_portal_config(p);
125362 + if (pcfg)
125363 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
125364 + }
125365 + return 0;
125366 +}
125367 +static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
125368 + unsigned long action, void *hcpu)
125369 +{
125370 + unsigned int cpu = (unsigned long)hcpu;
125371 +
125372 + switch (action) {
125373 + case CPU_ONLINE:
125374 + case CPU_ONLINE_FROZEN:
125375 + bman_online_cpu(cpu);
125376 + break;
125377 + case CPU_DOWN_PREPARE:
125378 + case CPU_DOWN_PREPARE_FROZEN:
125379 + bman_offline_cpu(cpu);
125380 + default:
125381 + break;
125382 + }
125383 + return NOTIFY_OK;
125384 +}
125385 +
125386 +static struct notifier_block bman_hotplug_cpu_notifier = {
125387 + .notifier_call = bman_hotplug_cpu_callback,
125388 +};
125389 +#endif /* CONFIG_HOTPLUG_CPU */
125390 +
125391 +/* Initialise the Bman driver. The meat of this function deals with portals. The
125392 + * following describes the flow of portal-handling, the code "steps" refer to
125393 + * this description;
125394 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
125395 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
125396 + * bound).
125397 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
125398 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
125399 + * them to cpus, placing them in the relevant list and setting ::cpu as
125400 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
125401 + * assign portals to all online cpus at the time of driver initialisation.
125402 + * Any failure to allocate portals (when parsing the "want" lists or when
125403 + * using default behaviour) will be silently tolerated (the "fixup" logic in
125404 + * step 3 will determine what happens in this case).
125405 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
125406 + * sharing and sharing is required (because not all cpus have been assigned
125407 + * portals), then one portal will marked for sharing. Conversely if no
125408 + * sharing is required, any portals marked for sharing will not be shared. It
125409 + * may be that sharing occurs when it wasn't expected, if portal allocation
125410 + * failed to honour all the requested assignments (including the default
125411 + * assignments if no bootarg is present).
125412 + * 4. Unshared portals are initialised on their respective cpus.
125413 + * 5. Shared portals are initialised on their respective cpus.
125414 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
125415 + * which are selected in a round-robin fashion.
125416 + * Any portal configs left unused are available for USDPAA allocation.
125417 + */
125418 +__init int bman_init(void)
125419 +{
125420 + struct cpumask slave_cpus;
125421 + struct cpumask unshared_cpus = *cpu_none_mask;
125422 + struct cpumask shared_cpus = *cpu_none_mask;
125423 + LIST_HEAD(unshared_pcfgs);
125424 + LIST_HEAD(shared_pcfgs);
125425 + struct device_node *dn;
125426 + struct bm_portal_config *pcfg;
125427 + struct bman_portal *p;
125428 + int cpu, ret;
125429 + struct cpumask offline_cpus;
125430 +
125431 + /* Initialise the Bman (CCSR) device */
125432 + for_each_compatible_node(dn, NULL, "fsl,bman") {
125433 + if (!bman_init_ccsr(dn))
125434 + pr_info("Bman err interrupt handler present\n");
125435 + else
125436 + pr_err("Bman CCSR setup failed\n");
125437 + }
125438 + /* Initialise any declared buffer pools */
125439 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
125440 + ret = fsl_bpool_init(dn);
125441 + if (ret)
125442 + return ret;
125443 + }
125444 + /* Step 1. See comments at the beginning of the file. */
125445 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
125446 + if (!of_device_is_available(dn))
125447 + continue;
125448 + pcfg = parse_pcfg(dn);
125449 + if (pcfg)
125450 + list_add_tail(&pcfg->list, &unused_pcfgs);
125451 + }
125452 + /* Step 2. */
125453 + for_each_possible_cpu(cpu) {
125454 + if (cpumask_test_cpu(cpu, &want_shared)) {
125455 + pcfg = get_pcfg(&unused_pcfgs);
125456 + if (!pcfg)
125457 + break;
125458 + pcfg->public_cfg.cpu = cpu;
125459 + list_add_tail(&pcfg->list, &shared_pcfgs);
125460 + cpumask_set_cpu(cpu, &shared_cpus);
125461 + }
125462 + if (cpumask_test_cpu(cpu, &want_unshared)) {
125463 + if (cpumask_test_cpu(cpu, &shared_cpus))
125464 + continue;
125465 + pcfg = get_pcfg(&unused_pcfgs);
125466 + if (!pcfg)
125467 + break;
125468 + pcfg->public_cfg.cpu = cpu;
125469 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125470 + cpumask_set_cpu(cpu, &unshared_cpus);
125471 + }
125472 + }
125473 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
125474 + /* Default, give an unshared portal to each online cpu */
125475 + for_each_online_cpu(cpu) {
125476 + pcfg = get_pcfg(&unused_pcfgs);
125477 + if (!pcfg)
125478 + break;
125479 + pcfg->public_cfg.cpu = cpu;
125480 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125481 + cpumask_set_cpu(cpu, &unshared_cpus);
125482 + }
125483 + }
125484 + /* Step 3. */
125485 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
125486 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
125487 + if (cpumask_empty(&slave_cpus)) {
125488 + /* No sharing required */
125489 + if (!list_empty(&shared_pcfgs)) {
125490 + /* Migrate "shared" to "unshared" */
125491 + cpumask_or(&unshared_cpus, &unshared_cpus,
125492 + &shared_cpus);
125493 + cpumask_clear(&shared_cpus);
125494 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
125495 + INIT_LIST_HEAD(&shared_pcfgs);
125496 + }
125497 + } else {
125498 + /* Sharing required */
125499 + if (list_empty(&shared_pcfgs)) {
125500 + /* Migrate one "unshared" to "shared" */
125501 + pcfg = get_pcfg(&unshared_pcfgs);
125502 + if (!pcfg) {
125503 + pr_crit("No BMan portals available!\n");
125504 + return 0;
125505 + }
125506 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
125507 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
125508 + list_add_tail(&pcfg->list, &shared_pcfgs);
125509 + }
125510 + }
125511 + /* Step 4. */
125512 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
125513 + pcfg->public_cfg.is_shared = 0;
125514 + p = init_pcfg(pcfg);
125515 + if (!p) {
125516 + pr_crit("Unable to initialize bman portal\n");
125517 + return 0;
125518 + }
125519 + }
125520 + /* Step 5. */
125521 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
125522 + pcfg->public_cfg.is_shared = 1;
125523 + p = init_pcfg(pcfg);
125524 + if (p)
125525 + shared_portals[num_shared_portals++] = p;
125526 + }
125527 + /* Step 6. */
125528 + if (!cpumask_empty(&slave_cpus))
125529 + for_each_cpu(cpu, &slave_cpus)
125530 + init_slave(cpu);
125531 + pr_info("Bman portals initialised\n");
125532 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
125533 + for_each_cpu(cpu, &offline_cpus)
125534 + bman_offline_cpu(cpu);
125535 +#ifdef CONFIG_HOTPLUG_CPU
125536 + register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
125537 +#endif
125538 + return 0;
125539 +}
125540 +
125541 +__init int bman_resource_init(void)
125542 +{
125543 + struct device_node *dn;
125544 + int ret;
125545 +
125546 + /* Initialise BPID allocation ranges */
125547 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
125548 + ret = fsl_bpid_range_init(dn);
125549 + if (ret)
125550 + return ret;
125551 + }
125552 + return 0;
125553 +}
125554 +
125555 +#ifdef CONFIG_SUSPEND
125556 +void suspend_unused_bportal(void)
125557 +{
125558 + struct bm_portal_config *pcfg;
125559 +
125560 + if (list_empty(&unused_pcfgs))
125561 + return;
125562 +
125563 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
125564 +#ifdef CONFIG_PM_DEBUG
125565 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
125566 +#endif
125567 + /* save isdr, disable all via isdr, clear isr */
125568 + pcfg->saved_isdr =
125569 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
125570 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
125571 + 0xe08);
125572 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
125573 + 0xe00);
125574 + }
125575 + return;
125576 +}
125577 +
125578 +void resume_unused_bportal(void)
125579 +{
125580 + struct bm_portal_config *pcfg;
125581 +
125582 + if (list_empty(&unused_pcfgs))
125583 + return;
125584 +
125585 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
125586 +#ifdef CONFIG_PM_DEBUG
125587 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
125588 +#endif
125589 + /* restore isdr */
125590 + __raw_writel(pcfg->saved_isdr,
125591 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
125592 + }
125593 + return;
125594 +}
125595 +#endif
125596 --- /dev/null
125597 +++ b/drivers/staging/fsl_qbman/bman_high.c
125598 @@ -0,0 +1,1145 @@
125599 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125600 + *
125601 + * Redistribution and use in source and binary forms, with or without
125602 + * modification, are permitted provided that the following conditions are met:
125603 + * * Redistributions of source code must retain the above copyright
125604 + * notice, this list of conditions and the following disclaimer.
125605 + * * Redistributions in binary form must reproduce the above copyright
125606 + * notice, this list of conditions and the following disclaimer in the
125607 + * documentation and/or other materials provided with the distribution.
125608 + * * Neither the name of Freescale Semiconductor nor the
125609 + * names of its contributors may be used to endorse or promote products
125610 + * derived from this software without specific prior written permission.
125611 + *
125612 + *
125613 + * ALTERNATIVELY, this software may be distributed under the terms of the
125614 + * GNU General Public License ("GPL") as published by the Free Software
125615 + * Foundation, either version 2 of that License or (at your option) any
125616 + * later version.
125617 + *
125618 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125619 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125620 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125621 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125622 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125623 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125624 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125625 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125626 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125627 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125628 + */
125629 +
125630 +#include "bman_low.h"
125631 +
125632 +/* Compilation constants */
125633 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
125634 +#define IRQNAME "BMan portal %d"
125635 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
125636 +
125637 +struct bman_portal {
125638 + struct bm_portal p;
125639 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
125640 + struct bman_depletion *pools;
125641 + int thresh_set;
125642 + unsigned long irq_sources;
125643 + u32 slowpoll; /* only used when interrupts are off */
125644 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
125645 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
125646 +#endif
125647 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125648 + raw_spinlock_t sharing_lock; /* only used if is_shared */
125649 + int is_shared;
125650 + struct bman_portal *sharing_redirect;
125651 +#endif
125652 + /* When the cpu-affine portal is activated, this is non-NULL */
125653 + const struct bm_portal_config *config;
125654 + /* This is needed for power management */
125655 + struct platform_device *pdev;
125656 + /* 64-entry hash-table of pool objects that are tracking depletion
125657 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
125658 + * we're not fussy about cache-misses and so forth - whereas the above
125659 + * members should all fit in one cacheline.
125660 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
125661 + * you'll never guess the hash-function ... */
125662 + struct bman_pool *cb[64];
125663 + char irqname[MAX_IRQNAME];
125664 + /* Track if the portal was alloced by the driver */
125665 + u8 alloced;
125666 + /* power management data */
125667 + u32 save_isdr;
125668 +};
125669 +
125670 +/* For an explanation of the locking, redirection, or affine-portal logic,
125671 + * please consult the Qman driver for details. This is the same, only simpler
125672 + * (no fiddly Qman-specific bits.) */
125673 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125674 +#define PORTAL_IRQ_LOCK(p, irqflags) \
125675 + do { \
125676 + if ((p)->is_shared) \
125677 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
125678 + else \
125679 + local_irq_save(irqflags); \
125680 + } while (0)
125681 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
125682 + do { \
125683 + if ((p)->is_shared) \
125684 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
125685 + irqflags); \
125686 + else \
125687 + local_irq_restore(irqflags); \
125688 + } while (0)
125689 +#else
125690 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
125691 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
125692 +#endif
125693 +
125694 +static cpumask_t affine_mask;
125695 +static DEFINE_SPINLOCK(affine_mask_lock);
125696 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
125697 +static inline struct bman_portal *get_raw_affine_portal(void)
125698 +{
125699 + return &get_cpu_var(bman_affine_portal);
125700 +}
125701 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125702 +static inline struct bman_portal *get_affine_portal(void)
125703 +{
125704 + struct bman_portal *p = get_raw_affine_portal();
125705 + if (p->sharing_redirect)
125706 + return p->sharing_redirect;
125707 + return p;
125708 +}
125709 +#else
125710 +#define get_affine_portal() get_raw_affine_portal()
125711 +#endif
125712 +static inline void put_affine_portal(void)
125713 +{
125714 + put_cpu_var(bman_affine_portal);
125715 +}
125716 +static inline struct bman_portal *get_poll_portal(void)
125717 +{
125718 + return &get_cpu_var(bman_affine_portal);
125719 +}
125720 +#define put_poll_portal()
125721 +
125722 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
125723 + * more than one such object per Bman buffer pool, eg. if different users of the
125724 + * pool are operating via different portals. */
125725 +struct bman_pool {
125726 + struct bman_pool_params params;
125727 + /* Used for hash-table admin when using depletion notifications. */
125728 + struct bman_portal *portal;
125729 + struct bman_pool *next;
125730 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
125731 + struct bm_buffer *sp;
125732 + unsigned int sp_fill;
125733 +#ifdef CONFIG_FSL_DPA_CHECKING
125734 + atomic_t in_use;
125735 +#endif
125736 +};
125737 +
125738 +/* (De)Registration of depletion notification callbacks */
125739 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
125740 +{
125741 + __maybe_unused unsigned long irqflags;
125742 + pool->portal = portal;
125743 + PORTAL_IRQ_LOCK(portal, irqflags);
125744 + pool->next = portal->cb[pool->params.bpid];
125745 + portal->cb[pool->params.bpid] = pool;
125746 + if (!pool->next)
125747 + /* First object for that bpid on this portal, enable the BSCN
125748 + * mask bit. */
125749 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
125750 + PORTAL_IRQ_UNLOCK(portal, irqflags);
125751 +}
125752 +static void depletion_unlink(struct bman_pool *pool)
125753 +{
125754 + struct bman_pool *it, *last = NULL;
125755 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
125756 + __maybe_unused unsigned long irqflags;
125757 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
125758 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
125759 + while (it != pool) {
125760 + last = it;
125761 + it = it->next;
125762 + }
125763 + if (!last)
125764 + *base = pool->next;
125765 + else
125766 + last->next = pool->next;
125767 + if (!last && !pool->next) {
125768 + /* Last object for that bpid on this portal, disable the BSCN
125769 + * mask bit. */
125770 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
125771 + /* And "forget" that we last saw this pool as depleted */
125772 + bman_depletion_unset(&pool->portal->pools[1],
125773 + pool->params.bpid);
125774 + }
125775 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
125776 +}
125777 +
125778 +/* In the case that the application's core loop calls qman_poll() and
125779 + * bman_poll(), we ought to balance how often we incur the overheads of the
125780 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
125781 + * constant is used when the last slow-poll detected no work to do, and the busy
125782 + * decrementer constant when the last slow-poll had work to do. */
125783 +#define SLOW_POLL_IDLE 1000
125784 +#define SLOW_POLL_BUSY 10
125785 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
125786 +
125787 +/* Portal interrupt handler */
125788 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
125789 +{
125790 + struct bman_portal *p = ptr;
125791 + u32 clear = p->irq_sources;
125792 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
125793 + clear |= __poll_portal_slow(p, is);
125794 + bm_isr_status_clear(&p->p, clear);
125795 + return IRQ_HANDLED;
125796 +}
125797 +
125798 +#ifdef CONFIG_SUSPEND
125799 +static int _bman_portal_suspend_noirq(struct device *dev)
125800 +{
125801 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
125802 +#ifdef CONFIG_PM_DEBUG
125803 + struct platform_device *pdev = to_platform_device(dev);
125804 +#endif
125805 + p->save_isdr = bm_isr_disable_read(&p->p);
125806 + bm_isr_disable_write(&p->p, 0xffffffff);
125807 + bm_isr_status_clear(&p->p, 0xffffffff);
125808 +#ifdef CONFIG_PM_DEBUG
125809 + pr_info("Suspend for %s\n", pdev->name);
125810 +#endif
125811 + return 0;
125812 +}
125813 +
125814 +static int _bman_portal_resume_noirq(struct device *dev)
125815 +{
125816 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
125817 +
125818 + /* restore isdr */
125819 + bm_isr_disable_write(&p->p, p->save_isdr);
125820 + return 0;
125821 +}
125822 +#else
125823 +#define _bman_portal_suspend_noirq NULL
125824 +#define _bman_portal_resume_noirq NULL
125825 +#endif
125826 +
125827 +struct dev_pm_domain bman_portal_device_pm_domain = {
125828 + .ops = {
125829 + USE_PLATFORM_PM_SLEEP_OPS
125830 + .suspend_noirq = _bman_portal_suspend_noirq,
125831 + .resume_noirq = _bman_portal_resume_noirq,
125832 + }
125833 +};
125834 +
125835 +struct bman_portal *bman_create_portal(
125836 + struct bman_portal *portal,
125837 + const struct bm_portal_config *config)
125838 +{
125839 + struct bm_portal *__p;
125840 + const struct bman_depletion *pools = &config->public_cfg.mask;
125841 + int ret;
125842 + u8 bpid = 0;
125843 + char buf[16];
125844 +
125845 + if (!portal) {
125846 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
125847 + if (!portal)
125848 + return portal;
125849 + portal->alloced = 1;
125850 + } else
125851 + portal->alloced = 0;
125852 +
125853 + __p = &portal->p;
125854 +
125855 + /* prep the low-level portal struct with the mapped addresses from the
125856 + * config, everything that follows depends on it and "config" is more
125857 + * for (de)reference... */
125858 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
125859 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
125860 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
125861 + pr_err("Bman RCR initialisation failed\n");
125862 + goto fail_rcr;
125863 + }
125864 + if (bm_mc_init(__p)) {
125865 + pr_err("Bman MC initialisation failed\n");
125866 + goto fail_mc;
125867 + }
125868 + if (bm_isr_init(__p)) {
125869 + pr_err("Bman ISR initialisation failed\n");
125870 + goto fail_isr;
125871 + }
125872 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
125873 + if (!portal->pools)
125874 + goto fail_pools;
125875 + portal->pools[0] = *pools;
125876 + bman_depletion_init(portal->pools + 1);
125877 + while (bpid < bman_pool_max) {
125878 + /* Default to all BPIDs disabled, we enable as required at
125879 + * run-time. */
125880 + bm_isr_bscn_mask(__p, bpid, 0);
125881 + bpid++;
125882 + }
125883 + portal->slowpoll = 0;
125884 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
125885 + portal->rcri_owned = NULL;
125886 +#endif
125887 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125888 + raw_spin_lock_init(&portal->sharing_lock);
125889 + portal->is_shared = config->public_cfg.is_shared;
125890 + portal->sharing_redirect = NULL;
125891 +#endif
125892 + sprintf(buf, "bportal-%u", config->public_cfg.index);
125893 + portal->pdev = platform_device_alloc(buf, -1);
125894 + if (!portal->pdev)
125895 + goto fail_devalloc;
125896 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
125897 + portal->pdev->dev.platform_data = portal;
125898 + ret = platform_device_add(portal->pdev);
125899 + if (ret)
125900 + goto fail_devadd;
125901 + memset(&portal->cb, 0, sizeof(portal->cb));
125902 + /* Write-to-clear any stale interrupt status bits */
125903 + bm_isr_disable_write(__p, 0xffffffff);
125904 + portal->irq_sources = 0;
125905 + bm_isr_enable_write(__p, portal->irq_sources);
125906 + bm_isr_status_clear(__p, 0xffffffff);
125907 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
125908 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
125909 + portal)) {
125910 + pr_err("request_irq() failed\n");
125911 + goto fail_irq;
125912 + }
125913 + if ((config->public_cfg.cpu != -1) &&
125914 + irq_can_set_affinity(config->public_cfg.irq) &&
125915 + irq_set_affinity(config->public_cfg.irq,
125916 + cpumask_of(config->public_cfg.cpu))) {
125917 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
125918 + goto fail_affinity;
125919 + }
125920 +
125921 + /* Need RCR to be empty before continuing */
125922 + ret = bm_rcr_get_fill(__p);
125923 + if (ret) {
125924 + pr_err("Bman RCR unclean\n");
125925 + goto fail_rcr_empty;
125926 + }
125927 + /* Success */
125928 + portal->config = config;
125929 +
125930 + bm_isr_disable_write(__p, 0);
125931 + bm_isr_uninhibit(__p);
125932 + return portal;
125933 +fail_rcr_empty:
125934 +fail_affinity:
125935 + free_irq(config->public_cfg.irq, portal);
125936 +fail_irq:
125937 + platform_device_del(portal->pdev);
125938 +fail_devadd:
125939 + platform_device_put(portal->pdev);
125940 +fail_devalloc:
125941 + kfree(portal->pools);
125942 +fail_pools:
125943 + bm_isr_finish(__p);
125944 +fail_isr:
125945 + bm_mc_finish(__p);
125946 +fail_mc:
125947 + bm_rcr_finish(__p);
125948 +fail_rcr:
125949 + if (portal->alloced)
125950 + kfree(portal);
125951 + return NULL;
125952 +}
125953 +
125954 +struct bman_portal *bman_create_affine_portal(
125955 + const struct bm_portal_config *config)
125956 +{
125957 + struct bman_portal *portal;
125958 +
125959 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
125960 + portal = bman_create_portal(portal, config);
125961 + if (portal) {
125962 + spin_lock(&affine_mask_lock);
125963 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
125964 + spin_unlock(&affine_mask_lock);
125965 + }
125966 + return portal;
125967 +}
125968 +
125969 +
125970 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
125971 + int cpu)
125972 +{
125973 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
125974 + struct bman_portal *p;
125975 + p = &per_cpu(bman_affine_portal, cpu);
125976 + BUG_ON(p->config);
125977 + BUG_ON(p->is_shared);
125978 + BUG_ON(!redirect->config->public_cfg.is_shared);
125979 + p->irq_sources = 0;
125980 + p->sharing_redirect = redirect;
125981 + return p;
125982 +#else
125983 + BUG();
125984 + return NULL;
125985 +#endif
125986 +}
125987 +
125988 +void bman_destroy_portal(struct bman_portal *bm)
125989 +{
125990 + const struct bm_portal_config *pcfg;
125991 + pcfg = bm->config;
125992 + bm_rcr_cce_update(&bm->p);
125993 + bm_rcr_cce_update(&bm->p);
125994 +
125995 + free_irq(pcfg->public_cfg.irq, bm);
125996 +
125997 + kfree(bm->pools);
125998 + bm_isr_finish(&bm->p);
125999 + bm_mc_finish(&bm->p);
126000 + bm_rcr_finish(&bm->p);
126001 + bm->config = NULL;
126002 + if (bm->alloced)
126003 + kfree(bm);
126004 +}
126005 +
126006 +const struct bm_portal_config *bman_destroy_affine_portal(void)
126007 +{
126008 + struct bman_portal *bm = get_raw_affine_portal();
126009 + const struct bm_portal_config *pcfg;
126010 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126011 + if (bm->sharing_redirect) {
126012 + bm->sharing_redirect = NULL;
126013 + put_affine_portal();
126014 + return NULL;
126015 + }
126016 + bm->is_shared = 0;
126017 +#endif
126018 + pcfg = bm->config;
126019 + bman_destroy_portal(bm);
126020 + spin_lock(&affine_mask_lock);
126021 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
126022 + spin_unlock(&affine_mask_lock);
126023 + put_affine_portal();
126024 + return pcfg;
126025 +}
126026 +
126027 +/* When release logic waits on available RCR space, we need a global waitqueue
126028 + * in the case of "affine" use (as the waits wake on different cpus which means
126029 + * different portals - so we can't wait on any per-portal waitqueue). */
126030 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
126031 +
126032 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
126033 +{
126034 + struct bman_depletion tmp;
126035 + u32 ret = is;
126036 +
126037 + /* There is a gotcha to be aware of. If we do the query before clearing
126038 + * the status register, we may miss state changes that occur between the
126039 + * two. If we write to clear the status register before the query, the
126040 + * cache-enabled query command may overtake the status register write
126041 + * unless we use a heavyweight sync (which we don't want). Instead, we
126042 + * write-to-clear the status register then *read it back* before doing
126043 + * the query, hence the odd while loop with the 'is' accumulation. */
126044 + if (is & BM_PIRQ_BSCN) {
126045 + struct bm_mc_result *mcr;
126046 + __maybe_unused unsigned long irqflags;
126047 + unsigned int i, j;
126048 + u32 __is;
126049 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126050 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
126051 + is |= __is;
126052 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126053 + }
126054 + is &= ~BM_PIRQ_BSCN;
126055 + PORTAL_IRQ_LOCK(p, irqflags);
126056 + bm_mc_start(&p->p);
126057 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126058 + while (!(mcr = bm_mc_result(&p->p)))
126059 + cpu_relax();
126060 + tmp = mcr->query.ds.state;
126061 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
126062 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
126063 + PORTAL_IRQ_UNLOCK(p, irqflags);
126064 + for (i = 0; i < 2; i++) {
126065 + int idx = i * 32;
126066 + /* tmp is a mask of currently-depleted pools.
126067 + * pools[0] is mask of those we care about.
126068 + * pools[1] is our previous view (we only want to
126069 + * be told about changes). */
126070 + tmp.__state[i] &= p->pools[0].__state[i];
126071 + if (tmp.__state[i] == p->pools[1].__state[i])
126072 + /* fast-path, nothing to see, move along */
126073 + continue;
126074 + for (j = 0; j <= 31; j++, idx++) {
126075 + struct bman_pool *pool = p->cb[idx];
126076 + int b4 = bman_depletion_get(&p->pools[1], idx);
126077 + int af = bman_depletion_get(&tmp, idx);
126078 + if (b4 == af)
126079 + continue;
126080 + while (pool) {
126081 + pool->params.cb(p, pool,
126082 + pool->params.cb_ctx, af);
126083 + pool = pool->next;
126084 + }
126085 + }
126086 + }
126087 + p->pools[1] = tmp;
126088 + }
126089 +
126090 + if (is & BM_PIRQ_RCRI) {
126091 + __maybe_unused unsigned long irqflags;
126092 + PORTAL_IRQ_LOCK(p, irqflags);
126093 + bm_rcr_cce_update(&p->p);
126094 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126095 + /* If waiting for sync, we only cancel the interrupt threshold
126096 + * when the ring utilisation hits zero. */
126097 + if (p->rcri_owned) {
126098 + if (!bm_rcr_get_fill(&p->p)) {
126099 + p->rcri_owned = NULL;
126100 + bm_rcr_set_ithresh(&p->p, 0);
126101 + }
126102 + } else
126103 +#endif
126104 + bm_rcr_set_ithresh(&p->p, 0);
126105 + PORTAL_IRQ_UNLOCK(p, irqflags);
126106 + wake_up(&affine_queue);
126107 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
126108 + is &= ~BM_PIRQ_RCRI;
126109 + }
126110 +
126111 + /* There should be no status register bits left undefined */
126112 + DPA_ASSERT(!is);
126113 + return ret;
126114 +}
126115 +
126116 +const struct bman_portal_config *bman_get_portal_config(void)
126117 +{
126118 + struct bman_portal *p = get_affine_portal();
126119 + const struct bman_portal_config *ret = &p->config->public_cfg;
126120 + put_affine_portal();
126121 + return ret;
126122 +}
126123 +EXPORT_SYMBOL(bman_get_portal_config);
126124 +
126125 +u32 bman_irqsource_get(void)
126126 +{
126127 + struct bman_portal *p = get_raw_affine_portal();
126128 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
126129 + put_affine_portal();
126130 + return ret;
126131 +}
126132 +EXPORT_SYMBOL(bman_irqsource_get);
126133 +
126134 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
126135 +{
126136 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126137 + if (p->sharing_redirect)
126138 + return -EINVAL;
126139 + else
126140 +#endif
126141 + {
126142 + __maybe_unused unsigned long irqflags;
126143 + PORTAL_IRQ_LOCK(p, irqflags);
126144 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
126145 + bm_isr_enable_write(&p->p, p->irq_sources);
126146 + PORTAL_IRQ_UNLOCK(p, irqflags);
126147 + }
126148 + return 0;
126149 +}
126150 +EXPORT_SYMBOL(bman_p_irqsource_add);
126151 +
126152 +int bman_irqsource_add(__maybe_unused u32 bits)
126153 +{
126154 + struct bman_portal *p = get_raw_affine_portal();
126155 + int ret = 0;
126156 + ret = bman_p_irqsource_add(p, bits);
126157 + put_affine_portal();
126158 + return ret;
126159 +}
126160 +EXPORT_SYMBOL(bman_irqsource_add);
126161 +
126162 +int bman_irqsource_remove(u32 bits)
126163 +{
126164 + struct bman_portal *p = get_raw_affine_portal();
126165 + __maybe_unused unsigned long irqflags;
126166 + u32 ier;
126167 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126168 + if (p->sharing_redirect) {
126169 + put_affine_portal();
126170 + return -EINVAL;
126171 + }
126172 +#endif
126173 + /* Our interrupt handler only processes+clears status register bits that
126174 + * are in p->irq_sources. As we're trimming that mask, if one of them
126175 + * were to assert in the status register just before we remove it from
126176 + * the enable register, there would be an interrupt-storm when we
126177 + * release the IRQ lock. So we wait for the enable register update to
126178 + * take effect in h/w (by reading it back) and then clear all other bits
126179 + * in the status register. Ie. we clear them from ISR once it's certain
126180 + * IER won't allow them to reassert. */
126181 + PORTAL_IRQ_LOCK(p, irqflags);
126182 + bits &= BM_PIRQ_VISIBLE;
126183 + clear_bits(bits, &p->irq_sources);
126184 + bm_isr_enable_write(&p->p, p->irq_sources);
126185 + ier = bm_isr_enable_read(&p->p);
126186 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
126187 + * data-dependency, ie. to protect against re-ordering. */
126188 + bm_isr_status_clear(&p->p, ~ier);
126189 + PORTAL_IRQ_UNLOCK(p, irqflags);
126190 + put_affine_portal();
126191 + return 0;
126192 +}
126193 +EXPORT_SYMBOL(bman_irqsource_remove);
126194 +
126195 +const cpumask_t *bman_affine_cpus(void)
126196 +{
126197 + return &affine_mask;
126198 +}
126199 +EXPORT_SYMBOL(bman_affine_cpus);
126200 +
126201 +u32 bman_poll_slow(void)
126202 +{
126203 + struct bman_portal *p = get_poll_portal();
126204 + u32 ret;
126205 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126206 + if (unlikely(p->sharing_redirect))
126207 + ret = (u32)-1;
126208 + else
126209 +#endif
126210 + {
126211 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126212 + ret = __poll_portal_slow(p, is);
126213 + bm_isr_status_clear(&p->p, ret);
126214 + }
126215 + put_poll_portal();
126216 + return ret;
126217 +}
126218 +EXPORT_SYMBOL(bman_poll_slow);
126219 +
126220 +/* Legacy wrapper */
126221 +void bman_poll(void)
126222 +{
126223 + struct bman_portal *p = get_poll_portal();
126224 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126225 + if (unlikely(p->sharing_redirect))
126226 + goto done;
126227 +#endif
126228 + if (!(p->slowpoll--)) {
126229 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126230 + u32 active = __poll_portal_slow(p, is);
126231 + if (active)
126232 + p->slowpoll = SLOW_POLL_BUSY;
126233 + else
126234 + p->slowpoll = SLOW_POLL_IDLE;
126235 + }
126236 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126237 +done:
126238 +#endif
126239 + put_poll_portal();
126240 +}
126241 +EXPORT_SYMBOL(bman_poll);
126242 +
126243 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
126244 +
126245 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
126246 +{
126247 + struct bman_pool *pool = NULL;
126248 + u32 bpid;
126249 +
126250 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
126251 + int ret = bman_alloc_bpid(&bpid);
126252 + if (ret)
126253 + return NULL;
126254 + } else {
126255 + if (params->bpid >= bman_pool_max)
126256 + return NULL;
126257 + bpid = params->bpid;
126258 + }
126259 +#ifdef CONFIG_FSL_BMAN_CONFIG
126260 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
126261 + int ret = bm_pool_set(bpid, params->thresholds);
126262 + if (ret)
126263 + goto err;
126264 + }
126265 +#else
126266 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126267 + goto err;
126268 +#endif
126269 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
126270 + if (!pool)
126271 + goto err;
126272 + pool->sp = NULL;
126273 + pool->sp_fill = 0;
126274 + pool->params = *params;
126275 +#ifdef CONFIG_FSL_DPA_CHECKING
126276 + atomic_set(&pool->in_use, 1);
126277 +#endif
126278 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126279 + pool->params.bpid = bpid;
126280 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
126281 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
126282 + GFP_KERNEL);
126283 + if (!pool->sp)
126284 + goto err;
126285 + }
126286 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
126287 + struct bman_portal *p = get_affine_portal();
126288 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
126289 + pr_err("Depletion events disabled for bpid %d\n", bpid);
126290 + goto err;
126291 + }
126292 + depletion_link(p, pool);
126293 + put_affine_portal();
126294 + }
126295 + return pool;
126296 +err:
126297 +#ifdef CONFIG_FSL_BMAN_CONFIG
126298 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126299 + bm_pool_set(bpid, zero_thresholds);
126300 +#endif
126301 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126302 + bman_release_bpid(bpid);
126303 + if (pool) {
126304 + kfree(pool->sp);
126305 + kfree(pool);
126306 + }
126307 + return NULL;
126308 +}
126309 +EXPORT_SYMBOL(bman_new_pool);
126310 +
126311 +void bman_free_pool(struct bman_pool *pool)
126312 +{
126313 +#ifdef CONFIG_FSL_BMAN_CONFIG
126314 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
126315 + bm_pool_set(pool->params.bpid, zero_thresholds);
126316 +#endif
126317 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
126318 + depletion_unlink(pool);
126319 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
126320 + if (pool->sp_fill)
126321 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
126322 + pool->sp_fill, pool->params.bpid);
126323 + kfree(pool->sp);
126324 + pool->sp = NULL;
126325 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
126326 + }
126327 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126328 + bman_release_bpid(pool->params.bpid);
126329 + kfree(pool);
126330 +}
126331 +EXPORT_SYMBOL(bman_free_pool);
126332 +
126333 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
126334 +{
126335 + return &pool->params;
126336 +}
126337 +EXPORT_SYMBOL(bman_get_params);
126338 +
126339 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
126340 +{
126341 + if (avail)
126342 + bm_rcr_cce_prefetch(&p->p);
126343 + else
126344 + bm_rcr_cce_update(&p->p);
126345 +}
126346 +
126347 +int bman_rcr_is_empty(void)
126348 +{
126349 + __maybe_unused unsigned long irqflags;
126350 + struct bman_portal *p = get_affine_portal();
126351 + u8 avail;
126352 +
126353 + PORTAL_IRQ_LOCK(p, irqflags);
126354 + update_rcr_ci(p, 0);
126355 + avail = bm_rcr_get_fill(&p->p);
126356 + PORTAL_IRQ_UNLOCK(p, irqflags);
126357 + put_affine_portal();
126358 + return avail == 0;
126359 +}
126360 +EXPORT_SYMBOL(bman_rcr_is_empty);
126361 +
126362 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
126363 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126364 + __maybe_unused struct bman_pool *pool,
126365 +#endif
126366 + __maybe_unused unsigned long *irqflags,
126367 + __maybe_unused u32 flags)
126368 +{
126369 + struct bm_rcr_entry *r;
126370 + u8 avail;
126371 +
126372 + *p = get_affine_portal();
126373 + PORTAL_IRQ_LOCK(*p, (*irqflags));
126374 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126375 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126376 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126377 + if ((*p)->rcri_owned) {
126378 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126379 + put_affine_portal();
126380 + return NULL;
126381 + }
126382 + (*p)->rcri_owned = pool;
126383 + }
126384 +#endif
126385 + avail = bm_rcr_get_avail(&(*p)->p);
126386 + if (avail < 2)
126387 + update_rcr_ci(*p, avail);
126388 + r = bm_rcr_start(&(*p)->p);
126389 + if (unlikely(!r)) {
126390 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126391 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126392 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
126393 + (*p)->rcri_owned = NULL;
126394 +#endif
126395 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126396 + put_affine_portal();
126397 + }
126398 + return r;
126399 +}
126400 +
126401 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126402 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
126403 + struct bman_pool *pool,
126404 + __maybe_unused unsigned long *irqflags,
126405 + u32 flags)
126406 +{
126407 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
126408 + if (!rcr)
126409 + bm_rcr_set_ithresh(&(*p)->p, 1);
126410 + return rcr;
126411 +}
126412 +
126413 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
126414 + struct bman_pool *pool,
126415 + __maybe_unused unsigned long *irqflags,
126416 + u32 flags)
126417 +{
126418 + struct bm_rcr_entry *rcr;
126419 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126420 + pool = NULL;
126421 +#endif
126422 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126423 + /* NB: return NULL if signal occurs before completion. Signal
126424 + * can occur during return. Caller must check for signal */
126425 + wait_event_interruptible(affine_queue,
126426 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126427 + else
126428 + wait_event(affine_queue,
126429 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126430 + return rcr;
126431 +}
126432 +#endif
126433 +
126434 +static inline int __bman_release(struct bman_pool *pool,
126435 + const struct bm_buffer *bufs, u8 num, u32 flags)
126436 +{
126437 + struct bman_portal *p;
126438 + struct bm_rcr_entry *r;
126439 + __maybe_unused unsigned long irqflags;
126440 + u32 i = num - 1;
126441 +
126442 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126443 + if (flags & BMAN_RELEASE_FLAG_WAIT)
126444 + r = wait_rel_start(&p, pool, &irqflags, flags);
126445 + else
126446 + r = try_rel_start(&p, pool, &irqflags, flags);
126447 +#else
126448 + r = try_rel_start(&p, &irqflags, flags);
126449 +#endif
126450 + if (!r)
126451 + return -EBUSY;
126452 + /* We can copy all but the first entry, as this can trigger badness
126453 + * with the valid-bit. Use the overlay to mask the verb byte. */
126454 + r->bufs[0].opaque =
126455 + ((cpu_to_be64((bufs[0].opaque |
126456 + ((u64)pool->params.bpid<<48))
126457 + & 0x00ffffffffffffff)));
126458 + if (i) {
126459 + for (i = 1; i < num; i++)
126460 + r->bufs[i].opaque =
126461 + cpu_to_be64(bufs[i].opaque);
126462 + }
126463 +
126464 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
126465 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
126466 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126467 + /* if we wish to sync we need to set the threshold after h/w sees the
126468 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
126469 + * accesses, this requires a heavy-weight sync. */
126470 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126471 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126472 + hwsync();
126473 + bm_rcr_set_ithresh(&p->p, 1);
126474 + }
126475 +#endif
126476 + PORTAL_IRQ_UNLOCK(p, irqflags);
126477 + put_affine_portal();
126478 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126479 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126480 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126481 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126482 + /* NB: return success even if signal occurs before
126483 + * condition is true. pvb_commit guarantees success */
126484 + wait_event_interruptible(affine_queue,
126485 + (p->rcri_owned != pool));
126486 + else
126487 + wait_event(affine_queue, (p->rcri_owned != pool));
126488 + }
126489 +#endif
126490 + return 0;
126491 +}
126492 +
126493 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
126494 + u32 flags)
126495 +{
126496 + int ret;
126497 +#ifdef CONFIG_FSL_DPA_CHECKING
126498 + if (!num || (num > 8))
126499 + return -EINVAL;
126500 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
126501 + return -EINVAL;
126502 +#endif
126503 + /* Without stockpile, this API is a pass-through to the h/w operation */
126504 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126505 + return __bman_release(pool, bufs, num, flags);
126506 +#ifdef CONFIG_FSL_DPA_CHECKING
126507 + if (!atomic_dec_and_test(&pool->in_use)) {
126508 + pr_crit("Parallel attempts to enter bman_released() detected.");
126509 + panic("only one instance of bman_released/acquired allowed");
126510 + }
126511 +#endif
126512 + /* Two movements of buffers are possible, and can occur in either order.
126513 + * A: moving buffers from the caller to the stockpile.
126514 + * B: moving buffers from the stockpile to hardware.
126515 + * Order 1: if there is already enough space in the stockpile for A
126516 + * then we want to do A first, and only do B if we trigger the
126517 + * stockpile-high threshold.
126518 + * Order 2: if there is not enough space in the stockpile for A, then
126519 + * we want to do B first, then do A if B had succeeded. However in this
126520 + * case B is dependent on how many buffers the user needs to release,
126521 + * not the stockpile-high threshold.
126522 + * Due to the different handling of B between the two cases, putting A
126523 + * and B in a while() loop would require quite obscure logic, so handle
126524 + * the different sequences explicitly. */
126525 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
126526 + /* Order 1: do A */
126527 + copy_words(pool->sp + pool->sp_fill, bufs,
126528 + sizeof(struct bm_buffer) * num);
126529 + pool->sp_fill += num;
126530 + /* do B relative to STOCKPILE_HIGH */
126531 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
126532 + ret = __bman_release(pool,
126533 + pool->sp + (pool->sp_fill - 8), 8,
126534 + flags);
126535 + if (ret >= 0)
126536 + pool->sp_fill -= 8;
126537 + }
126538 + } else {
126539 + /* Order 2: do B relative to 'num' */
126540 + do {
126541 + ret = __bman_release(pool,
126542 + pool->sp + (pool->sp_fill - 8), 8,
126543 + flags);
126544 + if (ret < 0)
126545 + /* failure */
126546 + goto release_done;
126547 + pool->sp_fill -= 8;
126548 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
126549 + /* do A */
126550 + copy_words(pool->sp + pool->sp_fill, bufs,
126551 + sizeof(struct bm_buffer) * num);
126552 + pool->sp_fill += num;
126553 + }
126554 + /* success */
126555 + ret = 0;
126556 +release_done:
126557 +#ifdef CONFIG_FSL_DPA_CHECKING
126558 + atomic_inc(&pool->in_use);
126559 +#endif
126560 + return ret;
126561 +}
126562 +EXPORT_SYMBOL(bman_release);
126563 +
126564 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
126565 + u8 num)
126566 +{
126567 + struct bman_portal *p = get_affine_portal();
126568 + struct bm_mc_command *mcc;
126569 + struct bm_mc_result *mcr;
126570 + __maybe_unused unsigned long irqflags;
126571 + int ret, i;
126572 +
126573 + PORTAL_IRQ_LOCK(p, irqflags);
126574 + mcc = bm_mc_start(&p->p);
126575 + mcc->acquire.bpid = pool->params.bpid;
126576 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
126577 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
126578 + while (!(mcr = bm_mc_result(&p->p)))
126579 + cpu_relax();
126580 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
126581 + if (bufs) {
126582 + for (i = 0; i < num; i++)
126583 + bufs[i].opaque =
126584 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
126585 + }
126586 + PORTAL_IRQ_UNLOCK(p, irqflags);
126587 + put_affine_portal();
126588 + if (ret != num)
126589 + ret = -ENOMEM;
126590 + return ret;
126591 +}
126592 +
126593 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
126594 + u32 flags)
126595 +{
126596 + int ret;
126597 +#ifdef CONFIG_FSL_DPA_CHECKING
126598 + if (!num || (num > 8))
126599 + return -EINVAL;
126600 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
126601 + return -EINVAL;
126602 +#endif
126603 + /* Without stockpile, this API is a pass-through to the h/w operation */
126604 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126605 + return __bman_acquire(pool, bufs, num);
126606 +#ifdef CONFIG_FSL_DPA_CHECKING
126607 + if (!atomic_dec_and_test(&pool->in_use)) {
126608 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
126609 + panic("only one instance of bman_released/acquired allowed");
126610 + }
126611 +#endif
126612 + /* Two movements of buffers are possible, and can occur in either order.
126613 + * A: moving buffers from stockpile to the caller.
126614 + * B: moving buffers from hardware to the stockpile.
126615 + * Order 1: if there are already enough buffers in the stockpile for A
126616 + * then we want to do A first, and only do B if we trigger the
126617 + * stockpile-low threshold.
126618 + * Order 2: if there are not enough buffers in the stockpile for A,
126619 + * then we want to do B first, then do A if B had succeeded. However in
126620 + * this case B is dependent on how many buffers the user needs, not the
126621 + * stockpile-low threshold.
126622 + * Due to the different handling of B between the two cases, putting A
126623 + * and B in a while() loop would require quite obscure logic, so handle
126624 + * the different sequences explicitly. */
126625 + if (num <= pool->sp_fill) {
126626 + /* Order 1: do A */
126627 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
126628 + sizeof(struct bm_buffer) * num);
126629 + pool->sp_fill -= num;
126630 + /* do B relative to STOCKPILE_LOW */
126631 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
126632 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
126633 + if (ret < 0)
126634 + ret = __bman_acquire(pool,
126635 + pool->sp + pool->sp_fill, 1);
126636 + if (ret < 0)
126637 + break;
126638 + pool->sp_fill += ret;
126639 + }
126640 + } else {
126641 + /* Order 2: do B relative to 'num' */
126642 + do {
126643 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
126644 + if (ret < 0)
126645 + ret = __bman_acquire(pool,
126646 + pool->sp + pool->sp_fill, 1);
126647 + if (ret < 0)
126648 + /* failure */
126649 + goto acquire_done;
126650 + pool->sp_fill += ret;
126651 + } while (pool->sp_fill < num);
126652 + /* do A */
126653 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
126654 + sizeof(struct bm_buffer) * num);
126655 + pool->sp_fill -= num;
126656 + }
126657 + /* success */
126658 + ret = num;
126659 +acquire_done:
126660 +#ifdef CONFIG_FSL_DPA_CHECKING
126661 + atomic_inc(&pool->in_use);
126662 +#endif
126663 + return ret;
126664 +}
126665 +EXPORT_SYMBOL(bman_acquire);
126666 +
126667 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
126668 +{
126669 + u8 num;
126670 + int ret;
126671 +
126672 + while (pool->sp_fill) {
126673 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
126674 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
126675 + num, flags);
126676 + if (ret)
126677 + return ret;
126678 + pool->sp_fill -= num;
126679 + }
126680 + return 0;
126681 +}
126682 +EXPORT_SYMBOL(bman_flush_stockpile);
126683 +
126684 +int bman_query_pools(struct bm_pool_state *state)
126685 +{
126686 + struct bman_portal *p = get_affine_portal();
126687 + struct bm_mc_result *mcr;
126688 + __maybe_unused unsigned long irqflags;
126689 +
126690 + PORTAL_IRQ_LOCK(p, irqflags);
126691 + bm_mc_start(&p->p);
126692 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126693 + while (!(mcr = bm_mc_result(&p->p)))
126694 + cpu_relax();
126695 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
126696 + *state = mcr->query;
126697 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
126698 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
126699 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
126700 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
126701 + PORTAL_IRQ_UNLOCK(p, irqflags);
126702 + put_affine_portal();
126703 + return 0;
126704 +}
126705 +EXPORT_SYMBOL(bman_query_pools);
126706 +
126707 +#ifdef CONFIG_FSL_BMAN_CONFIG
126708 +u32 bman_query_free_buffers(struct bman_pool *pool)
126709 +{
126710 + return bm_pool_free_buffers(pool->params.bpid);
126711 +}
126712 +EXPORT_SYMBOL(bman_query_free_buffers);
126713 +
126714 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
126715 +{
126716 + u32 bpid;
126717 +
126718 + bpid = bman_get_params(pool)->bpid;
126719 +
126720 + return bm_pool_set(bpid, thresholds);
126721 +}
126722 +EXPORT_SYMBOL(bman_update_pool_thresholds);
126723 +#endif
126724 +
126725 +int bman_shutdown_pool(u32 bpid)
126726 +{
126727 + struct bman_portal *p = get_affine_portal();
126728 + __maybe_unused unsigned long irqflags;
126729 + int ret;
126730 +
126731 + PORTAL_IRQ_LOCK(p, irqflags);
126732 + ret = bm_shutdown_pool(&p->p, bpid);
126733 + PORTAL_IRQ_UNLOCK(p, irqflags);
126734 + put_affine_portal();
126735 + return ret;
126736 +}
126737 +EXPORT_SYMBOL(bman_shutdown_pool);
126738 +
126739 +const struct bm_portal_config *bman_get_bm_portal_config(
126740 + struct bman_portal *portal)
126741 +{
126742 + return portal->sharing_redirect ? NULL : portal->config;
126743 +}
126744 --- /dev/null
126745 +++ b/drivers/staging/fsl_qbman/bman_low.h
126746 @@ -0,0 +1,565 @@
126747 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
126748 + *
126749 + * Redistribution and use in source and binary forms, with or without
126750 + * modification, are permitted provided that the following conditions are met:
126751 + * * Redistributions of source code must retain the above copyright
126752 + * notice, this list of conditions and the following disclaimer.
126753 + * * Redistributions in binary form must reproduce the above copyright
126754 + * notice, this list of conditions and the following disclaimer in the
126755 + * documentation and/or other materials provided with the distribution.
126756 + * * Neither the name of Freescale Semiconductor nor the
126757 + * names of its contributors may be used to endorse or promote products
126758 + * derived from this software without specific prior written permission.
126759 + *
126760 + *
126761 + * ALTERNATIVELY, this software may be distributed under the terms of the
126762 + * GNU General Public License ("GPL") as published by the Free Software
126763 + * Foundation, either version 2 of that License or (at your option) any
126764 + * later version.
126765 + *
126766 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126767 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126768 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126769 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126770 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126771 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126772 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126773 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126774 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126775 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126776 + */
126777 +
126778 +#include "bman_private.h"
126779 +
126780 +/***************************/
126781 +/* Portal register assists */
126782 +/***************************/
126783 +
126784 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
126785 +
126786 +/* Cache-inhibited register offsets */
126787 +#define BM_REG_RCR_PI_CINH 0x0000
126788 +#define BM_REG_RCR_CI_CINH 0x0004
126789 +#define BM_REG_RCR_ITR 0x0008
126790 +#define BM_REG_CFG 0x0100
126791 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
126792 +#define BM_REG_ISR 0x0e00
126793 +#define BM_REG_IIR 0x0e0c
126794 +
126795 +/* Cache-enabled register offsets */
126796 +#define BM_CL_CR 0x0000
126797 +#define BM_CL_RR0 0x0100
126798 +#define BM_CL_RR1 0x0140
126799 +#define BM_CL_RCR 0x1000
126800 +#define BM_CL_RCR_PI_CENA 0x3000
126801 +#define BM_CL_RCR_CI_CENA 0x3100
126802 +
126803 +#endif
126804 +
126805 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
126806 +
126807 +/* Cache-inhibited register offsets */
126808 +#define BM_REG_RCR_PI_CINH 0x3000
126809 +#define BM_REG_RCR_CI_CINH 0x3100
126810 +#define BM_REG_RCR_ITR 0x3200
126811 +#define BM_REG_CFG 0x3300
126812 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
126813 +#define BM_REG_ISR 0x3e00
126814 +#define BM_REG_IIR 0x3ec0
126815 +
126816 +/* Cache-enabled register offsets */
126817 +#define BM_CL_CR 0x0000
126818 +#define BM_CL_RR0 0x0100
126819 +#define BM_CL_RR1 0x0140
126820 +#define BM_CL_RCR 0x1000
126821 +#define BM_CL_RCR_PI_CENA 0x3000
126822 +#define BM_CL_RCR_CI_CENA 0x3100
126823 +
126824 +#endif
126825 +
126826 +/* BTW, the drivers (and h/w programming model) already obtain the required
126827 + * synchronisation for portal accesses via lwsync(), hwsync(), and
126828 + * data-dependencies. Use of barrier()s or other order-preserving primitives
126829 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
126830 + * simply ensure that the compiler treats the portal registers as volatile (ie.
126831 + * non-coherent). */
126832 +
126833 +/* Cache-inhibited register access. */
126834 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
126835 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
126836 + (bm)->addr_ci + (o));
126837 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
126838 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
126839 +
126840 +/* Cache-enabled (index) register access */
126841 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
126842 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
126843 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
126844 +#define __bm_cl_out(bm, o, val) \
126845 + do { \
126846 + u32 *__tmpclout = (bm)->addr_ce + (o); \
126847 + __raw_writel(cpu_to_be32(val), __tmpclout); \
126848 + dcbf(__tmpclout); \
126849 + } while (0)
126850 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
126851 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
126852 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
126853 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
126854 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
126855 +#define bm_cl_invalidate(reg)\
126856 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
126857 +
126858 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
126859 + * analysis, look at using the "extra" bit in the ring index registers to avoid
126860 + * cyclic issues. */
126861 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
126862 +{
126863 + /* 'first' is included, 'last' is excluded */
126864 + if (first <= last)
126865 + return last - first;
126866 + return ringsize + last - first;
126867 +}
126868 +
126869 +/* Portal modes.
126870 + * Enum types;
126871 + * pmode == production mode
126872 + * cmode == consumption mode,
126873 + * Enum values use 3 letter codes. First letter matches the portal mode,
126874 + * remaining two letters indicate;
126875 + * ci == cache-inhibited portal register
126876 + * ce == cache-enabled portal register
126877 + * vb == in-band valid-bit (cache-enabled)
126878 + */
126879 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
126880 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
126881 + bm_rcr_pce = 1, /* PI index, cache-enabled */
126882 + bm_rcr_pvb = 2 /* valid-bit */
126883 +};
126884 +enum bm_rcr_cmode { /* s/w-only */
126885 + bm_rcr_cci, /* CI index, cache-inhibited */
126886 + bm_rcr_cce /* CI index, cache-enabled */
126887 +};
126888 +
126889 +
126890 +/* ------------------------- */
126891 +/* --- Portal structures --- */
126892 +
126893 +#define BM_RCR_SIZE 8
126894 +
126895 +struct bm_rcr {
126896 + struct bm_rcr_entry *ring, *cursor;
126897 + u8 ci, available, ithresh, vbit;
126898 +#ifdef CONFIG_FSL_DPA_CHECKING
126899 + u32 busy;
126900 + enum bm_rcr_pmode pmode;
126901 + enum bm_rcr_cmode cmode;
126902 +#endif
126903 +};
126904 +
126905 +struct bm_mc {
126906 + struct bm_mc_command *cr;
126907 + struct bm_mc_result *rr;
126908 + u8 rridx, vbit;
126909 +#ifdef CONFIG_FSL_DPA_CHECKING
126910 + enum {
126911 + /* Can only be _mc_start()ed */
126912 + mc_idle,
126913 + /* Can only be _mc_commit()ed or _mc_abort()ed */
126914 + mc_user,
126915 + /* Can only be _mc_retry()ed */
126916 + mc_hw
126917 + } state;
126918 +#endif
126919 +};
126920 +
126921 +struct bm_addr {
126922 + void __iomem *addr_ce; /* cache-enabled */
126923 + void __iomem *addr_ci; /* cache-inhibited */
126924 +};
126925 +
126926 +struct bm_portal {
126927 + struct bm_addr addr;
126928 + struct bm_rcr rcr;
126929 + struct bm_mc mc;
126930 + struct bm_portal_config config;
126931 +} ____cacheline_aligned;
126932 +
126933 +
126934 +/* --------------- */
126935 +/* --- RCR API --- */
126936 +
126937 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
126938 +#define RCR_CARRYCLEAR(p) \
126939 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
126940 +
126941 +/* Bit-wise logic to convert a ring pointer to a ring index */
126942 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
126943 +{
126944 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
126945 +}
126946 +
126947 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
126948 +static inline void RCR_INC(struct bm_rcr *rcr)
126949 +{
126950 + /* NB: this is odd-looking, but experiments show that it generates
126951 + * fast code with essentially no branching overheads. We increment to
126952 + * the next RCR pointer and handle overflow and 'vbit'. */
126953 + struct bm_rcr_entry *partial = rcr->cursor + 1;
126954 + rcr->cursor = RCR_CARRYCLEAR(partial);
126955 + if (partial != rcr->cursor)
126956 + rcr->vbit ^= BM_RCR_VERB_VBIT;
126957 +}
126958 +
126959 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
126960 + __maybe_unused enum bm_rcr_cmode cmode)
126961 +{
126962 + /* This use of 'register', as well as all other occurrences, is because
126963 + * it has been observed to generate much faster code with gcc than is
126964 + * otherwise the case. */
126965 + register struct bm_rcr *rcr = &portal->rcr;
126966 + u32 cfg;
126967 + u8 pi;
126968 +
126969 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
126970 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
126971 +
126972 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
126973 + rcr->cursor = rcr->ring + pi;
126974 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
126975 + rcr->available = BM_RCR_SIZE - 1
126976 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
126977 + rcr->ithresh = bm_in(RCR_ITR);
126978 +#ifdef CONFIG_FSL_DPA_CHECKING
126979 + rcr->busy = 0;
126980 + rcr->pmode = pmode;
126981 + rcr->cmode = cmode;
126982 +#endif
126983 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
126984 + bm_out(CFG, cfg);
126985 + return 0;
126986 +}
126987 +
126988 +static inline void bm_rcr_finish(struct bm_portal *portal)
126989 +{
126990 + register struct bm_rcr *rcr = &portal->rcr;
126991 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
126992 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
126993 + DPA_ASSERT(!rcr->busy);
126994 + if (pi != RCR_PTR2IDX(rcr->cursor))
126995 + pr_crit("losing uncommited RCR entries\n");
126996 + if (ci != rcr->ci)
126997 + pr_crit("missing existing RCR completions\n");
126998 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
126999 + pr_crit("RCR destroyed unquiesced\n");
127000 +}
127001 +
127002 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
127003 +{
127004 + register struct bm_rcr *rcr = &portal->rcr;
127005 + DPA_ASSERT(!rcr->busy);
127006 + if (!rcr->available)
127007 + return NULL;
127008 +#ifdef CONFIG_FSL_DPA_CHECKING
127009 + rcr->busy = 1;
127010 +#endif
127011 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127012 + dcbz_64(rcr->cursor);
127013 +#endif
127014 + return rcr->cursor;
127015 +}
127016 +
127017 +static inline void bm_rcr_abort(struct bm_portal *portal)
127018 +{
127019 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127020 + DPA_ASSERT(rcr->busy);
127021 +#ifdef CONFIG_FSL_DPA_CHECKING
127022 + rcr->busy = 0;
127023 +#endif
127024 +}
127025 +
127026 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
127027 + struct bm_portal *portal, u8 myverb)
127028 +{
127029 + register struct bm_rcr *rcr = &portal->rcr;
127030 + DPA_ASSERT(rcr->busy);
127031 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
127032 + if (rcr->available == 1)
127033 + return NULL;
127034 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127035 + dcbf_64(rcr->cursor);
127036 + RCR_INC(rcr);
127037 + rcr->available--;
127038 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127039 + dcbz_64(rcr->cursor);
127040 +#endif
127041 + return rcr->cursor;
127042 +}
127043 +
127044 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
127045 +{
127046 + register struct bm_rcr *rcr = &portal->rcr;
127047 + DPA_ASSERT(rcr->busy);
127048 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
127049 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127050 + RCR_INC(rcr);
127051 + rcr->available--;
127052 + hwsync();
127053 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
127054 +#ifdef CONFIG_FSL_DPA_CHECKING
127055 + rcr->busy = 0;
127056 +#endif
127057 +}
127058 +
127059 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
127060 +{
127061 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127062 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127063 + bm_cl_invalidate(RCR_PI);
127064 + bm_cl_touch_rw(RCR_PI);
127065 +}
127066 +
127067 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
127068 +{
127069 + register struct bm_rcr *rcr = &portal->rcr;
127070 + DPA_ASSERT(rcr->busy);
127071 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127072 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127073 + RCR_INC(rcr);
127074 + rcr->available--;
127075 + lwsync();
127076 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
127077 +#ifdef CONFIG_FSL_DPA_CHECKING
127078 + rcr->busy = 0;
127079 +#endif
127080 +}
127081 +
127082 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
127083 +{
127084 + register struct bm_rcr *rcr = &portal->rcr;
127085 + struct bm_rcr_entry *rcursor;
127086 + DPA_ASSERT(rcr->busy);
127087 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
127088 + lwsync();
127089 + rcursor = rcr->cursor;
127090 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
127091 + dcbf_64(rcursor);
127092 + RCR_INC(rcr);
127093 + rcr->available--;
127094 +#ifdef CONFIG_FSL_DPA_CHECKING
127095 + rcr->busy = 0;
127096 +#endif
127097 +}
127098 +
127099 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
127100 +{
127101 + register struct bm_rcr *rcr = &portal->rcr;
127102 + u8 diff, old_ci = rcr->ci;
127103 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
127104 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127105 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127106 + rcr->available += diff;
127107 + return diff;
127108 +}
127109 +
127110 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
127111 +{
127112 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127113 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127114 + bm_cl_touch_ro(RCR_CI);
127115 +}
127116 +
127117 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
127118 +{
127119 + register struct bm_rcr *rcr = &portal->rcr;
127120 + u8 diff, old_ci = rcr->ci;
127121 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127122 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
127123 + bm_cl_invalidate(RCR_CI);
127124 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127125 + rcr->available += diff;
127126 + return diff;
127127 +}
127128 +
127129 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
127130 +{
127131 + register struct bm_rcr *rcr = &portal->rcr;
127132 + return rcr->ithresh;
127133 +}
127134 +
127135 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
127136 +{
127137 + register struct bm_rcr *rcr = &portal->rcr;
127138 + rcr->ithresh = ithresh;
127139 + bm_out(RCR_ITR, ithresh);
127140 +}
127141 +
127142 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
127143 +{
127144 + register struct bm_rcr *rcr = &portal->rcr;
127145 + return rcr->available;
127146 +}
127147 +
127148 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
127149 +{
127150 + register struct bm_rcr *rcr = &portal->rcr;
127151 + return BM_RCR_SIZE - 1 - rcr->available;
127152 +}
127153 +
127154 +
127155 +/* ------------------------------ */
127156 +/* --- Management command API --- */
127157 +
127158 +static inline int bm_mc_init(struct bm_portal *portal)
127159 +{
127160 + register struct bm_mc *mc = &portal->mc;
127161 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
127162 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
127163 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
127164 + BM_MCC_VERB_VBIT) ? 0 : 1;
127165 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
127166 +#ifdef CONFIG_FSL_DPA_CHECKING
127167 + mc->state = mc_idle;
127168 +#endif
127169 + return 0;
127170 +}
127171 +
127172 +static inline void bm_mc_finish(struct bm_portal *portal)
127173 +{
127174 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127175 + DPA_ASSERT(mc->state == mc_idle);
127176 +#ifdef CONFIG_FSL_DPA_CHECKING
127177 + if (mc->state != mc_idle)
127178 + pr_crit("Losing incomplete MC command\n");
127179 +#endif
127180 +}
127181 +
127182 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
127183 +{
127184 + register struct bm_mc *mc = &portal->mc;
127185 + DPA_ASSERT(mc->state == mc_idle);
127186 +#ifdef CONFIG_FSL_DPA_CHECKING
127187 + mc->state = mc_user;
127188 +#endif
127189 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127190 + dcbz_64(mc->cr);
127191 +#endif
127192 + return mc->cr;
127193 +}
127194 +
127195 +static inline void bm_mc_abort(struct bm_portal *portal)
127196 +{
127197 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127198 + DPA_ASSERT(mc->state == mc_user);
127199 +#ifdef CONFIG_FSL_DPA_CHECKING
127200 + mc->state = mc_idle;
127201 +#endif
127202 +}
127203 +
127204 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
127205 +{
127206 + register struct bm_mc *mc = &portal->mc;
127207 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127208 + DPA_ASSERT(mc->state == mc_user);
127209 + lwsync();
127210 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
127211 + dcbf(mc->cr);
127212 + dcbit_ro(rr);
127213 +#ifdef CONFIG_FSL_DPA_CHECKING
127214 + mc->state = mc_hw;
127215 +#endif
127216 +}
127217 +
127218 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
127219 +{
127220 + register struct bm_mc *mc = &portal->mc;
127221 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127222 + DPA_ASSERT(mc->state == mc_hw);
127223 + /* The inactive response register's verb byte always returns zero until
127224 + * its command is submitted and completed. This includes the valid-bit,
127225 + * in case you were wondering... */
127226 + if (!__raw_readb(&rr->verb)) {
127227 + dcbit_ro(rr);
127228 + return NULL;
127229 + }
127230 + mc->rridx ^= 1;
127231 + mc->vbit ^= BM_MCC_VERB_VBIT;
127232 +#ifdef CONFIG_FSL_DPA_CHECKING
127233 + mc->state = mc_idle;
127234 +#endif
127235 + return rr;
127236 +}
127237 +
127238 +
127239 +/* ------------------------------------- */
127240 +/* --- Portal interrupt register API --- */
127241 +
127242 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
127243 +{
127244 + return 0;
127245 +}
127246 +
127247 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
127248 +{
127249 +}
127250 +
127251 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
127252 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
127253 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
127254 + int enable)
127255 +{
127256 + u32 val;
127257 + DPA_ASSERT(bpid < bman_pool_max);
127258 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
127259 + val = __bm_in(&portal->addr, SCN_REG(bpid));
127260 + if (enable)
127261 + val |= SCN_BIT(bpid);
127262 + else
127263 + val &= ~SCN_BIT(bpid);
127264 + __bm_out(&portal->addr, SCN_REG(bpid), val);
127265 +}
127266 +
127267 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
127268 +{
127269 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127270 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
127271 +#else
127272 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
127273 +#endif
127274 +}
127275 +
127276 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
127277 + u32 val)
127278 +{
127279 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127280 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
127281 +#else
127282 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
127283 +#endif
127284 +}
127285 +
127286 +/* Buffer Pool Cleanup */
127287 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
127288 +{
127289 + struct bm_mc_command *bm_cmd;
127290 + struct bm_mc_result *bm_res;
127291 +
127292 + int aq_count = 0;
127293 + bool stop = false;
127294 + while (!stop) {
127295 + /* Acquire buffers until empty */
127296 + bm_cmd = bm_mc_start(p);
127297 + bm_cmd->acquire.bpid = bpid;
127298 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
127299 + while (!(bm_res = bm_mc_result(p)))
127300 + cpu_relax();
127301 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
127302 + /* Pool is empty */
127303 + /* TBD : Should we do a few extra iterations in
127304 + case some other some blocks keep buffers 'on deck',
127305 + which may also be problematic */
127306 + stop = true;
127307 + } else
127308 + ++aq_count;
127309 + }
127310 + return 0;
127311 +}
127312 --- /dev/null
127313 +++ b/drivers/staging/fsl_qbman/bman_private.h
127314 @@ -0,0 +1,166 @@
127315 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127316 + *
127317 + * Redistribution and use in source and binary forms, with or without
127318 + * modification, are permitted provided that the following conditions are met:
127319 + * * Redistributions of source code must retain the above copyright
127320 + * notice, this list of conditions and the following disclaimer.
127321 + * * Redistributions in binary form must reproduce the above copyright
127322 + * notice, this list of conditions and the following disclaimer in the
127323 + * documentation and/or other materials provided with the distribution.
127324 + * * Neither the name of Freescale Semiconductor nor the
127325 + * names of its contributors may be used to endorse or promote products
127326 + * derived from this software without specific prior written permission.
127327 + *
127328 + *
127329 + * ALTERNATIVELY, this software may be distributed under the terms of the
127330 + * GNU General Public License ("GPL") as published by the Free Software
127331 + * Foundation, either version 2 of that License or (at your option) any
127332 + * later version.
127333 + *
127334 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127335 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127336 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127337 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127338 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127339 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127340 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127341 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127342 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127343 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127344 + */
127345 +
127346 +#include "dpa_sys.h"
127347 +#include <linux/fsl_bman.h>
127348 +
127349 +/* Revision info (for errata and feature handling) */
127350 +#define BMAN_REV10 0x0100
127351 +#define BMAN_REV20 0x0200
127352 +#define BMAN_REV21 0x0201
127353 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
127354 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
127355 +
127356 +/*
127357 + * Global variables of the max portal/pool number this bman version supported
127358 + */
127359 +extern u16 bman_pool_max;
127360 +
127361 +/* used by CCSR and portal interrupt code */
127362 +enum bm_isr_reg {
127363 + bm_isr_status = 0,
127364 + bm_isr_enable = 1,
127365 + bm_isr_disable = 2,
127366 + bm_isr_inhibit = 3
127367 +};
127368 +
127369 +struct bm_portal_config {
127370 + /* Corenet portal addresses;
127371 + * [0]==cache-enabled, [1]==cache-inhibited. */
127372 + __iomem void *addr_virt[2];
127373 + struct resource addr_phys[2];
127374 + /* Allow these to be joined in lists */
127375 + struct list_head list;
127376 + /* User-visible portal configuration settings */
127377 + struct bman_portal_config public_cfg;
127378 + /* power management saved data */
127379 + u32 saved_isdr;
127380 +};
127381 +
127382 +#ifdef CONFIG_FSL_BMAN_CONFIG
127383 +/* Hooks from bman_driver.c to bman_config.c */
127384 +int bman_init_ccsr(struct device_node *node);
127385 +#endif
127386 +
127387 +/* Hooks from bman_driver.c in to bman_high.c */
127388 +struct bman_portal *bman_create_portal(
127389 + struct bman_portal *portal,
127390 + const struct bm_portal_config *config);
127391 +struct bman_portal *bman_create_affine_portal(
127392 + const struct bm_portal_config *config);
127393 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
127394 + int cpu);
127395 +void bman_destroy_portal(struct bman_portal *bm);
127396 +
127397 +const struct bm_portal_config *bman_destroy_affine_portal(void);
127398 +
127399 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
127400 +struct bm_portal_config *bm_get_unused_portal(void);
127401 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
127402 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
127403 +void bm_set_liodns(struct bm_portal_config *pcfg);
127404 +
127405 +/* Pool logic in the portal driver, during initialisation, needs to know if
127406 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
127407 +#ifdef CONFIG_FSL_BMAN_CONFIG
127408 +int bman_have_ccsr(void);
127409 +#else
127410 +#define bman_have_ccsr() 0
127411 +#endif
127412 +
127413 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
127414 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
127415 + * might fail (if the buffer pool is depleted). So this value provides some
127416 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
127417 + * are requested at once or if h/w has been tested a couple of times without
127418 + * luck. The _HIGH value: when bman_release() is called and the stockpile
127419 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
127420 + * the release ring is full). So this value provides some "stagger" so that
127421 + * ring-access is retried a couple of times prior to the API returning a
127422 + * failure. The following *must* be true;
127423 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
127424 + * (to avoid thrashing)
127425 + * BMAN_STOCKPILE_SZ >= 16
127426 + * (as the release logic expects to either send 8 buffers to hw prior to
127427 + * adding the given buffers to the stockpile or add the buffers to the
127428 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
127429 + * success/fail.)
127430 + */
127431 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
127432 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
127433 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
127434 +
127435 +/*************************************************/
127436 +/* BMan s/w corenet portal, low-level i/face */
127437 +/*************************************************/
127438 +
127439 +/* Used by all portal interrupt registers except 'inhibit'
127440 + * This mask contains all the "irqsource" bits visible to API users
127441 + */
127442 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
127443 +
127444 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
127445 + * the disable register" rather than "disable the ability to write". */
127446 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
127447 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
127448 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
127449 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
127450 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
127451 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
127452 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
127453 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
127454 +
127455 +#ifdef CONFIG_FSL_BMAN_CONFIG
127456 +/* Set depletion thresholds associated with a buffer pool. Requires that the
127457 + * operating system have access to Bman CCSR (ie. compiled in support and
127458 + * run-time access courtesy of the device-tree). */
127459 +int bm_pool_set(u32 bpid, const u32 *thresholds);
127460 +#define BM_POOL_THRESH_SW_ENTER 0
127461 +#define BM_POOL_THRESH_SW_EXIT 1
127462 +#define BM_POOL_THRESH_HW_ENTER 2
127463 +#define BM_POOL_THRESH_HW_EXIT 3
127464 +
127465 +/* Read the free buffer count for a given buffer */
127466 +u32 bm_pool_free_buffers(u32 bpid);
127467 +
127468 +__init int bman_init(void);
127469 +__init int bman_resource_init(void);
127470 +
127471 +const struct bm_portal_config *bman_get_bm_portal_config(
127472 + struct bman_portal *portal);
127473 +
127474 +/* power management */
127475 +#ifdef CONFIG_SUSPEND
127476 +void suspend_unused_bportal(void);
127477 +void resume_unused_bportal(void);
127478 +#endif
127479 +
127480 +#endif /* CONFIG_FSL_BMAN_CONFIG */
127481 --- /dev/null
127482 +++ b/drivers/staging/fsl_qbman/bman_test.c
127483 @@ -0,0 +1,56 @@
127484 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127485 + *
127486 + * Redistribution and use in source and binary forms, with or without
127487 + * modification, are permitted provided that the following conditions are met:
127488 + * * Redistributions of source code must retain the above copyright
127489 + * notice, this list of conditions and the following disclaimer.
127490 + * * Redistributions in binary form must reproduce the above copyright
127491 + * notice, this list of conditions and the following disclaimer in the
127492 + * documentation and/or other materials provided with the distribution.
127493 + * * Neither the name of Freescale Semiconductor nor the
127494 + * names of its contributors may be used to endorse or promote products
127495 + * derived from this software without specific prior written permission.
127496 + *
127497 + *
127498 + * ALTERNATIVELY, this software may be distributed under the terms of the
127499 + * GNU General Public License ("GPL") as published by the Free Software
127500 + * Foundation, either version 2 of that License or (at your option) any
127501 + * later version.
127502 + *
127503 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127504 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127505 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127506 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127507 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127508 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127509 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127510 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127511 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127512 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127513 + */
127514 +
127515 +#include "bman_test.h"
127516 +
127517 +MODULE_AUTHOR("Geoff Thorpe");
127518 +MODULE_LICENSE("Dual BSD/GPL");
127519 +MODULE_DESCRIPTION("Bman testing");
127520 +
127521 +static int test_init(void)
127522 +{
127523 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
127524 + int loop = 1;
127525 + while (loop--)
127526 + bman_test_high();
127527 +#endif
127528 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
127529 + bman_test_thresh();
127530 +#endif
127531 + return 0;
127532 +}
127533 +
127534 +static void test_exit(void)
127535 +{
127536 +}
127537 +
127538 +module_init(test_init);
127539 +module_exit(test_exit);
127540 --- /dev/null
127541 +++ b/drivers/staging/fsl_qbman/bman_test.h
127542 @@ -0,0 +1,44 @@
127543 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127544 + *
127545 + * Redistribution and use in source and binary forms, with or without
127546 + * modification, are permitted provided that the following conditions are met:
127547 + * * Redistributions of source code must retain the above copyright
127548 + * notice, this list of conditions and the following disclaimer.
127549 + * * Redistributions in binary form must reproduce the above copyright
127550 + * notice, this list of conditions and the following disclaimer in the
127551 + * documentation and/or other materials provided with the distribution.
127552 + * * Neither the name of Freescale Semiconductor nor the
127553 + * names of its contributors may be used to endorse or promote products
127554 + * derived from this software without specific prior written permission.
127555 + *
127556 + *
127557 + * ALTERNATIVELY, this software may be distributed under the terms of the
127558 + * GNU General Public License ("GPL") as published by the Free Software
127559 + * Foundation, either version 2 of that License or (at your option) any
127560 + * later version.
127561 + *
127562 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127563 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127564 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127565 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127566 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127567 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127568 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127569 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127570 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127571 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127572 + */
127573 +
127574 +#include <linux/kernel.h>
127575 +#include <linux/errno.h>
127576 +#include <linux/io.h>
127577 +#include <linux/slab.h>
127578 +#include <linux/module.h>
127579 +#include <linux/interrupt.h>
127580 +#include <linux/delay.h>
127581 +#include <linux/kthread.h>
127582 +
127583 +#include <linux/fsl_bman.h>
127584 +
127585 +void bman_test_high(void);
127586 +void bman_test_thresh(void);
127587 --- /dev/null
127588 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
127589 @@ -0,0 +1,183 @@
127590 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127591 + *
127592 + * Redistribution and use in source and binary forms, with or without
127593 + * modification, are permitted provided that the following conditions are met:
127594 + * * Redistributions of source code must retain the above copyright
127595 + * notice, this list of conditions and the following disclaimer.
127596 + * * Redistributions in binary form must reproduce the above copyright
127597 + * notice, this list of conditions and the following disclaimer in the
127598 + * documentation and/or other materials provided with the distribution.
127599 + * * Neither the name of Freescale Semiconductor nor the
127600 + * names of its contributors may be used to endorse or promote products
127601 + * derived from this software without specific prior written permission.
127602 + *
127603 + *
127604 + * ALTERNATIVELY, this software may be distributed under the terms of the
127605 + * GNU General Public License ("GPL") as published by the Free Software
127606 + * Foundation, either version 2 of that License or (at your option) any
127607 + * later version.
127608 + *
127609 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127610 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127611 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127612 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127613 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127614 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127615 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127616 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127617 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127618 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127619 + */
127620 +
127621 +#include "bman_test.h"
127622 +#include "bman_private.h"
127623 +
127624 +/*************/
127625 +/* constants */
127626 +/*************/
127627 +
127628 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
127629 +#define POOL_OPAQUE ((void *)0xdeadabba)
127630 +#define NUM_BUFS 93
127631 +#define LOOPS 3
127632 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
127633 +
127634 +/***************/
127635 +/* global vars */
127636 +/***************/
127637 +
127638 +static struct bman_pool *pool;
127639 +static int depleted;
127640 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
127641 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
127642 +static int bufs_received;
127643 +
127644 +/* Predeclare the callback so we can instantiate pool parameters */
127645 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
127646 +
127647 +/**********************/
127648 +/* internal functions */
127649 +/**********************/
127650 +
127651 +static void bufs_init(void)
127652 +{
127653 + int i;
127654 + for (i = 0; i < NUM_BUFS; i++)
127655 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
127656 + bufs_received = 0;
127657 +}
127658 +
127659 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
127660 +{
127661 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
127662 +
127663 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
127664 + * LS-bits of buffer addresses, masking off the upper 8-bits on
127665 + * release commands. The API provides for 48-bit addresses
127666 + * because some SoCs support all 48-bits. When generating
127667 + * garbage addresses for testing, we either need to zero the
127668 + * upper 8-bits when releasing to Bman (otherwise we'll be
127669 + * disappointed when the buffers we acquire back from Bman
127670 + * don't match), or we need to mask the upper 8-bits off when
127671 + * comparing. We do the latter.
127672 + */
127673 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
127674 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
127675 + return -1;
127676 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
127677 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
127678 + return 1;
127679 + } else {
127680 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
127681 + return -1;
127682 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
127683 + return 1;
127684 + }
127685 +
127686 + return 0;
127687 +}
127688 +
127689 +static void bufs_confirm(void)
127690 +{
127691 + int i, j;
127692 + for (i = 0; i < NUM_BUFS; i++) {
127693 + int matches = 0;
127694 + for (j = 0; j < NUM_BUFS; j++)
127695 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
127696 + matches++;
127697 + BUG_ON(matches != 1);
127698 + }
127699 +}
127700 +
127701 +/********/
127702 +/* test */
127703 +/********/
127704 +
127705 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
127706 + void *pool_ctx, int __depleted)
127707 +{
127708 + BUG_ON(__pool != pool);
127709 + BUG_ON(pool_ctx != POOL_OPAQUE);
127710 + depleted = __depleted;
127711 +}
127712 +
127713 +void bman_test_high(void)
127714 +{
127715 + struct bman_pool_params pparams = {
127716 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
127717 + .cb = depletion_cb,
127718 + .cb_ctx = POOL_OPAQUE,
127719 + };
127720 + int i, loops = LOOPS;
127721 + struct bm_buffer tmp_buf;
127722 +
127723 + bufs_init();
127724 +
127725 + pr_info("BMAN: --- starting high-level test ---\n");
127726 +
127727 + pool = bman_new_pool(&pparams);
127728 + BUG_ON(!pool);
127729 +
127730 + /*******************/
127731 + /* Release buffers */
127732 + /*******************/
127733 +do_loop:
127734 + i = 0;
127735 + while (i < NUM_BUFS) {
127736 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
127737 + int num = 8;
127738 + if ((i + num) > NUM_BUFS)
127739 + num = NUM_BUFS - i;
127740 + if ((i + num) == NUM_BUFS)
127741 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
127742 + if (bman_release(pool, bufs_in + i, num, flags))
127743 + panic("bman_release() failed\n");
127744 + i += num;
127745 + }
127746 +
127747 + /*******************/
127748 + /* Acquire buffers */
127749 + /*******************/
127750 + while (i > 0) {
127751 + int tmp, num = 8;
127752 + if (num > i)
127753 + num = i;
127754 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
127755 + BUG_ON(tmp != num);
127756 + i -= num;
127757 + }
127758 +
127759 + i = bman_acquire(pool, &tmp_buf, 1, 0);
127760 + BUG_ON(i > 0);
127761 +
127762 + bufs_confirm();
127763 +
127764 + if (--loops)
127765 + goto do_loop;
127766 +
127767 + /************/
127768 + /* Clean up */
127769 + /************/
127770 + bman_free_pool(pool);
127771 + pr_info("BMAN: --- finished high-level test ---\n");
127772 +}
127773 --- /dev/null
127774 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
127775 @@ -0,0 +1,196 @@
127776 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
127777 + *
127778 + * Redistribution and use in source and binary forms, with or without
127779 + * modification, are permitted provided that the following conditions are met:
127780 + * * Redistributions of source code must retain the above copyright
127781 + * notice, this list of conditions and the following disclaimer.
127782 + * * Redistributions in binary form must reproduce the above copyright
127783 + * notice, this list of conditions and the following disclaimer in the
127784 + * documentation and/or other materials provided with the distribution.
127785 + * * Neither the name of Freescale Semiconductor nor the
127786 + * names of its contributors may be used to endorse or promote products
127787 + * derived from this software without specific prior written permission.
127788 + *
127789 + *
127790 + * ALTERNATIVELY, this software may be distributed under the terms of the
127791 + * GNU General Public License ("GPL") as published by the Free Software
127792 + * Foundation, either version 2 of that License or (at your option) any
127793 + * later version.
127794 + *
127795 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127796 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127797 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127798 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127799 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127800 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127801 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127802 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127803 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127804 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127805 + */
127806 +
127807 +#include "bman_test.h"
127808 +
127809 +/* Test constants */
127810 +#define TEST_NUMBUFS 129728
127811 +#define TEST_EXIT 129536
127812 +#define TEST_ENTRY 129024
127813 +
127814 +struct affine_test_data {
127815 + struct task_struct *t;
127816 + int cpu;
127817 + int expect_affinity;
127818 + int drain;
127819 + int num_enter;
127820 + int num_exit;
127821 + struct list_head node;
127822 + struct completion wakethread;
127823 + struct completion wakeparent;
127824 +};
127825 +
127826 +static void cb_depletion(struct bman_portal *portal,
127827 + struct bman_pool *pool,
127828 + void *opaque,
127829 + int depleted)
127830 +{
127831 + struct affine_test_data *data = opaque;
127832 + int c = smp_processor_id();
127833 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
127834 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
127835 + /* We should be executing on the CPU of the thread that owns the pool if
127836 + * and that CPU has an affine portal (ie. it isn't slaved). */
127837 + BUG_ON((c != data->cpu) && data->expect_affinity);
127838 + BUG_ON((c == data->cpu) && !data->expect_affinity);
127839 + if (depleted)
127840 + data->num_enter++;
127841 + else
127842 + data->num_exit++;
127843 +}
127844 +
127845 +/* Params used to set up a pool, this also dynamically allocates a BPID */
127846 +static const struct bman_pool_params params_nocb = {
127847 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
127848 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
127849 +};
127850 +
127851 +/* Params used to set up each cpu's pool with callbacks enabled */
127852 +static struct bman_pool_params params_cb = {
127853 + .bpid = 0, /* will be replaced to match pool_nocb */
127854 + .flags = BMAN_POOL_FLAG_DEPLETION,
127855 + .cb = cb_depletion
127856 +};
127857 +
127858 +static struct bman_pool *pool_nocb;
127859 +static LIST_HEAD(threads);
127860 +
127861 +static int affine_test(void *__data)
127862 +{
127863 + struct bman_pool *pool;
127864 + struct affine_test_data *data = __data;
127865 + struct bman_pool_params my_params = params_cb;
127866 +
127867 + pr_info("thread %d: starting\n", data->cpu);
127868 + /* create the pool */
127869 + my_params.cb_ctx = data;
127870 + pool = bman_new_pool(&my_params);
127871 + BUG_ON(!pool);
127872 + complete(&data->wakeparent);
127873 + wait_for_completion(&data->wakethread);
127874 + init_completion(&data->wakethread);
127875 +
127876 + /* if we're the drainer, we get signalled for that */
127877 + if (data->drain) {
127878 + struct bm_buffer buf;
127879 + int ret;
127880 + pr_info("thread %d: draining...\n", data->cpu);
127881 + do {
127882 + ret = bman_acquire(pool, &buf, 1, 0);
127883 + } while (ret > 0);
127884 + pr_info("thread %d: draining done.\n", data->cpu);
127885 + complete(&data->wakeparent);
127886 + wait_for_completion(&data->wakethread);
127887 + init_completion(&data->wakethread);
127888 + }
127889 +
127890 + /* cleanup */
127891 + bman_free_pool(pool);
127892 + while (!kthread_should_stop())
127893 + cpu_relax();
127894 + pr_info("thread %d: exiting\n", data->cpu);
127895 + return 0;
127896 +}
127897 +
127898 +static struct affine_test_data *start_affine_test(int cpu, int drain)
127899 +{
127900 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
127901 +
127902 + if (!data)
127903 + return NULL;
127904 + data->cpu = cpu;
127905 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
127906 + data->drain = drain;
127907 + data->num_enter = 0;
127908 + data->num_exit = 0;
127909 + init_completion(&data->wakethread);
127910 + init_completion(&data->wakeparent);
127911 + list_add_tail(&data->node, &threads);
127912 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
127913 + BUG_ON(IS_ERR(data->t));
127914 + kthread_bind(data->t, cpu);
127915 + wake_up_process(data->t);
127916 + return data;
127917 +}
127918 +
127919 +void bman_test_thresh(void)
127920 +{
127921 + int loop = TEST_NUMBUFS;
127922 + int ret, num_cpus = 0;
127923 + struct affine_test_data *data, *drainer = NULL;
127924 +
127925 + pr_info("bman_test_thresh: start\n");
127926 +
127927 + /* allocate a BPID and seed it */
127928 + pool_nocb = bman_new_pool(&params_nocb);
127929 + BUG_ON(!pool_nocb);
127930 + while (loop--) {
127931 + struct bm_buffer buf;
127932 + bm_buffer_set64(&buf, 0x0badbeef + loop);
127933 + ret = bman_release(pool_nocb, &buf, 1,
127934 + BMAN_RELEASE_FLAG_WAIT);
127935 + BUG_ON(ret);
127936 + }
127937 + while (!bman_rcr_is_empty())
127938 + cpu_relax();
127939 + pr_info("bman_test_thresh: buffers are in\n");
127940 +
127941 + /* create threads and wait for them to create pools */
127942 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
127943 + for_each_cpu(loop, cpu_online_mask) {
127944 + data = start_affine_test(loop, drainer ? 0 : 1);
127945 + BUG_ON(!data);
127946 + if (!drainer)
127947 + drainer = data;
127948 + num_cpus++;
127949 + wait_for_completion(&data->wakeparent);
127950 + }
127951 +
127952 + /* signal the drainer to start draining */
127953 + complete(&drainer->wakethread);
127954 + wait_for_completion(&drainer->wakeparent);
127955 + init_completion(&drainer->wakeparent);
127956 +
127957 + /* tear down */
127958 + list_for_each_entry_safe(data, drainer, &threads, node) {
127959 + complete(&data->wakethread);
127960 + ret = kthread_stop(data->t);
127961 + BUG_ON(ret);
127962 + list_del(&data->node);
127963 + /* check that we get the expected callbacks (and no others) */
127964 + BUG_ON(data->num_enter != 1);
127965 + BUG_ON(data->num_exit != 0);
127966 + kfree(data);
127967 + }
127968 + bman_free_pool(pool_nocb);
127969 +
127970 + pr_info("bman_test_thresh: done\n");
127971 +}
127972 --- /dev/null
127973 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
127974 @@ -0,0 +1,706 @@
127975 +/* Copyright 2009-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_qman.h>
128008 +#include <linux/fsl_bman.h>
128009 +
128010 +/* Qman and Bman APIs are front-ends to the common code; */
128011 +
128012 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
128013 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
128014 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
128015 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
128016 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
128017 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
128018 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
128019 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
128020 +
128021 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
128022 + * FQIDs (probably from user-space), it can filter out those that aren't in the
128023 + * OOS state (better to leak a h/w resource than to crash). This function
128024 + * returns the number of invalid IDs that were not released. */
128025 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
128026 + int (*is_valid)(u32 id))
128027 +{
128028 + int valid_mode = 0;
128029 + u32 loop = id, total_invalid = 0;
128030 + while (loop < (id + count)) {
128031 + int isvalid = is_valid ? is_valid(loop) : 1;
128032 + if (!valid_mode) {
128033 + /* We're looking for a valid ID to terminate an invalid
128034 + * range */
128035 + if (isvalid) {
128036 + /* We finished a range of invalid IDs, a valid
128037 + * range is now underway */
128038 + valid_mode = 1;
128039 + count -= (loop - id);
128040 + id = loop;
128041 + } else
128042 + total_invalid++;
128043 + } else {
128044 + /* We're looking for an invalid ID to terminate a
128045 + * valid range */
128046 + if (!isvalid) {
128047 + /* Release the range of valid IDs, an unvalid
128048 + * range is now underway */
128049 + if (loop > id)
128050 + dpa_alloc_free(alloc, id, loop - id);
128051 + valid_mode = 0;
128052 + }
128053 + }
128054 + loop++;
128055 + }
128056 + /* Release any unterminated range of valid IDs */
128057 + if (valid_mode && count)
128058 + dpa_alloc_free(alloc, id, count);
128059 + return total_invalid;
128060 +}
128061 +
128062 +/* BPID allocator front-end */
128063 +
128064 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
128065 +{
128066 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
128067 +}
128068 +EXPORT_SYMBOL(bman_alloc_bpid_range);
128069 +
128070 +static int bp_cleanup(u32 bpid)
128071 +{
128072 + return bman_shutdown_pool(bpid) == 0;
128073 +}
128074 +void bman_release_bpid_range(u32 bpid, u32 count)
128075 +{
128076 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
128077 + if (total_invalid)
128078 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
128079 + bpid, bpid + count - 1, count, total_invalid);
128080 +}
128081 +EXPORT_SYMBOL(bman_release_bpid_range);
128082 +
128083 +void bman_seed_bpid_range(u32 bpid, u32 count)
128084 +{
128085 + dpa_alloc_seed(&bpalloc, bpid, count);
128086 +}
128087 +EXPORT_SYMBOL(bman_seed_bpid_range);
128088 +
128089 +int bman_reserve_bpid_range(u32 bpid, u32 count)
128090 +{
128091 + return dpa_alloc_reserve(&bpalloc, bpid, count);
128092 +}
128093 +EXPORT_SYMBOL(bman_reserve_bpid_range);
128094 +
128095 +
128096 +/* FQID allocator front-end */
128097 +
128098 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
128099 +{
128100 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
128101 +}
128102 +EXPORT_SYMBOL(qman_alloc_fqid_range);
128103 +
128104 +static int fq_cleanup(u32 fqid)
128105 +{
128106 + return qman_shutdown_fq(fqid) == 0;
128107 +}
128108 +void qman_release_fqid_range(u32 fqid, u32 count)
128109 +{
128110 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
128111 + if (total_invalid)
128112 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
128113 + fqid, fqid + count - 1, count, total_invalid);
128114 +}
128115 +EXPORT_SYMBOL(qman_release_fqid_range);
128116 +
128117 +int qman_reserve_fqid_range(u32 fqid, u32 count)
128118 +{
128119 + return dpa_alloc_reserve(&fqalloc, fqid, count);
128120 +}
128121 +EXPORT_SYMBOL(qman_reserve_fqid_range);
128122 +
128123 +void qman_seed_fqid_range(u32 fqid, u32 count)
128124 +{
128125 + dpa_alloc_seed(&fqalloc, fqid, count);
128126 +}
128127 +EXPORT_SYMBOL(qman_seed_fqid_range);
128128 +
128129 +/* Pool-channel allocator front-end */
128130 +
128131 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
128132 +{
128133 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
128134 +}
128135 +EXPORT_SYMBOL(qman_alloc_pool_range);
128136 +
128137 +static int qpool_cleanup(u32 qp)
128138 +{
128139 + /* We query all FQDs starting from
128140 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128141 + * whose destination channel is the pool-channel being released.
128142 + * When a non-OOS FQD is found we attempt to clean it up */
128143 + struct qman_fq fq = {
128144 + .fqid = 1
128145 + };
128146 + int err;
128147 + do {
128148 + struct qm_mcr_queryfq_np np;
128149 + err = qman_query_fq_np(&fq, &np);
128150 + if (err)
128151 + /* FQID range exceeded, found no problems */
128152 + return 1;
128153 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128154 + struct qm_fqd fqd;
128155 + err = qman_query_fq(&fq, &fqd);
128156 + BUG_ON(err);
128157 + if (fqd.dest.channel == qp) {
128158 + /* The channel is the FQ's target, clean it */
128159 + if (qman_shutdown_fq(fq.fqid) != 0)
128160 + /* Couldn't shut down the FQ
128161 + so the pool must be leaked */
128162 + return 0;
128163 + }
128164 + }
128165 + /* Move to the next FQID */
128166 + fq.fqid++;
128167 + } while (1);
128168 +}
128169 +void qman_release_pool_range(u32 qp, u32 count)
128170 +{
128171 + u32 total_invalid = release_id_range(&qpalloc, qp,
128172 + count, qpool_cleanup);
128173 + if (total_invalid) {
128174 + /* Pool channels are almost always used individually */
128175 + if (count == 1)
128176 + pr_err("Pool channel 0x%x had %d leaks\n",
128177 + qp, total_invalid);
128178 + else
128179 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
128180 + qp, qp + count - 1, count, total_invalid);
128181 + }
128182 +}
128183 +EXPORT_SYMBOL(qman_release_pool_range);
128184 +
128185 +
128186 +void qman_seed_pool_range(u32 poolid, u32 count)
128187 +{
128188 + dpa_alloc_seed(&qpalloc, poolid, count);
128189 +
128190 +}
128191 +EXPORT_SYMBOL(qman_seed_pool_range);
128192 +
128193 +int qman_reserve_pool_range(u32 poolid, u32 count)
128194 +{
128195 + return dpa_alloc_reserve(&qpalloc, poolid, count);
128196 +}
128197 +EXPORT_SYMBOL(qman_reserve_pool_range);
128198 +
128199 +
128200 +/* CGR ID allocator front-end */
128201 +
128202 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
128203 +{
128204 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
128205 +}
128206 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
128207 +
128208 +static int cqr_cleanup(u32 cgrid)
128209 +{
128210 + /* We query all FQDs starting from
128211 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128212 + * whose CGR is the CGR being released.
128213 + */
128214 + struct qman_fq fq = {
128215 + .fqid = 1
128216 + };
128217 + int err;
128218 + do {
128219 + struct qm_mcr_queryfq_np np;
128220 + err = qman_query_fq_np(&fq, &np);
128221 + if (err)
128222 + /* FQID range exceeded, found no problems */
128223 + return 1;
128224 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128225 + struct qm_fqd fqd;
128226 + err = qman_query_fq(&fq, &fqd);
128227 + BUG_ON(err);
128228 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
128229 + (fqd.cgid == cgrid)) {
128230 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
128231 + " CGR will be leaked\n",
128232 + cgrid, fq.fqid);
128233 + return 1;
128234 + }
128235 + }
128236 + /* Move to the next FQID */
128237 + fq.fqid++;
128238 + } while (1);
128239 +}
128240 +
128241 +void qman_release_cgrid_range(u32 cgrid, u32 count)
128242 +{
128243 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
128244 + count, cqr_cleanup);
128245 + if (total_invalid)
128246 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
128247 + cgrid, cgrid + count - 1, count, total_invalid);
128248 +}
128249 +EXPORT_SYMBOL(qman_release_cgrid_range);
128250 +
128251 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
128252 +{
128253 + dpa_alloc_seed(&cgralloc, cgrid, count);
128254 +
128255 +}
128256 +EXPORT_SYMBOL(qman_seed_cgrid_range);
128257 +
128258 +/* CEETM CHANNEL ID allocator front-end */
128259 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
128260 + int partial)
128261 +{
128262 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
128263 +}
128264 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
128265 +
128266 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
128267 + int partial)
128268 +{
128269 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
128270 +}
128271 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
128272 +
128273 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
128274 +{
128275 + u32 total_invalid;
128276 +
128277 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
128278 + NULL);
128279 + if (total_invalid)
128280 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128281 + channelid, channelid + count - 1, count, total_invalid);
128282 +}
128283 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
128284 +
128285 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
128286 +{
128287 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
128288 +
128289 +}
128290 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
128291 +
128292 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
128293 +{
128294 + u32 total_invalid;
128295 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
128296 + NULL);
128297 + if (total_invalid)
128298 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128299 + channelid, channelid + count - 1, count, total_invalid);
128300 +}
128301 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
128302 +
128303 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
128304 +{
128305 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
128306 +
128307 +}
128308 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
128309 +
128310 +/* CEETM LFQID allocator front-end */
128311 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
128312 + int partial)
128313 +{
128314 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
128315 +}
128316 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
128317 +
128318 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
128319 + int partial)
128320 +{
128321 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
128322 +}
128323 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
128324 +
128325 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
128326 +{
128327 + u32 total_invalid;
128328 +
128329 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
128330 + NULL);
128331 + if (total_invalid)
128332 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128333 + lfqid, lfqid + count - 1, count, total_invalid);
128334 +}
128335 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
128336 +
128337 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
128338 +{
128339 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
128340 +
128341 +}
128342 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
128343 +
128344 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
128345 +{
128346 + u32 total_invalid;
128347 +
128348 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
128349 + NULL);
128350 + if (total_invalid)
128351 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128352 + lfqid, lfqid + count - 1, count, total_invalid);
128353 +}
128354 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
128355 +
128356 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
128357 +{
128358 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
128359 +
128360 +}
128361 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
128362 +
128363 +
128364 +/* Everything else is the common backend to all the allocators */
128365 +
128366 +/* The allocator is a (possibly-empty) list of these; */
128367 +struct alloc_node {
128368 + struct list_head list;
128369 + u32 base;
128370 + u32 num;
128371 + /* refcount and is_alloced are only set
128372 + when the node is in the used list */
128373 + unsigned int refcount;
128374 + int is_alloced;
128375 +};
128376 +
128377 +/* #define DPA_ALLOC_DEBUG */
128378 +
128379 +#ifdef DPA_ALLOC_DEBUG
128380 +#define DPRINT pr_info
128381 +static void DUMP(struct dpa_alloc *alloc)
128382 +{
128383 + int off = 0;
128384 + char buf[256];
128385 + struct alloc_node *p;
128386 + pr_info("Free Nodes\n");
128387 + list_for_each_entry(p, &alloc->free, list) {
128388 + if (off < 255)
128389 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128390 + p->base, p->base + p->num - 1);
128391 + }
128392 + pr_info("%s\n", buf);
128393 +
128394 + off = 0;
128395 + pr_info("Used Nodes\n");
128396 + list_for_each_entry(p, &alloc->used, list) {
128397 + if (off < 255)
128398 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128399 + p->base, p->base + p->num - 1);
128400 + }
128401 + pr_info("%s\n", buf);
128402 +
128403 +
128404 +
128405 +}
128406 +#else
128407 +#define DPRINT(x...)
128408 +#define DUMP(a)
128409 +#endif
128410 +
128411 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
128412 + int partial)
128413 +{
128414 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
128415 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
128416 + struct alloc_node *margin_left, *margin_right;
128417 +
128418 + *result = (u32)-1;
128419 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
128420 + DUMP(alloc);
128421 + /* If 'align' is 0, it should behave as though it was 1 */
128422 + if (!align)
128423 + align = 1;
128424 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
128425 + if (!margin_left)
128426 + goto err;
128427 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
128428 + if (!margin_right) {
128429 + kfree(margin_left);
128430 + goto err;
128431 + }
128432 + spin_lock_irq(&alloc->lock);
128433 + list_for_each_entry(i, &alloc->free, list) {
128434 + base = (i->base + align - 1) / align;
128435 + base *= align;
128436 + if ((base - i->base) >= i->num)
128437 + /* alignment is impossible, regardless of count */
128438 + continue;
128439 + num = i->num - (base - i->base);
128440 + if (num >= count) {
128441 + /* this one will do nicely */
128442 + num = count;
128443 + goto done;
128444 + }
128445 + if (num > next_best_num) {
128446 + next_best = i;
128447 + next_best_base = base;
128448 + next_best_num = num;
128449 + }
128450 + }
128451 + if (partial && next_best) {
128452 + i = next_best;
128453 + base = next_best_base;
128454 + num = next_best_num;
128455 + } else
128456 + i = NULL;
128457 +done:
128458 + if (i) {
128459 + if (base != i->base) {
128460 + margin_left->base = i->base;
128461 + margin_left->num = base - i->base;
128462 + list_add_tail(&margin_left->list, &i->list);
128463 + } else
128464 + kfree(margin_left);
128465 + if ((base + num) < (i->base + i->num)) {
128466 + margin_right->base = base + num;
128467 + margin_right->num = (i->base + i->num) -
128468 + (base + num);
128469 + list_add(&margin_right->list, &i->list);
128470 + } else
128471 + kfree(margin_right);
128472 + list_del(&i->list);
128473 + kfree(i);
128474 + *result = base;
128475 + } else {
128476 + spin_unlock_irq(&alloc->lock);
128477 + kfree(margin_left);
128478 + kfree(margin_right);
128479 + }
128480 +
128481 +err:
128482 + DPRINT("returning %d\n", i ? num : -ENOMEM);
128483 + DUMP(alloc);
128484 + if (!i)
128485 + return -ENOMEM;
128486 +
128487 + /* Add the allocation to the used list with a refcount of 1 */
128488 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128489 + if (!used_node) {
128490 + spin_unlock_irq(&alloc->lock);
128491 + return -ENOMEM;
128492 + }
128493 + used_node->base = *result;
128494 + used_node->num = num;
128495 + used_node->refcount = 1;
128496 + used_node->is_alloced = 1;
128497 + list_add_tail(&used_node->list, &alloc->used);
128498 + spin_unlock_irq(&alloc->lock);
128499 + return (int)num;
128500 +}
128501 +
128502 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
128503 + * forcing error-handling on to users in the deallocation path. */
128504 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128505 +{
128506 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
128507 + BUG_ON(!node);
128508 + DPRINT("release_range(%d,%d)\n", base_id, count);
128509 + DUMP(alloc);
128510 + BUG_ON(!count);
128511 + spin_lock_irq(&alloc->lock);
128512 +
128513 +
128514 + node->base = base_id;
128515 + node->num = count;
128516 + list_for_each_entry(i, &alloc->free, list) {
128517 + if (i->base >= node->base) {
128518 + /* BUG_ON(any overlapping) */
128519 + BUG_ON(i->base < (node->base + node->num));
128520 + list_add_tail(&node->list, &i->list);
128521 + goto done;
128522 + }
128523 + }
128524 + list_add_tail(&node->list, &alloc->free);
128525 +done:
128526 + /* Merge to the left */
128527 + i = list_entry(node->list.prev, struct alloc_node, list);
128528 + if (node->list.prev != &alloc->free) {
128529 + BUG_ON((i->base + i->num) > node->base);
128530 + if ((i->base + i->num) == node->base) {
128531 + node->base = i->base;
128532 + node->num += i->num;
128533 + list_del(&i->list);
128534 + kfree(i);
128535 + }
128536 + }
128537 + /* Merge to the right */
128538 + i = list_entry(node->list.next, struct alloc_node, list);
128539 + if (node->list.next != &alloc->free) {
128540 + BUG_ON((node->base + node->num) > i->base);
128541 + if ((node->base + node->num) == i->base) {
128542 + node->num += i->num;
128543 + list_del(&i->list);
128544 + kfree(i);
128545 + }
128546 + }
128547 + spin_unlock_irq(&alloc->lock);
128548 + DUMP(alloc);
128549 +}
128550 +
128551 +
128552 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128553 +{
128554 + struct alloc_node *i = NULL;
128555 + spin_lock_irq(&alloc->lock);
128556 +
128557 + /* First find the node in the used list and decrement its ref count */
128558 + list_for_each_entry(i, &alloc->used, list) {
128559 + if (i->base == base_id && i->num == count) {
128560 + --i->refcount;
128561 + if (i->refcount == 0) {
128562 + list_del(&i->list);
128563 + spin_unlock_irq(&alloc->lock);
128564 + if (i->is_alloced)
128565 + _dpa_alloc_free(alloc, base_id, count);
128566 + kfree(i);
128567 + return;
128568 + }
128569 + spin_unlock_irq(&alloc->lock);
128570 + return;
128571 + }
128572 + }
128573 + /* Couldn't find the allocation */
128574 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
128575 + base_id, count);
128576 + spin_unlock_irq(&alloc->lock);
128577 +}
128578 +
128579 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
128580 +{
128581 + /* Same as free but no previous allocation checking is needed */
128582 + _dpa_alloc_free(alloc, base_id, count);
128583 +}
128584 +
128585 +
128586 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
128587 +{
128588 + struct alloc_node *i = NULL, *used_node;
128589 +
128590 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
128591 + DUMP(alloc);
128592 +
128593 + spin_lock_irq(&alloc->lock);
128594 +
128595 + /* Check for the node in the used list.
128596 + If found, increase it's refcount */
128597 + list_for_each_entry(i, &alloc->used, list) {
128598 + if ((i->base == base) && (i->num == num)) {
128599 + ++i->refcount;
128600 + spin_unlock_irq(&alloc->lock);
128601 + return 0;
128602 + }
128603 + if ((base >= i->base) && (base < (i->base + i->num))) {
128604 + /* This is an attempt to reserve a region that was
128605 + already reserved or alloced with a different
128606 + base or num */
128607 + pr_err("Cannot reserve %d - %d, it overlaps with"
128608 + " existing reservation from %d - %d\n",
128609 + base, base + num - 1, i->base,
128610 + i->base + i->num - 1);
128611 + spin_unlock_irq(&alloc->lock);
128612 + return -1;
128613 + }
128614 + }
128615 + /* Check to make sure this ID isn't in the free list */
128616 + list_for_each_entry(i, &alloc->free, list) {
128617 + if ((base >= i->base) && (base < (i->base + i->num))) {
128618 + /* yep, the reservation is within this node */
128619 + pr_err("Cannot reserve %d - %d, it overlaps with"
128620 + " free range %d - %d and must be alloced\n",
128621 + base, base + num - 1,
128622 + i->base, i->base + i->num - 1);
128623 + spin_unlock_irq(&alloc->lock);
128624 + return -1;
128625 + }
128626 + }
128627 + /* Add the allocation to the used list with a refcount of 1 */
128628 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128629 + if (!used_node) {
128630 + spin_unlock_irq(&alloc->lock);
128631 + return -ENOMEM;
128632 +
128633 + }
128634 + used_node->base = base;
128635 + used_node->num = num;
128636 + used_node->refcount = 1;
128637 + used_node->is_alloced = 0;
128638 + list_add_tail(&used_node->list, &alloc->used);
128639 + spin_unlock_irq(&alloc->lock);
128640 + return 0;
128641 +}
128642 +
128643 +
128644 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
128645 +{
128646 + struct alloc_node *i = NULL;
128647 + DPRINT("alloc_pop()\n");
128648 + DUMP(alloc);
128649 + spin_lock_irq(&alloc->lock);
128650 + if (!list_empty(&alloc->free)) {
128651 + i = list_entry(alloc->free.next, struct alloc_node, list);
128652 + list_del(&i->list);
128653 + }
128654 + spin_unlock_irq(&alloc->lock);
128655 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
128656 + DUMP(alloc);
128657 + if (!i)
128658 + return -ENOMEM;
128659 + *result = i->base;
128660 + *count = i->num;
128661 + kfree(i);
128662 + return 0;
128663 +}
128664 +
128665 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
128666 +{
128667 + struct alloc_node *i = NULL;
128668 + int res = 0;
128669 + DPRINT("alloc_check()\n");
128670 + spin_lock_irq(&list_head->lock);
128671 +
128672 + list_for_each_entry(i, &list_head->free, list) {
128673 + if ((item >= i->base) && (item < (i->base + i->num))) {
128674 + res = 1;
128675 + break;
128676 + }
128677 + }
128678 + spin_unlock_irq(&list_head->lock);
128679 + return res;
128680 +}
128681 --- /dev/null
128682 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
128683 @@ -0,0 +1,259 @@
128684 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
128685 + *
128686 + * Redistribution and use in source and binary forms, with or without
128687 + * modification, are permitted provided that the following conditions are met:
128688 + * * Redistributions of source code must retain the above copyright
128689 + * notice, this list of conditions and the following disclaimer.
128690 + * * Redistributions in binary form must reproduce the above copyright
128691 + * notice, this list of conditions and the following disclaimer in the
128692 + * documentation and/or other materials provided with the distribution.
128693 + * * Neither the name of Freescale Semiconductor nor the
128694 + * names of its contributors may be used to endorse or promote products
128695 + * derived from this software without specific prior written permission.
128696 + *
128697 + *
128698 + * ALTERNATIVELY, this software may be distributed under the terms of the
128699 + * GNU General Public License ("GPL") as published by the Free Software
128700 + * Foundation, either version 2 of that License or (at your option) any
128701 + * later version.
128702 + *
128703 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128704 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128705 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128706 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128707 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128708 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128709 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128710 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128711 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128712 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128713 + */
128714 +
128715 +#ifndef DPA_SYS_H
128716 +#define DPA_SYS_H
128717 +
128718 +#include <linux/kernel.h>
128719 +#include <linux/errno.h>
128720 +#include <linux/io.h>
128721 +#include <linux/dma-mapping.h>
128722 +#include <linux/bootmem.h>
128723 +#include <linux/slab.h>
128724 +#include <linux/module.h>
128725 +#include <linux/init.h>
128726 +#include <linux/interrupt.h>
128727 +#include <linux/delay.h>
128728 +#include <linux/of_platform.h>
128729 +#include <linux/of_address.h>
128730 +#include <linux/of_irq.h>
128731 +#include <linux/kthread.h>
128732 +#include <linux/memblock.h>
128733 +#include <linux/completion.h>
128734 +#include <linux/log2.h>
128735 +#include <linux/types.h>
128736 +#include <linux/ioctl.h>
128737 +#include <linux/miscdevice.h>
128738 +#include <linux/uaccess.h>
128739 +#include <linux/debugfs.h>
128740 +#include <linux/seq_file.h>
128741 +#include <linux/device.h>
128742 +#include <linux/uio_driver.h>
128743 +#include <linux/smp.h>
128744 +#include <linux/fsl_hypervisor.h>
128745 +#include <linux/vmalloc.h>
128746 +#include <linux/ctype.h>
128747 +#include <linux/math64.h>
128748 +#include <linux/bitops.h>
128749 +
128750 +#include <linux/fsl_usdpaa.h>
128751 +
128752 +/* When copying aligned words or shorts, try to avoid memcpy() */
128753 +#define CONFIG_TRY_BETTER_MEMCPY
128754 +
128755 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
128756 +#define DPA_PORTAL_CE 0
128757 +#define DPA_PORTAL_CI 1
128758 +
128759 +/***********************/
128760 +/* Misc inline assists */
128761 +/***********************/
128762 +
128763 +#if defined CONFIG_PPC32
128764 +#include "dpa_sys_ppc32.h"
128765 +#elif defined CONFIG_PPC64
128766 +#include "dpa_sys_ppc64.h"
128767 +#elif defined CONFIG_ARM
128768 +#include "dpa_sys_arm.h"
128769 +#elif defined CONFIG_ARM64
128770 +#include "dpa_sys_arm64.h"
128771 +#endif
128772 +
128773 +
128774 +#ifdef CONFIG_FSL_DPA_CHECKING
128775 +#define DPA_ASSERT(x) \
128776 + do { \
128777 + if (!(x)) { \
128778 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
128779 + __stringify_1(x)); \
128780 + dump_stack(); \
128781 + panic("assertion failure"); \
128782 + } \
128783 + } while (0)
128784 +#else
128785 +#define DPA_ASSERT(x)
128786 +#endif
128787 +
128788 +/* memcpy() stuff - when you know alignments in advance */
128789 +#ifdef CONFIG_TRY_BETTER_MEMCPY
128790 +static inline void copy_words(void *dest, const void *src, size_t sz)
128791 +{
128792 + u32 *__dest = dest;
128793 + const u32 *__src = src;
128794 + size_t __sz = sz >> 2;
128795 + BUG_ON((unsigned long)dest & 0x3);
128796 + BUG_ON((unsigned long)src & 0x3);
128797 + BUG_ON(sz & 0x3);
128798 + while (__sz--)
128799 + *(__dest++) = *(__src++);
128800 +}
128801 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
128802 +{
128803 + u16 *__dest = dest;
128804 + const u16 *__src = src;
128805 + size_t __sz = sz >> 1;
128806 + BUG_ON((unsigned long)dest & 0x1);
128807 + BUG_ON((unsigned long)src & 0x1);
128808 + BUG_ON(sz & 0x1);
128809 + while (__sz--)
128810 + *(__dest++) = *(__src++);
128811 +}
128812 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
128813 +{
128814 + u8 *__dest = dest;
128815 + const u8 *__src = src;
128816 + while (sz--)
128817 + *(__dest++) = *(__src++);
128818 +}
128819 +#else
128820 +#define copy_words memcpy
128821 +#define copy_shorts memcpy
128822 +#define copy_bytes memcpy
128823 +#endif
128824 +
128825 +/************/
128826 +/* RB-trees */
128827 +/************/
128828 +
128829 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
128830 + * non-linux systems. This also encapsulates the extra plumbing that linux code
128831 + * usually provides when using RB-trees. This encapsulation assumes that the
128832 + * data type held by the tree is u32. */
128833 +
128834 +struct dpa_rbtree {
128835 + struct rb_root root;
128836 +};
128837 +#define DPA_RBTREE { .root = RB_ROOT }
128838 +
128839 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
128840 +{
128841 + tree->root = RB_ROOT;
128842 +}
128843 +
128844 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
128845 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
128846 +{ \
128847 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
128848 + while (*p) { \
128849 + u32 item; \
128850 + parent = *p; \
128851 + item = rb_entry(parent, type, node_field)->val_field; \
128852 + if (obj->val_field < item) \
128853 + p = &parent->rb_left; \
128854 + else if (obj->val_field > item) \
128855 + p = &parent->rb_right; \
128856 + else \
128857 + return -EBUSY; \
128858 + } \
128859 + rb_link_node(&obj->node_field, parent, p); \
128860 + rb_insert_color(&obj->node_field, &tree->root); \
128861 + return 0; \
128862 +} \
128863 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
128864 +{ \
128865 + rb_erase(&obj->node_field, &tree->root); \
128866 +} \
128867 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
128868 +{ \
128869 + type *ret; \
128870 + struct rb_node *p = tree->root.rb_node; \
128871 + while (p) { \
128872 + ret = rb_entry(p, type, node_field); \
128873 + if (val < ret->val_field) \
128874 + p = p->rb_left; \
128875 + else if (val > ret->val_field) \
128876 + p = p->rb_right; \
128877 + else \
128878 + return ret; \
128879 + } \
128880 + return NULL; \
128881 +}
128882 +
128883 +/************/
128884 +/* Bootargs */
128885 +/************/
128886 +
128887 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
128888 + * though; a comma-separated list of items, each item being a cpu index and/or a
128889 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
128890 + * that the portal associated with that cpu should be shared. See bman_driver.c
128891 + * for more specifics. */
128892 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
128893 +{
128894 + *cpu = 0;
128895 + if (!isdigit(**s))
128896 + return -EINVAL;
128897 + while (isdigit(**s))
128898 + *cpu = *cpu * 10 + (*((*s)++) - '0');
128899 + return 0;
128900 +}
128901 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
128902 + struct cpumask *want_unshared,
128903 + const char *argname)
128904 +{
128905 + const char *s = str;
128906 + unsigned int shared, cpu1, cpu2, loop;
128907 +
128908 +keep_going:
128909 + if (*s == 's') {
128910 + shared = 1;
128911 + s++;
128912 + } else
128913 + shared = 0;
128914 + if (__parse_portals_cpu(&s, &cpu1))
128915 + goto err;
128916 + if (*s == '-') {
128917 + s++;
128918 + if (__parse_portals_cpu(&s, &cpu2))
128919 + goto err;
128920 + if (cpu2 < cpu1)
128921 + goto err;
128922 + } else
128923 + cpu2 = cpu1;
128924 + for (loop = cpu1; loop <= cpu2; loop++)
128925 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
128926 + if (*s == ',') {
128927 + s++;
128928 + goto keep_going;
128929 + } else if ((*s == '\0') || isspace(*s))
128930 + return 0;
128931 +err:
128932 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
128933 + (unsigned long)s - (unsigned long)str);
128934 + return -EINVAL;
128935 +}
128936 +#ifdef CONFIG_FSL_USDPAA
128937 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
128938 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
128939 + enum usdpaa_portal_type ptype, unsigned int *irq,
128940 + void **iir_reg);
128941 +#endif
128942 +#endif /* DPA_SYS_H */
128943 --- /dev/null
128944 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
128945 @@ -0,0 +1,95 @@
128946 +/* Copyright 2016 Freescale Semiconductor, Inc.
128947 + *
128948 + * Redistribution and use in source and binary forms, with or without
128949 + * modification, are permitted provided that the following conditions are met:
128950 + * * Redistributions of source code must retain the above copyright
128951 + * notice, this list of conditions and the following disclaimer.
128952 + * * Redistributions in binary form must reproduce the above copyright
128953 + * notice, this list of conditions and the following disclaimer in the
128954 + * documentation and/or other materials provided with the distribution.
128955 + * * Neither the name of Freescale Semiconductor nor the
128956 + * names of its contributors may be used to endorse or promote products
128957 + * derived from this software without specific prior written permission.
128958 + *
128959 + *
128960 + * ALTERNATIVELY, this software may be distributed under the terms of the
128961 + * GNU General Public License ("GPL") as published by the Free Software
128962 + * Foundation, either version 2 of that License or (at your option) any
128963 + * later version.
128964 + *
128965 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128966 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128967 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128968 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128969 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128970 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128971 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128972 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128973 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128974 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128975 + */
128976 +
128977 +#ifndef DPA_SYS_ARM_H
128978 +#define DPA_SYS_ARM_H
128979 +
128980 +#include <asm/cacheflush.h>
128981 +#include <asm/barrier.h>
128982 +
128983 +/* Implementation of ARM specific routines */
128984 +
128985 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
128986 + * barriers and that dcb*() won't fall victim to compiler or execution
128987 + * reordering with respect to other code/instructions that manipulate the same
128988 + * cacheline. */
128989 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
128990 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
128991 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
128992 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
128993 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
128994 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
128995 +
128996 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
128997 +
128998 +#define dcbf_64(p) \
128999 + do { \
129000 + dcbf((u32)p); \
129001 + } while (0)
129002 +/* Commonly used combo */
129003 +#define dcbit_ro(p) \
129004 + do { \
129005 + dcbi((u32)p); \
129006 + dcbt_ro((u32)p); \
129007 + } while (0)
129008 +
129009 +static inline u64 mfatb(void)
129010 +{
129011 + return get_cycles();
129012 +}
129013 +
129014 +static inline u32 in_be32(volatile void *addr)
129015 +{
129016 + return be32_to_cpu(*((volatile u32 *) addr));
129017 +}
129018 +
129019 +static inline void out_be32(void *addr, u32 val)
129020 +{
129021 + *((u32 *) addr) = cpu_to_be32(val);
129022 +}
129023 +
129024 +
129025 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129026 +{
129027 + *p |= mask;
129028 +}
129029 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129030 +{
129031 + *p &= ~mask;
129032 +}
129033 +
129034 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129035 +{
129036 + __cpuc_flush_dcache_area((void *) start, stop - start);
129037 +}
129038 +
129039 +#define hard_smp_processor_id() raw_smp_processor_id()
129040 +#endif
129041 --- /dev/null
129042 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129043 @@ -0,0 +1,102 @@
129044 +/* Copyright 2014 Freescale Semiconductor, Inc.
129045 + *
129046 + * Redistribution and use in source and binary forms, with or without
129047 + * modification, are permitted provided that the following conditions are met:
129048 + * * Redistributions of source code must retain the above copyright
129049 + * notice, this list of conditions and the following disclaimer.
129050 + * * Redistributions in binary form must reproduce the above copyright
129051 + * notice, this list of conditions and the following disclaimer in the
129052 + * documentation and/or other materials provided with the distribution.
129053 + * * Neither the name of Freescale Semiconductor nor the
129054 + * names of its contributors may be used to endorse or promote products
129055 + * derived from this software without specific prior written permission.
129056 + *
129057 + *
129058 + * ALTERNATIVELY, this software may be distributed under the terms of the
129059 + * GNU General Public License ("GPL") as published by the Free Software
129060 + * Foundation, either version 2 of that License or (at your option) any
129061 + * later version.
129062 + *
129063 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129064 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129065 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129066 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129067 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129068 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129069 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129070 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129071 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129072 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129073 + */
129074 +
129075 +#ifndef DPA_SYS_ARM64_H
129076 +#define DPA_SYS_ARM64_H
129077 +
129078 +#include <asm/cacheflush.h>
129079 +#include <asm/barrier.h>
129080 +
129081 +/* Implementation of ARM 64 bit specific routines */
129082 +
129083 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129084 + * barriers and that dcb*() won't fall victim to compiler or execution
129085 + * reordering with respect to other code/instructions that manipulate the same
129086 + * cacheline. */
129087 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129088 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129089 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
129090 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
129091 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
129092 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
129093 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
129094 +
129095 +#define dcbz_64(p) \
129096 + do { \
129097 + dcbz(p); \
129098 + } while (0)
129099 +
129100 +#define dcbf_64(p) \
129101 + do { \
129102 + dcbf(p); \
129103 + } while (0)
129104 +/* Commonly used combo */
129105 +#define dcbit_ro(p) \
129106 + do { \
129107 + dcbi(p); \
129108 + dcbt_ro(p); \
129109 + } while (0)
129110 +
129111 +static inline u64 mfatb(void)
129112 +{
129113 + return get_cycles();
129114 +}
129115 +
129116 +static inline u32 in_be32(volatile void *addr)
129117 +{
129118 + return be32_to_cpu(*((volatile u32 *) addr));
129119 +}
129120 +
129121 +static inline void out_be32(void *addr, u32 val)
129122 +{
129123 + *((u32 *) addr) = cpu_to_be32(val);
129124 +}
129125 +
129126 +
129127 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129128 +{
129129 + *p |= mask;
129130 +}
129131 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129132 +{
129133 + *p &= ~mask;
129134 +}
129135 +
129136 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129137 +{
129138 + __flush_dcache_area((void *) start, stop - start);
129139 +}
129140 +
129141 +#define hard_smp_processor_id() raw_smp_processor_id()
129142 +
129143 +
129144 +
129145 +#endif
129146 --- /dev/null
129147 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
129148 @@ -0,0 +1,70 @@
129149 +/* Copyright 2014 Freescale Semiconductor, Inc.
129150 + *
129151 + * Redistribution and use in source and binary forms, with or without
129152 + * modification, are permitted provided that the following conditions are met:
129153 + * * Redistributions of source code must retain the above copyright
129154 + * notice, this list of conditions and the following disclaimer.
129155 + * * Redistributions in binary form must reproduce the above copyright
129156 + * notice, this list of conditions and the following disclaimer in the
129157 + * documentation and/or other materials provided with the distribution.
129158 + * * Neither the name of Freescale Semiconductor nor the
129159 + * names of its contributors may be used to endorse or promote products
129160 + * derived from this software without specific prior written permission.
129161 + *
129162 + *
129163 + * ALTERNATIVELY, this software may be distributed under the terms of the
129164 + * GNU General Public License ("GPL") as published by the Free Software
129165 + * Foundation, either version 2 of that License or (at your option) any
129166 + * later version.
129167 + *
129168 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129169 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129170 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129171 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129172 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129173 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129174 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129175 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129176 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129177 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129178 + */
129179 +
129180 +#ifndef DPA_SYS_PPC32_H
129181 +#define DPA_SYS_PPC32_H
129182 +
129183 +/* Implementation of PowerPC 32 bit specific routines */
129184 +
129185 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129186 + * barriers and that dcb*() won't fall victim to compiler or execution
129187 + * reordering with respect to other code/instructions that manipulate the same
129188 + * cacheline. */
129189 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129190 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129191 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129192 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129193 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129194 +#define dcbi(p) dcbf(p)
129195 +
129196 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
129197 +#define dcbz_64(p) dcbzl(p)
129198 +#define dcbf_64(p) dcbf(p)
129199 +
129200 +/* Commonly used combo */
129201 +#define dcbit_ro(p) \
129202 + do { \
129203 + dcbi(p); \
129204 + dcbt_ro(p); \
129205 + } while (0)
129206 +
129207 +static inline u64 mfatb(void)
129208 +{
129209 + u32 hi, lo, chk;
129210 + do {
129211 + hi = mfspr(SPRN_ATBU);
129212 + lo = mfspr(SPRN_ATBL);
129213 + chk = mfspr(SPRN_ATBU);
129214 + } while (unlikely(hi != chk));
129215 + return ((u64)hi << 32) | (u64)lo;
129216 +}
129217 +
129218 +#endif
129219 --- /dev/null
129220 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
129221 @@ -0,0 +1,79 @@
129222 +/* Copyright 2014 Freescale Semiconductor, Inc.
129223 + *
129224 + * Redistribution and use in source and binary forms, with or without
129225 + * modification, are permitted provided that the following conditions are met:
129226 + * * Redistributions of source code must retain the above copyright
129227 + * notice, this list of conditions and the following disclaimer.
129228 + * * Redistributions in binary form must reproduce the above copyright
129229 + * notice, this list of conditions and the following disclaimer in the
129230 + * documentation and/or other materials provided with the distribution.
129231 + * * Neither the name of Freescale Semiconductor nor the
129232 + * names of its contributors may be used to endorse or promote products
129233 + * derived from this software without specific prior written permission.
129234 + *
129235 + *
129236 + * ALTERNATIVELY, this software may be distributed under the terms of the
129237 + * GNU General Public License ("GPL") as published by the Free Software
129238 + * Foundation, either version 2 of that License or (at your option) any
129239 + * later version.
129240 + *
129241 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129242 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129243 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129244 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129245 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129246 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129247 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129248 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129249 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129250 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129251 + */
129252 +
129253 +#ifndef DPA_SYS_PPC64_H
129254 +#define DPA_SYS_PPC64_H
129255 +
129256 +/* Implementation of PowerPC 64 bit specific routines */
129257 +
129258 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129259 + * barriers and that dcb*() won't fall victim to compiler or execution
129260 + * reordering with respect to other code/instructions that manipulate the same
129261 + * cacheline. */
129262 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129263 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129264 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129265 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129266 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129267 +#define dcbi(p) dcbf(p)
129268 +
129269 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
129270 +#define dcbz_64(p) \
129271 + do { \
129272 + dcbz((void*)p + 32); \
129273 + dcbz(p); \
129274 + } while (0)
129275 +#define dcbf_64(p) \
129276 + do { \
129277 + dcbf((void*)p + 32); \
129278 + dcbf(p); \
129279 + } while (0)
129280 +/* Commonly used combo */
129281 +#define dcbit_ro(p) \
129282 + do { \
129283 + dcbi(p); \
129284 + dcbi((void*)p + 32); \
129285 + dcbt_ro(p); \
129286 + dcbt_ro((void*)p + 32); \
129287 + } while (0)
129288 +
129289 +static inline u64 mfatb(void)
129290 +{
129291 + u32 hi, lo, chk;
129292 + do {
129293 + hi = mfspr(SPRN_ATBU);
129294 + lo = mfspr(SPRN_ATBL);
129295 + chk = mfspr(SPRN_ATBU);
129296 + } while (unlikely(hi != chk));
129297 + return ((u64)hi << 32) | (u64)lo;
129298 +}
129299 +
129300 +#endif
129301 --- /dev/null
129302 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
129303 @@ -0,0 +1,1983 @@
129304 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
129305 + * Authors: Andy Fleming <afleming@freescale.com>
129306 + * Timur Tabi <timur@freescale.com>
129307 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
129308 + *
129309 + * This file is licensed under the terms of the GNU General Public License
129310 + * version 2. This program is licensed "as is" without any warranty of any
129311 + * kind, whether express or implied.
129312 + */
129313 +
129314 +
129315 +#include <linux/miscdevice.h>
129316 +#include <linux/fs.h>
129317 +#include <linux/cdev.h>
129318 +#include <linux/mm.h>
129319 +#include <linux/of.h>
129320 +#include <linux/memblock.h>
129321 +#include <linux/slab.h>
129322 +#include <linux/mman.h>
129323 +#include <linux/of_reserved_mem.h>
129324 +
129325 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
129326 +#include <mm/mmu_decl.h>
129327 +#endif
129328 +
129329 +#include "dpa_sys.h"
129330 +#include <linux/fsl_usdpaa.h>
129331 +#include "bman_low.h"
129332 +#include "qman_low.h"
129333 +
129334 +/* Physical address range of the memory reservation, exported for mm/mem.c */
129335 +static u64 phys_start;
129336 +static u64 phys_size;
129337 +static u64 arg_phys_size;
129338 +
129339 +/* PFN versions of the above */
129340 +static unsigned long pfn_start;
129341 +static unsigned long pfn_size;
129342 +
129343 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
129344 + * isn't atomic_t). */
129345 +static DEFINE_SPINLOCK(mem_lock);
129346 +
129347 +/* The range of TLB1 indices */
129348 +static unsigned int first_tlb;
129349 +static unsigned int num_tlb = 1;
129350 +static unsigned int current_tlb; /* loops around for fault handling */
129351 +
129352 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
129353 + * may be mapped. Unmapped fragments are always merged where possible. */
129354 +static LIST_HEAD(mem_list);
129355 +
129356 +struct mem_mapping;
129357 +
129358 +/* Memory fragments are in 'mem_list'. */
129359 +struct mem_fragment {
129360 + u64 base;
129361 + u64 len;
129362 + unsigned long pfn_base; /* PFN version of 'base' */
129363 + unsigned long pfn_len; /* PFN version of 'len' */
129364 + unsigned int refs; /* zero if unmapped */
129365 + u64 root_len; /* Size of the orignal fragment */
129366 + unsigned long root_pfn; /* PFN of the orignal fragment */
129367 + struct list_head list;
129368 + /* if mapped, flags+name captured at creation time */
129369 + u32 flags;
129370 + char name[USDPAA_DMA_NAME_MAX];
129371 + u64 map_len;
129372 + /* support multi-process locks per-memory-fragment. */
129373 + int has_locking;
129374 + wait_queue_head_t wq;
129375 + struct mem_mapping *owner;
129376 +};
129377 +
129378 +/* Mappings of memory fragments in 'struct ctx'. These are created from
129379 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
129380 + * mmap(). */
129381 +struct mem_mapping {
129382 + struct mem_fragment *root_frag;
129383 + u32 frag_count;
129384 + u64 total_size;
129385 + struct list_head list;
129386 + int refs;
129387 + void *virt_addr;
129388 +};
129389 +
129390 +struct portal_mapping {
129391 + struct usdpaa_ioctl_portal_map user;
129392 + union {
129393 + struct qm_portal_config *qportal;
129394 + struct bm_portal_config *bportal;
129395 + };
129396 + /* Declare space for the portals in case the process
129397 + exits unexpectedly and needs to be cleaned by the kernel */
129398 + union {
129399 + struct qm_portal qman_portal_low;
129400 + struct bm_portal bman_portal_low;
129401 + };
129402 + struct list_head list;
129403 + struct resource *phys;
129404 + struct iommu_domain *iommu_domain;
129405 +};
129406 +
129407 +/* Track the DPAA resources the process is using */
129408 +struct active_resource {
129409 + struct list_head list;
129410 + u32 id;
129411 + u32 num;
129412 + unsigned int refcount;
129413 +};
129414 +
129415 +/* Per-FD state (which should also be per-process but we don't enforce that) */
129416 +struct ctx {
129417 + /* Lock to protect the context */
129418 + spinlock_t lock;
129419 + /* Allocated resources get put here for accounting */
129420 + struct list_head resources[usdpaa_id_max];
129421 + /* list of DMA maps */
129422 + struct list_head maps;
129423 + /* list of portal maps */
129424 + struct list_head portals;
129425 +};
129426 +
129427 +/* Different resource classes */
129428 +static const struct alloc_backend {
129429 + enum usdpaa_id_type id_type;
129430 + int (*alloc)(u32 *, u32, u32, int);
129431 + void (*release)(u32 base, unsigned int count);
129432 + int (*reserve)(u32 base, unsigned int count);
129433 + const char *acronym;
129434 +} alloc_backends[] = {
129435 + {
129436 + .id_type = usdpaa_id_fqid,
129437 + .alloc = qman_alloc_fqid_range,
129438 + .release = qman_release_fqid_range,
129439 + .reserve = qman_reserve_fqid_range,
129440 + .acronym = "FQID"
129441 + },
129442 + {
129443 + .id_type = usdpaa_id_bpid,
129444 + .alloc = bman_alloc_bpid_range,
129445 + .release = bman_release_bpid_range,
129446 + .reserve = bman_reserve_bpid_range,
129447 + .acronym = "BPID"
129448 + },
129449 + {
129450 + .id_type = usdpaa_id_qpool,
129451 + .alloc = qman_alloc_pool_range,
129452 + .release = qman_release_pool_range,
129453 + .reserve = qman_reserve_pool_range,
129454 + .acronym = "QPOOL"
129455 + },
129456 + {
129457 + .id_type = usdpaa_id_cgrid,
129458 + .alloc = qman_alloc_cgrid_range,
129459 + .release = qman_release_cgrid_range,
129460 + .acronym = "CGRID"
129461 + },
129462 + {
129463 + .id_type = usdpaa_id_ceetm0_lfqid,
129464 + .alloc = qman_alloc_ceetm0_lfqid_range,
129465 + .release = qman_release_ceetm0_lfqid_range,
129466 + .acronym = "CEETM0_LFQID"
129467 + },
129468 + {
129469 + .id_type = usdpaa_id_ceetm0_channelid,
129470 + .alloc = qman_alloc_ceetm0_channel_range,
129471 + .release = qman_release_ceetm0_channel_range,
129472 + .acronym = "CEETM0_LFQID"
129473 + },
129474 + {
129475 + .id_type = usdpaa_id_ceetm1_lfqid,
129476 + .alloc = qman_alloc_ceetm1_lfqid_range,
129477 + .release = qman_release_ceetm1_lfqid_range,
129478 + .acronym = "CEETM1_LFQID"
129479 + },
129480 + {
129481 + .id_type = usdpaa_id_ceetm1_channelid,
129482 + .alloc = qman_alloc_ceetm1_channel_range,
129483 + .release = qman_release_ceetm1_channel_range,
129484 + .acronym = "CEETM1_LFQID"
129485 + },
129486 + {
129487 + /* This terminates the array */
129488 + .id_type = usdpaa_id_max
129489 + }
129490 +};
129491 +
129492 +/* Determines the largest acceptable page size for a given size
129493 + The sizes are determined by what the TLB1 acceptable page sizes are */
129494 +static u32 largest_page_size(u32 size)
129495 +{
129496 + int shift = 30; /* Start at 1G size */
129497 + if (size < 4096)
129498 + return 0;
129499 + do {
129500 + if (size >= (1<<shift))
129501 + return 1<<shift;
129502 + shift -= 2;
129503 + } while (shift >= 12); /* Up to 4k */
129504 + return 0;
129505 +}
129506 +
129507 +/* Determine if value is power of 4 */
129508 +static inline bool is_power_of_4(u64 x)
129509 +{
129510 + if (x == 0 || ((x & (x - 1)) != 0))
129511 + return false;
129512 + return !!(x & 0x5555555555555555ull);
129513 +}
129514 +
129515 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
129516 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
129517 + * until it has a suitable fragment size.) */
129518 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
129519 +{
129520 + struct mem_fragment *x[3];
129521 +
129522 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129523 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129524 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129525 + if (!x[0] || !x[1] || !x[2]) {
129526 + kfree(x[0]);
129527 + kfree(x[1]);
129528 + kfree(x[2]);
129529 + return NULL;
129530 + }
129531 + BUG_ON(frag->refs);
129532 + frag->len >>= 2;
129533 + frag->pfn_len >>= 2;
129534 + x[0]->base = frag->base + frag->len;
129535 + x[1]->base = x[0]->base + frag->len;
129536 + x[2]->base = x[1]->base + frag->len;
129537 + x[0]->len = x[1]->len = x[2]->len = frag->len;
129538 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
129539 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
129540 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
129541 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
129542 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
129543 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
129544 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
129545 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
129546 + list_add_tail(&x[0]->list, &frag->list);
129547 + list_add_tail(&x[1]->list, &x[0]->list);
129548 + list_add_tail(&x[2]->list, &x[1]->list);
129549 + return x[2];
129550 +}
129551 +
129552 +static __maybe_unused void dump_frags(void)
129553 +{
129554 + struct mem_fragment *frag;
129555 + int i = 0;
129556 + list_for_each_entry(frag, &mem_list, list) {
129557 + 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",
129558 + i, frag->base, frag->pfn_base,
129559 + frag->len, frag->root_len, frag->root_pfn,
129560 + frag->refs, frag->name);
129561 + ++i;
129562 + }
129563 +}
129564 +
129565 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
129566 +static void compress_frags(void)
129567 +{
129568 + /* Walk the fragment list and combine fragments */
129569 + struct mem_fragment *frag, *nxtfrag;
129570 + u64 len = 0;
129571 +
129572 + int i, numfrags;
129573 +
129574 +
129575 + frag = list_entry(mem_list.next, struct mem_fragment, list);
129576 +
129577 + while (&frag->list != &mem_list) {
129578 + /* Must combine consecutive fragemenst with
129579 + same root_pfn such that they are power of 4 */
129580 + if (frag->refs != 0) {
129581 + frag = list_entry(frag->list.next,
129582 + struct mem_fragment, list);
129583 + continue; /* Not this window */
129584 + }
129585 + len = frag->len;
129586 + numfrags = 0;
129587 + nxtfrag = list_entry(frag->list.next,
129588 + struct mem_fragment, list);
129589 + while (true) {
129590 + if (&nxtfrag->list == &mem_list) {
129591 + numfrags = 0;
129592 + break; /* End of list */
129593 + }
129594 + if (nxtfrag->refs) {
129595 + numfrags = 0;
129596 + break; /* In use still */
129597 + }
129598 + if (nxtfrag->root_pfn != frag->root_pfn) {
129599 + numfrags = 0;
129600 + break; /* Crosses root fragment boundary */
129601 + }
129602 + len += nxtfrag->len;
129603 + numfrags++;
129604 + if (is_power_of_4(len)) {
129605 + /* These fragments can be combined */
129606 + break;
129607 + }
129608 + nxtfrag = list_entry(nxtfrag->list.next,
129609 + struct mem_fragment, list);
129610 + }
129611 + if (numfrags == 0) {
129612 + frag = list_entry(frag->list.next,
129613 + struct mem_fragment, list);
129614 + continue; /* try the next window */
129615 + }
129616 + for (i = 0; i < numfrags; i++) {
129617 + struct mem_fragment *todel =
129618 + list_entry(nxtfrag->list.prev,
129619 + struct mem_fragment, list);
129620 + nxtfrag->len += todel->len;
129621 + nxtfrag->pfn_len += todel->pfn_len;
129622 + list_del(&todel->list);
129623 + }
129624 + /* Re evaluate the list, things may merge now */
129625 + frag = list_entry(mem_list.next, struct mem_fragment, list);
129626 + }
129627 +}
129628 +
129629 +/* Hook from arch/powerpc/mm/mem.c */
129630 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
129631 +{
129632 + struct mem_fragment *frag;
129633 + int idx = -1;
129634 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
129635 + return -1;
129636 + /* It's in-range, we need to find the fragment */
129637 + spin_lock(&mem_lock);
129638 + list_for_each_entry(frag, &mem_list, list) {
129639 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
129640 + frag->pfn_len))) {
129641 + *phys_addr = frag->base;
129642 + *size = frag->len;
129643 + idx = current_tlb++;
129644 + if (current_tlb >= (first_tlb + num_tlb))
129645 + current_tlb = first_tlb;
129646 + break;
129647 + }
129648 + }
129649 + spin_unlock(&mem_lock);
129650 + return idx;
129651 +}
129652 +
129653 +static int usdpaa_open(struct inode *inode, struct file *filp)
129654 +{
129655 + const struct alloc_backend *backend = &alloc_backends[0];
129656 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
129657 + if (!ctx)
129658 + return -ENOMEM;
129659 + filp->private_data = ctx;
129660 +
129661 + while (backend->id_type != usdpaa_id_max) {
129662 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
129663 + backend++;
129664 + }
129665 +
129666 + INIT_LIST_HEAD(&ctx->maps);
129667 + INIT_LIST_HEAD(&ctx->portals);
129668 + spin_lock_init(&ctx->lock);
129669 +
129670 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
129671 +
129672 + return 0;
129673 +}
129674 +
129675 +#define DQRR_MAXFILL 15
129676 +
129677 +/* Reset a QMan portal to its default state */
129678 +static int init_qm_portal(struct qm_portal_config *config,
129679 + struct qm_portal *portal)
129680 +{
129681 + const struct qm_dqrr_entry *dqrr = NULL;
129682 + int i;
129683 +
129684 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
129685 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
129686 +
129687 + /* Make sure interrupts are inhibited */
129688 + qm_out(IIR, 1);
129689 +
129690 + /* Initialize the DQRR. This will stop any dequeue
129691 + commands that are in progress */
129692 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
129693 + qm_dqrr_cdc, DQRR_MAXFILL)) {
129694 + pr_err("qm_dqrr_init() failed when trying to"
129695 + " recover portal, portal will be leaked\n");
129696 + return 1;
129697 + }
129698 +
129699 + /* Discard any entries on the DQRR */
129700 + /* If we consume the ring twice something is wrong */
129701 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
129702 + qm_dqrr_pvb_update(portal);
129703 + dqrr = qm_dqrr_current(portal);
129704 + if (!dqrr)
129705 + break;
129706 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
129707 + qm_dqrr_pvb_update(portal);
129708 + qm_dqrr_next(portal);
129709 + }
129710 + /* Initialize the EQCR */
129711 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
129712 + qm_eqcr_get_ci_stashing(portal), 1)) {
129713 + pr_err("Qman EQCR initialisation failed\n");
129714 + return 1;
129715 + }
129716 + /* initialize the MR */
129717 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
129718 + pr_err("Qman MR initialisation failed\n");
129719 + return 1;
129720 + }
129721 + qm_mr_pvb_update(portal);
129722 + while (qm_mr_current(portal)) {
129723 + qm_mr_next(portal);
129724 + qm_mr_cci_consume_to_current(portal);
129725 + qm_mr_pvb_update(portal);
129726 + }
129727 +
129728 + if (qm_mc_init(portal)) {
129729 + pr_err("Qman MC initialisation failed\n");
129730 + return 1;
129731 + }
129732 + return 0;
129733 +}
129734 +
129735 +static int init_bm_portal(struct bm_portal_config *config,
129736 + struct bm_portal *portal)
129737 +{
129738 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
129739 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
129740 +
129741 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
129742 + pr_err("Bman RCR initialisation failed\n");
129743 + return 1;
129744 + }
129745 + if (bm_mc_init(portal)) {
129746 + pr_err("Bman MC initialisation failed\n");
129747 + return 1;
129748 + }
129749 + return 0;
129750 +}
129751 +
129752 +/* Function that will scan all FQ's in the system. For each FQ that is not
129753 + OOS it will call the check_channel helper to determine if the FQ should
129754 + be torn down. If the check_channel helper returns true the FQ will be
129755 + transitioned to the OOS state */
129756 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
129757 + bool (*check_channel)(void*, u32))
129758 +{
129759 + u32 fq_id = 0;
129760 + while (1) {
129761 + struct qm_mc_command *mcc;
129762 + struct qm_mc_result *mcr;
129763 + u8 state;
129764 + u32 channel;
129765 +
129766 + /* Determine the channel for the FQID */
129767 + mcc = qm_mc_start(portal);
129768 + mcc->queryfq.fqid = fq_id;
129769 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
129770 + while (!(mcr = qm_mc_result(portal)))
129771 + cpu_relax();
129772 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
129773 + == QM_MCR_VERB_QUERYFQ);
129774 + if (mcr->result != QM_MCR_RESULT_OK)
129775 + break; /* End of valid FQIDs */
129776 +
129777 + channel = mcr->queryfq.fqd.dest.channel;
129778 + /* Determine the state of the FQID */
129779 + mcc = qm_mc_start(portal);
129780 + mcc->queryfq_np.fqid = fq_id;
129781 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
129782 + while (!(mcr = qm_mc_result(portal)))
129783 + cpu_relax();
129784 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
129785 + == QM_MCR_VERB_QUERYFQ_NP);
129786 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
129787 + if (state == QM_MCR_NP_STATE_OOS)
129788 + /* Already OOS, no need to do anymore checks */
129789 + goto next;
129790 +
129791 + if (check_channel(ctx, channel))
129792 + qm_shutdown_fq(&portal, 1, fq_id);
129793 + next:
129794 + ++fq_id;
129795 + }
129796 + return 0;
129797 +}
129798 +
129799 +static bool check_channel_device(void *_ctx, u32 channel)
129800 +{
129801 + struct ctx *ctx = _ctx;
129802 + struct portal_mapping *portal, *tmpportal;
129803 + struct active_resource *res;
129804 +
129805 + /* See if the FQ is destined for one of the portals we're cleaning up */
129806 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
129807 + if (portal->user.type == usdpaa_portal_qman) {
129808 + if (portal->qportal->public_cfg.channel == channel) {
129809 + /* This FQs destination is a portal
129810 + we're cleaning, send a retire */
129811 + return true;
129812 + }
129813 + }
129814 + }
129815 +
129816 + /* Check the pool channels that will be released as well */
129817 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
129818 + if ((res->id >= channel) &&
129819 + ((res->id + res->num - 1) <= channel))
129820 + return true;
129821 + }
129822 + return false;
129823 +}
129824 +
129825 +static bool check_portal_channel(void *ctx, u32 channel)
129826 +{
129827 + u32 portal_channel = *(u32 *)ctx;
129828 + if (portal_channel == channel) {
129829 + /* This FQs destination is a portal
129830 + we're cleaning, send a retire */
129831 + return true;
129832 + }
129833 + return false;
129834 +}
129835 +
129836 +
129837 +
129838 +
129839 +static int usdpaa_release(struct inode *inode, struct file *filp)
129840 +{
129841 + struct ctx *ctx = filp->private_data;
129842 + struct mem_mapping *map, *tmpmap;
129843 + struct portal_mapping *portal, *tmpportal;
129844 + const struct alloc_backend *backend = &alloc_backends[0];
129845 + struct active_resource *res;
129846 + struct qm_portal *qm_cleanup_portal = NULL;
129847 + struct bm_portal *bm_cleanup_portal = NULL;
129848 + struct qm_portal_config *qm_alloced_portal = NULL;
129849 + struct bm_portal_config *bm_alloced_portal = NULL;
129850 +
129851 + struct qm_portal *portal_array[qman_portal_max];
129852 + int portal_count = 0;
129853 +
129854 + /* Ensure the release operation cannot be migrated to another
129855 + CPU as CPU specific variables may be needed during cleanup */
129856 +#ifdef CONFIG_PREEMPT_RT_FULL
129857 + migrate_disable();
129858 +#endif
129859 + /* The following logic is used to recover resources that were not
129860 + correctly released by the process that is closing the FD.
129861 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
129862 + in the kernel
129863 + */
129864 +
129865 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
129866 + /* Try to recover any portals that weren't shut down */
129867 + if (portal->user.type == usdpaa_portal_qman) {
129868 + portal_array[portal_count] = &portal->qman_portal_low;
129869 + ++portal_count;
129870 + init_qm_portal(portal->qportal,
129871 + &portal->qman_portal_low);
129872 + if (!qm_cleanup_portal) {
129873 + qm_cleanup_portal = &portal->qman_portal_low;
129874 + } else {
129875 + /* Clean FQs on the dedicated channel */
129876 + u32 chan = portal->qportal->public_cfg.channel;
129877 + qm_check_and_destroy_fqs(
129878 + &portal->qman_portal_low, &chan,
129879 + check_portal_channel);
129880 + }
129881 + } else {
129882 + /* BMAN */
129883 + init_bm_portal(portal->bportal,
129884 + &portal->bman_portal_low);
129885 + if (!bm_cleanup_portal)
129886 + bm_cleanup_portal = &portal->bman_portal_low;
129887 + }
129888 + }
129889 + /* If no portal was found, allocate one for cleanup */
129890 + if (!qm_cleanup_portal) {
129891 + qm_alloced_portal = qm_get_unused_portal();
129892 + if (!qm_alloced_portal) {
129893 + pr_crit("No QMan portal avalaible for cleanup\n");
129894 +#ifdef CONFIG_PREEMPT_RT_FULL
129895 + migrate_enable();
129896 +#endif
129897 + return -1;
129898 + }
129899 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
129900 + GFP_KERNEL);
129901 + if (!qm_cleanup_portal) {
129902 +#ifdef CONFIG_PREEMPT_RT_FULL
129903 + migrate_enable();
129904 +#endif
129905 + return -ENOMEM;
129906 + }
129907 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
129908 + portal_array[portal_count] = qm_cleanup_portal;
129909 + ++portal_count;
129910 + }
129911 + if (!bm_cleanup_portal) {
129912 + bm_alloced_portal = bm_get_unused_portal();
129913 + if (!bm_alloced_portal) {
129914 + pr_crit("No BMan portal avalaible for cleanup\n");
129915 +#ifdef CONFIG_PREEMPT_RT_FULL
129916 + migrate_enable();
129917 +#endif
129918 + return -1;
129919 + }
129920 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
129921 + GFP_KERNEL);
129922 + if (!bm_cleanup_portal) {
129923 +#ifdef CONFIG_PREEMPT_RT_FULL
129924 + migrate_enable();
129925 +#endif
129926 + return -ENOMEM;
129927 + }
129928 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
129929 + }
129930 +
129931 + /* OOS the FQs associated with this process */
129932 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
129933 +
129934 + while (backend->id_type != usdpaa_id_max) {
129935 + int leaks = 0;
129936 + list_for_each_entry(res, &ctx->resources[backend->id_type],
129937 + list) {
129938 + if (backend->id_type == usdpaa_id_fqid) {
129939 + int i = 0;
129940 + for (; i < res->num; i++) {
129941 + /* Clean FQs with the cleanup portal */
129942 + qm_shutdown_fq(portal_array,
129943 + portal_count,
129944 + res->id + i);
129945 + }
129946 + }
129947 + leaks += res->num;
129948 + backend->release(res->id, res->num);
129949 + }
129950 + if (leaks)
129951 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
129952 + backend->acronym, (leaks > 1) ? "s" : "");
129953 + backend++;
129954 + }
129955 + /* Release any DMA regions */
129956 + spin_lock(&mem_lock);
129957 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
129958 + struct mem_fragment *current_frag = map->root_frag;
129959 + int i;
129960 + if (map->root_frag->has_locking &&
129961 + (map->root_frag->owner == map)) {
129962 + map->root_frag->owner = NULL;
129963 + wake_up(&map->root_frag->wq);
129964 + }
129965 + /* Check each fragment and merge if the ref count is 0 */
129966 + for (i = 0; i < map->frag_count; i++) {
129967 + --current_frag->refs;
129968 + current_frag = list_entry(current_frag->list.prev,
129969 + struct mem_fragment, list);
129970 + }
129971 +
129972 + compress_frags();
129973 + list_del(&map->list);
129974 + kfree(map);
129975 + }
129976 + spin_unlock(&mem_lock);
129977 +
129978 + /* Return portals */
129979 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
129980 + if (portal->user.type == usdpaa_portal_qman) {
129981 + /* Give the portal back to the allocator */
129982 + init_qm_portal(portal->qportal,
129983 + &portal->qman_portal_low);
129984 + qm_put_unused_portal(portal->qportal);
129985 + } else {
129986 + init_bm_portal(portal->bportal,
129987 + &portal->bman_portal_low);
129988 + bm_put_unused_portal(portal->bportal);
129989 + }
129990 + list_del(&portal->list);
129991 + kfree(portal);
129992 + }
129993 + if (qm_alloced_portal) {
129994 + qm_put_unused_portal(qm_alloced_portal);
129995 + kfree(qm_cleanup_portal);
129996 + }
129997 + if (bm_alloced_portal) {
129998 + bm_put_unused_portal(bm_alloced_portal);
129999 + kfree(bm_cleanup_portal);
130000 + }
130001 +
130002 + kfree(ctx);
130003 +#ifdef CONFIG_PREEMPT_RT_FULL
130004 + migrate_enable();
130005 +#endif
130006 + return 0;
130007 +}
130008 +
130009 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
130010 + int *match, unsigned long *pfn)
130011 +{
130012 + struct mem_mapping *map;
130013 +
130014 + list_for_each_entry(map, &ctx->maps, list) {
130015 + int i;
130016 + struct mem_fragment *frag = map->root_frag;
130017 +
130018 + for (i = 0; i < map->frag_count; i++) {
130019 + if (frag->pfn_base == vma->vm_pgoff) {
130020 + *match = 1;
130021 + *pfn = frag->pfn_base;
130022 + return 0;
130023 + }
130024 + frag = list_entry(frag->list.next, struct mem_fragment,
130025 + list);
130026 + }
130027 + }
130028 + *match = 0;
130029 + return 0;
130030 +}
130031 +
130032 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
130033 + int *match, unsigned long *pfn)
130034 +{
130035 + *pfn = res->start >> PAGE_SHIFT;
130036 + if (*pfn == vma->vm_pgoff) {
130037 + *match = 1;
130038 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
130039 + return -EINVAL;
130040 + } else
130041 + *match = 0;
130042 + return 0;
130043 +}
130044 +
130045 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
130046 + int *match, unsigned long *pfn)
130047 +{
130048 + struct portal_mapping *portal;
130049 + int ret;
130050 +
130051 + list_for_each_entry(portal, &ctx->portals, list) {
130052 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
130053 + match, pfn);
130054 + if (*match) {
130055 + vma->vm_page_prot =
130056 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
130057 + pgprot_cached_ns(vma->vm_page_prot);
130058 +#else
130059 + pgprot_cached_noncoherent(vma->vm_page_prot);
130060 +#endif
130061 + return ret;
130062 + }
130063 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
130064 + match, pfn);
130065 + if (*match) {
130066 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
130067 + return ret;
130068 + }
130069 + }
130070 + *match = 0;
130071 + return 0;
130072 +}
130073 +
130074 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
130075 +{
130076 + struct ctx *ctx = filp->private_data;
130077 + unsigned long pfn = 0;
130078 + int match, ret;
130079 +
130080 + spin_lock(&mem_lock);
130081 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
130082 + if (!match)
130083 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
130084 + spin_unlock(&mem_lock);
130085 + if (!match)
130086 + return -EINVAL;
130087 + if (!ret)
130088 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
130089 + vma->vm_end - vma->vm_start,
130090 + vma->vm_page_prot);
130091 + return ret;
130092 +}
130093 +
130094 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
130095 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
130096 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
130097 + ({ \
130098 + unsigned long foo_align = (sz) - 1; \
130099 + ((addr) + foo_align) & ~foo_align; \
130100 + })
130101 +/* Searching for a size-aligned virtual address range starting from 'addr' */
130102 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
130103 + unsigned long addr,
130104 + unsigned long len,
130105 + unsigned long pgoff,
130106 + unsigned long flags)
130107 +{
130108 + struct vm_area_struct *vma;
130109 +
130110 + if (len % PAGE_SIZE)
130111 + return -EINVAL;
130112 + if (!len)
130113 + return -EINVAL;
130114 +
130115 + /* Need to align the address to the largest pagesize of the mapping
130116 + * because the MMU requires the virtual address to have the same
130117 + * alignment as the physical address */
130118 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
130119 + vma = find_vma(current->mm, addr);
130120 + /* Keep searching until we reach the end of currently-used virtual
130121 + * address-space or we find a big enough gap. */
130122 + while (vma) {
130123 + if ((addr + len) < vma->vm_start)
130124 + return addr;
130125 +
130126 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
130127 + vma = vma->vm_next;
130128 + }
130129 + if ((TASK_SIZE - len) < addr)
130130 + return -ENOMEM;
130131 + return addr;
130132 +}
130133 +
130134 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
130135 +{
130136 + struct usdpaa_ioctl_id_alloc i;
130137 + const struct alloc_backend *backend;
130138 + struct active_resource *res;
130139 + int ret = copy_from_user(&i, arg, sizeof(i));
130140 + if (ret)
130141 + return ret;
130142 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130143 + return -EINVAL;
130144 + backend = &alloc_backends[i.id_type];
130145 + /* Allocate the required resource type */
130146 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
130147 + if (ret < 0)
130148 + return ret;
130149 + i.num = ret;
130150 + /* Copy the result to user-space */
130151 + ret = copy_to_user(arg, &i, sizeof(i));
130152 + if (ret) {
130153 + backend->release(i.base, i.num);
130154 + return ret;
130155 + }
130156 + /* Assign the allocated range to the FD accounting */
130157 + res = kmalloc(sizeof(*res), GFP_KERNEL);
130158 + if (!res) {
130159 + backend->release(i.base, i.num);
130160 + return -ENOMEM;
130161 + }
130162 + spin_lock(&ctx->lock);
130163 + res->id = i.base;
130164 + res->num = i.num;
130165 + res->refcount = 1;
130166 + list_add(&res->list, &ctx->resources[i.id_type]);
130167 + spin_unlock(&ctx->lock);
130168 + return 0;
130169 +}
130170 +
130171 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
130172 +{
130173 + struct usdpaa_ioctl_id_release i;
130174 + const struct alloc_backend *backend;
130175 + struct active_resource *tmp, *pos;
130176 +
130177 + int ret = copy_from_user(&i, arg, sizeof(i));
130178 + if (ret)
130179 + return ret;
130180 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130181 + return -EINVAL;
130182 + backend = &alloc_backends[i.id_type];
130183 + /* Pull the range out of the FD accounting - the range is valid iff this
130184 + * succeeds. */
130185 + spin_lock(&ctx->lock);
130186 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130187 + if (pos->id == i.base && pos->num == i.num) {
130188 + pos->refcount--;
130189 + if (pos->refcount) {
130190 + spin_unlock(&ctx->lock);
130191 + return 0; /* Still being used */
130192 + }
130193 + list_del(&pos->list);
130194 + kfree(pos);
130195 + spin_unlock(&ctx->lock);
130196 + goto found;
130197 + }
130198 + }
130199 + /* Failed to find the resource */
130200 + spin_unlock(&ctx->lock);
130201 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
130202 + i.id_type, i.base, i.num);
130203 + return -EINVAL;
130204 +found:
130205 + /* Release the resource to the backend */
130206 + backend->release(i.base, i.num);
130207 + return 0;
130208 +}
130209 +
130210 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
130211 +{
130212 + struct usdpaa_ioctl_id_reserve i;
130213 + const struct alloc_backend *backend;
130214 + struct active_resource *tmp, *pos;
130215 +
130216 + int ret = copy_from_user(&i, arg, sizeof(i));
130217 + if (ret)
130218 + return ret;
130219 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130220 + return -EINVAL;
130221 + backend = &alloc_backends[i.id_type];
130222 + if (!backend->reserve)
130223 + return -EINVAL;
130224 + /* Pull the range out of the FD accounting - the range is valid iff this
130225 + * succeeds. */
130226 + spin_lock(&ctx->lock);
130227 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130228 + if (pos->id == i.base && pos->num == i.num) {
130229 + pos->refcount++;
130230 + spin_unlock(&ctx->lock);
130231 + return 0;
130232 + }
130233 + }
130234 +
130235 + /* Failed to find the resource */
130236 + spin_unlock(&ctx->lock);
130237 +
130238 + /* Reserve the resource in the backend */
130239 + ret = backend->reserve(i.base, i.num);
130240 + if (ret)
130241 + return ret;
130242 + /* Assign the reserved range to the FD accounting */
130243 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
130244 + if (!pos) {
130245 + backend->release(i.base, i.num);
130246 + return -ENOMEM;
130247 + }
130248 + spin_lock(&ctx->lock);
130249 + pos->id = i.base;
130250 + pos->num = i.num;
130251 + pos->refcount = 1;
130252 + list_add(&pos->list, &ctx->resources[i.id_type]);
130253 + spin_unlock(&ctx->lock);
130254 + return 0;
130255 +}
130256 +
130257 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
130258 + struct usdpaa_ioctl_dma_map *i)
130259 +{
130260 + struct mem_fragment *frag, *start_frag, *next_frag;
130261 + struct mem_mapping *map, *tmp;
130262 + int ret = 0;
130263 + u32 largest_page, so_far = 0;
130264 + int frag_count = 0;
130265 + unsigned long next_addr = PAGE_SIZE, populate;
130266 +
130267 + /* error checking to ensure values copied from user space are valid */
130268 + if (i->len % PAGE_SIZE)
130269 + return -EINVAL;
130270 +
130271 + map = kmalloc(sizeof(*map), GFP_KERNEL);
130272 + if (!map)
130273 + return -ENOMEM;
130274 +
130275 + spin_lock(&mem_lock);
130276 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
130277 + list_for_each_entry(frag, &mem_list, list) {
130278 + if (frag->refs && (frag->flags &
130279 + USDPAA_DMA_FLAG_SHARE) &&
130280 + !strncmp(i->name, frag->name,
130281 + USDPAA_DMA_NAME_MAX)) {
130282 + /* Matching entry */
130283 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
130284 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
130285 + ret = -EBUSY;
130286 + goto out;
130287 + }
130288 +
130289 + /* Check to ensure size matches record */
130290 + if (i->len != frag->map_len && i->len) {
130291 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
130292 + frag->name);
130293 + return -EINVAL;
130294 + }
130295 +
130296 + /* Check if this has already been mapped
130297 + to this process */
130298 + list_for_each_entry(tmp, &ctx->maps, list)
130299 + if (tmp->root_frag == frag) {
130300 + /* Already mapped, just need to
130301 + inc ref count */
130302 + tmp->refs++;
130303 + kfree(map);
130304 + i->did_create = 0;
130305 + i->len = tmp->total_size;
130306 + i->phys_addr = frag->base;
130307 + i->ptr = tmp->virt_addr;
130308 + spin_unlock(&mem_lock);
130309 + return 0;
130310 + }
130311 + /* Matching entry - just need to map */
130312 + i->has_locking = frag->has_locking;
130313 + i->did_create = 0;
130314 + i->len = frag->map_len;
130315 + start_frag = frag;
130316 + goto do_map;
130317 + }
130318 + }
130319 + /* No matching entry */
130320 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
130321 + pr_err("ioctl_dma_map() No matching entry\n");
130322 + ret = -ENOMEM;
130323 + goto out;
130324 + }
130325 + }
130326 + /* New fragment required, size must be provided. */
130327 + if (!i->len) {
130328 + ret = -EINVAL;
130329 + goto out;
130330 + }
130331 +
130332 + /* Find one of more contiguous fragments that satisfy the total length
130333 + trying to minimize the number of fragments
130334 + compute the largest page size that the allocation could use */
130335 + largest_page = largest_page_size(i->len);
130336 + start_frag = NULL;
130337 + while (largest_page &&
130338 + largest_page <= largest_page_size(phys_size) &&
130339 + start_frag == NULL) {
130340 + /* Search the list for a frag of that size */
130341 + list_for_each_entry(frag, &mem_list, list) {
130342 + if (!frag->refs && (frag->len == largest_page)) {
130343 + /* See if the next x fragments are free
130344 + and can accomidate the size */
130345 + u32 found_size = largest_page;
130346 + next_frag = list_entry(frag->list.prev,
130347 + struct mem_fragment,
130348 + list);
130349 + /* If the fragement is too small check
130350 + if the neighbours cab support it */
130351 + while (found_size < i->len) {
130352 + if (&mem_list == &next_frag->list)
130353 + break; /* End of list */
130354 + if (next_frag->refs != 0 ||
130355 + next_frag->len == 0)
130356 + break; /* not enough space */
130357 + found_size += next_frag->len;
130358 + next_frag = list_entry(
130359 + next_frag->list.prev,
130360 + struct mem_fragment,
130361 + list);
130362 + }
130363 + if (found_size >= i->len) {
130364 + /* Success! there is enough contigous
130365 + free space */
130366 + start_frag = frag;
130367 + break;
130368 + }
130369 + }
130370 + } /* next frag loop */
130371 + /* Couldn't statisfy the request with this
130372 + largest page size, try a smaller one */
130373 + largest_page <<= 2;
130374 + }
130375 + if (start_frag == NULL) {
130376 + /* Couldn't find proper amount of space */
130377 + ret = -ENOMEM;
130378 + goto out;
130379 + }
130380 + i->did_create = 1;
130381 +do_map:
130382 + /* Verify there is sufficient space to do the mapping */
130383 + down_write(&current->mm->mmap_sem);
130384 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
130385 + up_write(&current->mm->mmap_sem);
130386 +
130387 + if (next_addr & ~PAGE_MASK) {
130388 + ret = -ENOMEM;
130389 + goto out;
130390 + }
130391 +
130392 + /* We may need to divide the final fragment to accomidate the mapping */
130393 + next_frag = start_frag;
130394 + while (so_far != i->len) {
130395 + BUG_ON(next_frag->len == 0);
130396 + while ((next_frag->len + so_far) > i->len) {
130397 + /* Split frag until they match */
130398 + split_frag(next_frag);
130399 + }
130400 + so_far += next_frag->len;
130401 + next_frag->refs++;
130402 + ++frag_count;
130403 + next_frag = list_entry(next_frag->list.prev,
130404 + struct mem_fragment, list);
130405 + }
130406 + if (i->did_create) {
130407 + size_t name_len = 0;
130408 + start_frag->flags = i->flags;
130409 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
130410 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
130411 + if (name_len >= USDPAA_DMA_NAME_MAX) {
130412 + ret = -EFAULT;
130413 + goto out;
130414 + }
130415 + start_frag->map_len = i->len;
130416 + start_frag->has_locking = i->has_locking;
130417 + init_waitqueue_head(&start_frag->wq);
130418 + start_frag->owner = NULL;
130419 + }
130420 +
130421 + /* Setup the map entry */
130422 + map->root_frag = start_frag;
130423 + map->total_size = i->len;
130424 + map->frag_count = frag_count;
130425 + map->refs = 1;
130426 + list_add(&map->list, &ctx->maps);
130427 + i->phys_addr = start_frag->base;
130428 +out:
130429 + spin_unlock(&mem_lock);
130430 +
130431 + if (!ret) {
130432 + unsigned long longret;
130433 + down_write(&current->mm->mmap_sem);
130434 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
130435 + PROT_READ |
130436 + (i->flags &
130437 + USDPAA_DMA_FLAG_RDONLY ? 0
130438 + : PROT_WRITE),
130439 + MAP_SHARED,
130440 + start_frag->pfn_base,
130441 + &populate);
130442 + up_write(&current->mm->mmap_sem);
130443 + if (longret & ~PAGE_MASK) {
130444 + ret = (int)longret;
130445 + } else {
130446 + i->ptr = (void *)longret;
130447 + map->virt_addr = i->ptr;
130448 + }
130449 + } else
130450 + kfree(map);
130451 + return ret;
130452 +}
130453 +
130454 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
130455 +{
130456 + struct mem_mapping *map;
130457 + struct vm_area_struct *vma;
130458 + int ret, i;
130459 + struct mem_fragment *current_frag;
130460 + size_t sz;
130461 + unsigned long base;
130462 + unsigned long vaddr;
130463 +
130464 + down_write(&current->mm->mmap_sem);
130465 + vma = find_vma(current->mm, (unsigned long)arg);
130466 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130467 + up_write(&current->mm->mmap_sem);
130468 + return -EFAULT;
130469 + }
130470 + spin_lock(&mem_lock);
130471 + list_for_each_entry(map, &ctx->maps, list) {
130472 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130473 + /* Drop the map lock if we hold it */
130474 + if (map->root_frag->has_locking &&
130475 + (map->root_frag->owner == map)) {
130476 + map->root_frag->owner = NULL;
130477 + wake_up(&map->root_frag->wq);
130478 + }
130479 + goto map_match;
130480 + }
130481 + }
130482 + /* Failed to find a matching mapping for this process */
130483 + ret = -EFAULT;
130484 + spin_unlock(&mem_lock);
130485 + goto out;
130486 +map_match:
130487 + map->refs--;
130488 + if (map->refs != 0) {
130489 + /* Another call the dma_map is referencing this */
130490 + ret = 0;
130491 + spin_unlock(&mem_lock);
130492 + goto out;
130493 + }
130494 +
130495 + current_frag = map->root_frag;
130496 + vaddr = (unsigned long) map->virt_addr;
130497 + for (i = 0; i < map->frag_count; i++) {
130498 + DPA_ASSERT(current_frag->refs > 0);
130499 + --current_frag->refs;
130500 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
130501 + /*
130502 + * Make sure we invalidate the TLB entry for
130503 + * this fragment, otherwise a remap of a different
130504 + * page to this vaddr would give acces to an
130505 + * incorrect piece of memory
130506 + */
130507 + cleartlbcam(vaddr, mfspr(SPRN_PID));
130508 +#endif
130509 + vaddr += current_frag->len;
130510 + current_frag = list_entry(current_frag->list.prev,
130511 + struct mem_fragment, list);
130512 + }
130513 + map->root_frag->name[0] = 0;
130514 + list_del(&map->list);
130515 + compress_frags();
130516 + spin_unlock(&mem_lock);
130517 +
130518 + base = vma->vm_start;
130519 + sz = vma->vm_end - vma->vm_start;
130520 + do_munmap(current->mm, base, sz);
130521 + ret = 0;
130522 + out:
130523 + up_write(&current->mm->mmap_sem);
130524 + return ret;
130525 +}
130526 +
130527 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
130528 +{
130529 + struct mem_fragment *frag;
130530 + struct usdpaa_ioctl_dma_used result;
130531 +
130532 + result.free_bytes = 0;
130533 + result.total_bytes = phys_size;
130534 +
130535 + list_for_each_entry(frag, &mem_list, list) {
130536 + if (frag->refs == 0)
130537 + result.free_bytes += frag->len;
130538 + }
130539 +
130540 + return copy_to_user(arg, &result, sizeof(result)); }
130541 +
130542 +static int test_lock(struct mem_mapping *map)
130543 +{
130544 + int ret = 0;
130545 + spin_lock(&mem_lock);
130546 + if (!map->root_frag->owner) {
130547 + map->root_frag->owner = map;
130548 + ret = 1;
130549 + }
130550 + spin_unlock(&mem_lock);
130551 + return ret;
130552 +}
130553 +
130554 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
130555 +{
130556 + struct mem_mapping *map;
130557 + struct vm_area_struct *vma;
130558 +
130559 + down_read(&current->mm->mmap_sem);
130560 + vma = find_vma(current->mm, (unsigned long)arg);
130561 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130562 + up_read(&current->mm->mmap_sem);
130563 + return -EFAULT;
130564 + }
130565 + spin_lock(&mem_lock);
130566 + list_for_each_entry(map, &ctx->maps, list) {
130567 + if (map->root_frag->pfn_base == vma->vm_pgoff)
130568 + goto map_match;
130569 + }
130570 + map = NULL;
130571 +map_match:
130572 + spin_unlock(&mem_lock);
130573 + up_read(&current->mm->mmap_sem);
130574 +
130575 + if (!map)
130576 + return -EFAULT;
130577 + if (!map->root_frag->has_locking)
130578 + return -ENODEV;
130579 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
130580 +}
130581 +
130582 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
130583 +{
130584 + struct mem_mapping *map;
130585 + struct vm_area_struct *vma;
130586 + int ret;
130587 +
130588 + down_read(&current->mm->mmap_sem);
130589 + vma = find_vma(current->mm, (unsigned long)arg);
130590 + if (!vma || (vma->vm_start > (unsigned long)arg))
130591 + ret = -EFAULT;
130592 + else {
130593 + spin_lock(&mem_lock);
130594 + list_for_each_entry(map, &ctx->maps, list) {
130595 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130596 + if (!map->root_frag->has_locking)
130597 + ret = -ENODEV;
130598 + else if (map->root_frag->owner == map) {
130599 + map->root_frag->owner = NULL;
130600 + wake_up(&map->root_frag->wq);
130601 + ret = 0;
130602 + } else
130603 + ret = -EBUSY;
130604 + goto map_match;
130605 + }
130606 + }
130607 + ret = -EINVAL;
130608 +map_match:
130609 + spin_unlock(&mem_lock);
130610 + }
130611 + up_read(&current->mm->mmap_sem);
130612 + return ret;
130613 +}
130614 +
130615 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
130616 +{
130617 + unsigned long longret = 0, populate;
130618 + resource_size_t len;
130619 +
130620 + down_write(&current->mm->mmap_sem);
130621 + len = resource_size(res);
130622 + if (len != (unsigned long)len)
130623 + return -EINVAL;
130624 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
130625 + PROT_READ | PROT_WRITE, MAP_SHARED,
130626 + res->start >> PAGE_SHIFT, &populate);
130627 + up_write(&current->mm->mmap_sem);
130628 +
130629 + if (longret & ~PAGE_MASK)
130630 + return (int)longret;
130631 +
130632 + *ptr = (void *) longret;
130633 + return 0;
130634 +}
130635 +
130636 +static void portal_munmap(struct resource *res, void *ptr)
130637 +{
130638 + down_write(&current->mm->mmap_sem);
130639 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res));
130640 + up_write(&current->mm->mmap_sem);
130641 +}
130642 +
130643 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
130644 + struct usdpaa_ioctl_portal_map *arg)
130645 +{
130646 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
130647 + int ret;
130648 +
130649 + if (!mapping)
130650 + return -ENOMEM;
130651 +
130652 + mapping->user = *arg;
130653 + mapping->iommu_domain = NULL;
130654 +
130655 + if (mapping->user.type == usdpaa_portal_qman) {
130656 + mapping->qportal =
130657 + qm_get_unused_portal_idx(mapping->user.index);
130658 + if (!mapping->qportal) {
130659 + ret = -ENODEV;
130660 + goto err_get_portal;
130661 + }
130662 + mapping->phys = &mapping->qportal->addr_phys[0];
130663 + mapping->user.channel = mapping->qportal->public_cfg.channel;
130664 + mapping->user.pools = mapping->qportal->public_cfg.pools;
130665 + mapping->user.index = mapping->qportal->public_cfg.index;
130666 + } else if (mapping->user.type == usdpaa_portal_bman) {
130667 + mapping->bportal =
130668 + bm_get_unused_portal_idx(mapping->user.index);
130669 + if (!mapping->bportal) {
130670 + ret = -ENODEV;
130671 + goto err_get_portal;
130672 + }
130673 + mapping->phys = &mapping->bportal->addr_phys[0];
130674 + mapping->user.index = mapping->bportal->public_cfg.index;
130675 + } else {
130676 + ret = -EINVAL;
130677 + goto err_copy_from_user;
130678 + }
130679 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
130680 + * handlers look it up. */
130681 + spin_lock(&mem_lock);
130682 + list_add(&mapping->list, &ctx->portals);
130683 + spin_unlock(&mem_lock);
130684 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
130685 + &mapping->user.addr.cena);
130686 + if (ret)
130687 + goto err_mmap_cena;
130688 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
130689 + &mapping->user.addr.cinh);
130690 + if (ret)
130691 + goto err_mmap_cinh;
130692 + *arg = mapping->user;
130693 + return ret;
130694 +
130695 +err_mmap_cinh:
130696 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
130697 +err_mmap_cena:
130698 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
130699 + qm_put_unused_portal(mapping->qportal);
130700 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
130701 + bm_put_unused_portal(mapping->bportal);
130702 + spin_lock(&mem_lock);
130703 + list_del(&mapping->list);
130704 + spin_unlock(&mem_lock);
130705 +err_get_portal:
130706 +err_copy_from_user:
130707 + kfree(mapping);
130708 + return ret;
130709 +}
130710 +
130711 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
130712 +{
130713 + struct portal_mapping *mapping;
130714 + struct vm_area_struct *vma;
130715 + unsigned long pfn;
130716 + u32 channel;
130717 +
130718 + /* Get the PFN corresponding to one of the virt addresses */
130719 + down_read(&current->mm->mmap_sem);
130720 + vma = find_vma(current->mm, (unsigned long)i->cinh);
130721 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
130722 + up_read(&current->mm->mmap_sem);
130723 + return -EFAULT;
130724 + }
130725 + pfn = vma->vm_pgoff;
130726 + up_read(&current->mm->mmap_sem);
130727 +
130728 + /* Find the corresponding portal */
130729 + spin_lock(&mem_lock);
130730 + list_for_each_entry(mapping, &ctx->portals, list) {
130731 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
130732 + goto found;
130733 + }
130734 + mapping = NULL;
130735 +found:
130736 + if (mapping)
130737 + list_del(&mapping->list);
130738 + spin_unlock(&mem_lock);
130739 + if (!mapping)
130740 + return -ENODEV;
130741 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
130742 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
130743 + if (mapping->user.type == usdpaa_portal_qman) {
130744 + init_qm_portal(mapping->qportal,
130745 + &mapping->qman_portal_low);
130746 +
130747 + /* Tear down any FQs this portal is referencing */
130748 + channel = mapping->qportal->public_cfg.channel;
130749 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
130750 + &channel,
130751 + check_portal_channel);
130752 + qm_put_unused_portal(mapping->qportal);
130753 + } else if (mapping->user.type == usdpaa_portal_bman) {
130754 + init_bm_portal(mapping->bportal,
130755 + &mapping->bman_portal_low);
130756 + bm_put_unused_portal(mapping->bportal);
130757 + }
130758 + kfree(mapping);
130759 + return 0;
130760 +}
130761 +
130762 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
130763 + uint32_t cpu, uint32_t cache, uint32_t window)
130764 +{
130765 +#ifdef CONFIG_FSL_PAMU
130766 + int ret;
130767 + int window_count = 1;
130768 + struct iommu_domain_geometry geom_attr;
130769 + struct pamu_stash_attribute stash_attr;
130770 +
130771 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
130772 + if (!pcfg->iommu_domain) {
130773 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
130774 + __func__);
130775 + goto _no_iommu;
130776 + }
130777 + geom_attr.aperture_start = 0;
130778 + geom_attr.aperture_end =
130779 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
130780 + geom_attr.force_aperture = true;
130781 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
130782 + &geom_attr);
130783 + if (ret < 0) {
130784 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
130785 + __func__, ret);
130786 + goto _iommu_domain_free;
130787 + }
130788 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
130789 + &window_count);
130790 + if (ret < 0) {
130791 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
130792 + __func__, ret);
130793 + goto _iommu_domain_free;
130794 + }
130795 + stash_attr.cpu = cpu;
130796 + stash_attr.cache = cache;
130797 + /* set stash information for the window */
130798 + stash_attr.window = 0;
130799 +
130800 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
130801 + DOMAIN_ATTR_FSL_PAMU_STASH,
130802 + &stash_attr);
130803 + if (ret < 0) {
130804 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
130805 + __func__, ret);
130806 + goto _iommu_domain_free;
130807 + }
130808 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
130809 + IOMMU_READ | IOMMU_WRITE);
130810 + if (ret < 0) {
130811 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
130812 + __func__, ret);
130813 + goto _iommu_domain_free;
130814 + }
130815 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
130816 + if (ret < 0) {
130817 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
130818 + __func__, ret);
130819 + goto _iommu_domain_free;
130820 + }
130821 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
130822 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
130823 + &window_count);
130824 + if (ret < 0) {
130825 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
130826 + __func__, ret);
130827 + goto _iommu_detach_device;
130828 + }
130829 +_no_iommu:
130830 +#endif
130831 +
130832 +#ifdef CONFIG_FSL_QMAN_CONFIG
130833 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
130834 +#endif
130835 + pr_warn("Failed to set QMan portal's stash request queue\n");
130836 +
130837 + return;
130838 +
130839 +#ifdef CONFIG_FSL_PAMU
130840 +_iommu_detach_device:
130841 + iommu_detach_device(pcfg->iommu_domain, NULL);
130842 +_iommu_domain_free:
130843 + iommu_domain_free(pcfg->iommu_domain);
130844 +#endif
130845 +}
130846 +
130847 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
130848 + struct usdpaa_ioctl_raw_portal *arg)
130849 +{
130850 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
130851 + int ret;
130852 +
130853 + if (!mapping)
130854 + return -ENOMEM;
130855 +
130856 + mapping->user.type = arg->type;
130857 + mapping->iommu_domain = NULL;
130858 + if (arg->type == usdpaa_portal_qman) {
130859 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
130860 + if (!mapping->qportal) {
130861 + ret = -ENODEV;
130862 + goto err;
130863 + }
130864 + mapping->phys = &mapping->qportal->addr_phys[0];
130865 + arg->index = mapping->qportal->public_cfg.index;
130866 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
130867 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
130868 + if (arg->enable_stash) {
130869 + /* Setup the PAMU with the supplied parameters */
130870 + portal_config_pamu(mapping->qportal, arg->sdest,
130871 + arg->cpu, arg->cache, arg->window);
130872 + }
130873 + } else if (mapping->user.type == usdpaa_portal_bman) {
130874 + mapping->bportal =
130875 + bm_get_unused_portal_idx(arg->index);
130876 + if (!mapping->bportal) {
130877 + ret = -ENODEV;
130878 + goto err;
130879 + }
130880 + mapping->phys = &mapping->bportal->addr_phys[0];
130881 + arg->index = mapping->bportal->public_cfg.index;
130882 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
130883 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
130884 + } else {
130885 + ret = -EINVAL;
130886 + goto err;
130887 + }
130888 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
130889 + * handlers look it up. */
130890 + spin_lock(&mem_lock);
130891 + list_add(&mapping->list, &ctx->portals);
130892 + spin_unlock(&mem_lock);
130893 + return 0;
130894 +err:
130895 + kfree(mapping);
130896 + return ret;
130897 +}
130898 +
130899 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
130900 + struct usdpaa_ioctl_raw_portal *arg)
130901 +{
130902 + struct portal_mapping *mapping;
130903 + u32 channel;
130904 +
130905 + /* Find the corresponding portal */
130906 + spin_lock(&mem_lock);
130907 + list_for_each_entry(mapping, &ctx->portals, list) {
130908 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
130909 + goto found;
130910 + }
130911 + mapping = NULL;
130912 +found:
130913 + if (mapping)
130914 + list_del(&mapping->list);
130915 + spin_unlock(&mem_lock);
130916 + if (!mapping)
130917 + return -ENODEV;
130918 + if (mapping->user.type == usdpaa_portal_qman) {
130919 + init_qm_portal(mapping->qportal,
130920 + &mapping->qman_portal_low);
130921 +
130922 + /* Tear down any FQs this portal is referencing */
130923 + channel = mapping->qportal->public_cfg.channel;
130924 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
130925 + &channel,
130926 + check_portal_channel);
130927 + qm_put_unused_portal(mapping->qportal);
130928 + } else if (mapping->user.type == usdpaa_portal_bman) {
130929 + init_bm_portal(mapping->bportal,
130930 + &mapping->bman_portal_low);
130931 + bm_put_unused_portal(mapping->bportal);
130932 + }
130933 + kfree(mapping);
130934 + return 0;
130935 +}
130936 +
130937 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
130938 +{
130939 + struct ctx *ctx = fp->private_data;
130940 + void __user *a = (void __user *)arg;
130941 + switch (cmd) {
130942 + case USDPAA_IOCTL_ID_ALLOC:
130943 + return ioctl_id_alloc(ctx, a);
130944 + case USDPAA_IOCTL_ID_RELEASE:
130945 + return ioctl_id_release(ctx, a);
130946 + case USDPAA_IOCTL_ID_RESERVE:
130947 + return ioctl_id_reserve(ctx, a);
130948 + case USDPAA_IOCTL_DMA_MAP:
130949 + {
130950 + struct usdpaa_ioctl_dma_map input;
130951 + int ret;
130952 + if (copy_from_user(&input, a, sizeof(input)))
130953 + return -EFAULT;
130954 + ret = ioctl_dma_map(fp, ctx, &input);
130955 + if (copy_to_user(a, &input, sizeof(input)))
130956 + return -EFAULT;
130957 + return ret;
130958 + }
130959 + case USDPAA_IOCTL_DMA_UNMAP:
130960 + return ioctl_dma_unmap(ctx, a);
130961 + case USDPAA_IOCTL_DMA_LOCK:
130962 + return ioctl_dma_lock(ctx, a);
130963 + case USDPAA_IOCTL_DMA_UNLOCK:
130964 + return ioctl_dma_unlock(ctx, a);
130965 + case USDPAA_IOCTL_PORTAL_MAP:
130966 + {
130967 + struct usdpaa_ioctl_portal_map input;
130968 + int ret;
130969 + if (copy_from_user(&input, a, sizeof(input)))
130970 + return -EFAULT;
130971 + ret = ioctl_portal_map(fp, ctx, &input);
130972 + if (copy_to_user(a, &input, sizeof(input)))
130973 + return -EFAULT;
130974 + return ret;
130975 + }
130976 + case USDPAA_IOCTL_PORTAL_UNMAP:
130977 + {
130978 + struct usdpaa_portal_map input;
130979 + if (copy_from_user(&input, a, sizeof(input)))
130980 + return -EFAULT;
130981 + return ioctl_portal_unmap(ctx, &input);
130982 + }
130983 + case USDPAA_IOCTL_DMA_USED:
130984 + return ioctl_dma_stats(ctx, a);
130985 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
130986 + {
130987 + struct usdpaa_ioctl_raw_portal input;
130988 + int ret;
130989 + if (copy_from_user(&input, a, sizeof(input)))
130990 + return -EFAULT;
130991 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
130992 + if (copy_to_user(a, &input, sizeof(input)))
130993 + return -EFAULT;
130994 + return ret;
130995 + }
130996 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
130997 + {
130998 + struct usdpaa_ioctl_raw_portal input;
130999 + if (copy_from_user(&input, a, sizeof(input)))
131000 + return -EFAULT;
131001 + return ioctl_free_raw_portal(fp, ctx, &input);
131002 + }
131003 + }
131004 + return -EINVAL;
131005 +}
131006 +
131007 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
131008 + unsigned long arg)
131009 +{
131010 +#ifdef CONFIG_COMPAT
131011 + struct ctx *ctx = fp->private_data;
131012 + void __user *a = (void __user *)arg;
131013 +#endif
131014 + switch (cmd) {
131015 +#ifdef CONFIG_COMPAT
131016 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
131017 + {
131018 + int ret;
131019 + struct usdpaa_ioctl_dma_map_compat input;
131020 + struct usdpaa_ioctl_dma_map converted;
131021 +
131022 + if (copy_from_user(&input, a, sizeof(input)))
131023 + return -EFAULT;
131024 +
131025 + converted.ptr = compat_ptr(input.ptr);
131026 + converted.phys_addr = input.phys_addr;
131027 + converted.len = input.len;
131028 + converted.flags = input.flags;
131029 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
131030 + converted.has_locking = input.has_locking;
131031 + converted.did_create = input.did_create;
131032 +
131033 + ret = ioctl_dma_map(fp, ctx, &converted);
131034 + input.ptr = ptr_to_compat(converted.ptr);
131035 + input.phys_addr = converted.phys_addr;
131036 + input.len = converted.len;
131037 + input.flags = converted.flags;
131038 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
131039 + input.has_locking = converted.has_locking;
131040 + input.did_create = converted.did_create;
131041 + if (copy_to_user(a, &input, sizeof(input)))
131042 + return -EFAULT;
131043 + return ret;
131044 + }
131045 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
131046 + {
131047 + int ret;
131048 + struct compat_usdpaa_ioctl_portal_map input;
131049 + struct usdpaa_ioctl_portal_map converted;
131050 + if (copy_from_user(&input, a, sizeof(input)))
131051 + return -EFAULT;
131052 + converted.type = input.type;
131053 + converted.index = input.index;
131054 + ret = ioctl_portal_map(fp, ctx, &converted);
131055 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
131056 + input.addr.cena = ptr_to_compat(converted.addr.cena);
131057 + input.channel = converted.channel;
131058 + input.pools = converted.pools;
131059 + input.index = converted.index;
131060 + if (copy_to_user(a, &input, sizeof(input)))
131061 + return -EFAULT;
131062 + return ret;
131063 + }
131064 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
131065 + {
131066 + struct usdpaa_portal_map_compat input;
131067 + struct usdpaa_portal_map converted;
131068 +
131069 + if (copy_from_user(&input, a, sizeof(input)))
131070 + return -EFAULT;
131071 + converted.cinh = compat_ptr(input.cinh);
131072 + converted.cena = compat_ptr(input.cena);
131073 + return ioctl_portal_unmap(ctx, &converted);
131074 + }
131075 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
131076 + {
131077 + int ret;
131078 + struct usdpaa_ioctl_raw_portal converted;
131079 + struct compat_ioctl_raw_portal input;
131080 + if (copy_from_user(&input, a, sizeof(input)))
131081 + return -EFAULT;
131082 + converted.type = input.type;
131083 + converted.index = input.index;
131084 + converted.enable_stash = input.enable_stash;
131085 + converted.cpu = input.cpu;
131086 + converted.cache = input.cache;
131087 + converted.window = input.window;
131088 + converted.sdest = input.sdest;
131089 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
131090 +
131091 + input.cinh = converted.cinh;
131092 + input.cena = converted.cena;
131093 + input.index = converted.index;
131094 +
131095 + if (copy_to_user(a, &input, sizeof(input)))
131096 + return -EFAULT;
131097 + return ret;
131098 + }
131099 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
131100 + {
131101 + struct usdpaa_ioctl_raw_portal converted;
131102 + struct compat_ioctl_raw_portal input;
131103 + if (copy_from_user(&input, a, sizeof(input)))
131104 + return -EFAULT;
131105 + converted.type = input.type;
131106 + converted.index = input.index;
131107 + converted.cinh = input.cinh;
131108 + converted.cena = input.cena;
131109 + return ioctl_free_raw_portal(fp, ctx, &converted);
131110 + }
131111 +#endif
131112 + default:
131113 + return usdpaa_ioctl(fp, cmd, arg);
131114 + }
131115 + return -EINVAL;
131116 +}
131117 +
131118 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
131119 + enum usdpaa_portal_type ptype, unsigned int *irq,
131120 + void **iir_reg)
131121 +{
131122 + /* Walk the list of portals for filp and return the config
131123 + for the portal that matches the hint */
131124 + struct ctx *context;
131125 + struct portal_mapping *portal;
131126 +
131127 + /* First sanitize the filp */
131128 + if (filp->f_op->open != usdpaa_open)
131129 + return -ENODEV;
131130 + context = filp->private_data;
131131 + spin_lock(&context->lock);
131132 + list_for_each_entry(portal, &context->portals, list) {
131133 + if (portal->user.type == ptype &&
131134 + portal->user.addr.cinh == cinh) {
131135 + if (ptype == usdpaa_portal_qman) {
131136 + *irq = portal->qportal->public_cfg.irq;
131137 + *iir_reg = portal->qportal->addr_virt[1] +
131138 + QM_REG_IIR;
131139 + } else {
131140 + *irq = portal->bportal->public_cfg.irq;
131141 + *iir_reg = portal->bportal->addr_virt[1] +
131142 + BM_REG_IIR;
131143 + }
131144 + spin_unlock(&context->lock);
131145 + return 0;
131146 + }
131147 + }
131148 + spin_unlock(&context->lock);
131149 + return -EINVAL;
131150 +}
131151 +
131152 +static const struct file_operations usdpaa_fops = {
131153 + .open = usdpaa_open,
131154 + .release = usdpaa_release,
131155 + .mmap = usdpaa_mmap,
131156 + .get_unmapped_area = usdpaa_get_unmapped_area,
131157 + .unlocked_ioctl = usdpaa_ioctl,
131158 + .compat_ioctl = usdpaa_ioctl_compat
131159 +};
131160 +
131161 +static struct miscdevice usdpaa_miscdev = {
131162 + .name = "fsl-usdpaa",
131163 + .fops = &usdpaa_fops,
131164 + .minor = MISC_DYNAMIC_MINOR,
131165 +};
131166 +
131167 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
131168 + * indicate how much memory (if any) to allocate during early boot. If the
131169 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
131170 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
131171 + * than there are TLB1 entries, fault-handling will occur. */
131172 +
131173 +static __init int usdpaa_mem(char *arg)
131174 +{
131175 + pr_warn("uspdaa_mem argument is depracated\n");
131176 + arg_phys_size = memparse(arg, &arg);
131177 + num_tlb = 1;
131178 + if (*arg == ',') {
131179 + unsigned long ul;
131180 + int err = kstrtoul(arg + 1, 0, &ul);
131181 + if (err < 0) {
131182 + num_tlb = 1;
131183 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
131184 + } else
131185 + num_tlb = (unsigned int)ul;
131186 + }
131187 + return 0;
131188 +}
131189 +early_param("usdpaa_mem", usdpaa_mem);
131190 +
131191 +static int usdpaa_mem_init(struct reserved_mem *rmem)
131192 +{
131193 + phys_start = rmem->base;
131194 + phys_size = rmem->size;
131195 +
131196 + WARN_ON(!(phys_start && phys_size));
131197 +
131198 + return 0;
131199 +}
131200 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
131201 +
131202 +__init int fsl_usdpaa_init_early(void)
131203 +{
131204 + if (!phys_size || !phys_start) {
131205 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
131206 + return 0;
131207 + }
131208 + if (phys_size % PAGE_SIZE) {
131209 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
131210 + phys_size = 0;
131211 + return 0;
131212 + }
131213 + if (arg_phys_size && phys_size != arg_phys_size) {
131214 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
131215 + arg_phys_size, phys_size);
131216 + phys_size = 0;
131217 + return 0;
131218 + }
131219 + pfn_start = phys_start >> PAGE_SHIFT;
131220 + pfn_size = phys_size >> PAGE_SHIFT;
131221 +#ifdef CONFIG_PPC
131222 + first_tlb = current_tlb = tlbcam_index;
131223 + tlbcam_index += num_tlb;
131224 +#endif
131225 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
131226 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
131227 + return 0;
131228 +}
131229 +subsys_initcall(fsl_usdpaa_init_early);
131230 +
131231 +
131232 +static int __init usdpaa_init(void)
131233 +{
131234 + struct mem_fragment *frag;
131235 + int ret;
131236 + u64 tmp_size = phys_size;
131237 + u64 tmp_start = phys_start;
131238 + u64 tmp_pfn_size = pfn_size;
131239 + u64 tmp_pfn_start = pfn_start;
131240 +
131241 + pr_info("Freescale USDPAA process driver\n");
131242 + if (!phys_start) {
131243 + pr_warn("fsl-usdpaa: no region found\n");
131244 + return 0;
131245 + }
131246 +
131247 + while (tmp_size != 0) {
131248 + u32 frag_size = largest_page_size(tmp_size);
131249 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
131250 + if (!frag) {
131251 + pr_err("Failed to setup USDPAA memory accounting\n");
131252 + return -ENOMEM;
131253 + }
131254 + frag->base = tmp_start;
131255 + frag->len = frag->root_len = frag_size;
131256 + frag->root_pfn = tmp_pfn_start;
131257 + frag->pfn_base = tmp_pfn_start;
131258 + frag->pfn_len = frag_size / PAGE_SIZE;
131259 + frag->refs = 0;
131260 + init_waitqueue_head(&frag->wq);
131261 + frag->owner = NULL;
131262 + list_add(&frag->list, &mem_list);
131263 +
131264 + /* Adjust for this frag */
131265 + tmp_start += frag_size;
131266 + tmp_size -= frag_size;
131267 + tmp_pfn_start += frag_size / PAGE_SIZE;
131268 + tmp_pfn_size -= frag_size / PAGE_SIZE;
131269 + }
131270 + ret = misc_register(&usdpaa_miscdev);
131271 + if (ret)
131272 + pr_err("fsl-usdpaa: failed to register misc device\n");
131273 + return ret;
131274 +}
131275 +
131276 +static void __exit usdpaa_exit(void)
131277 +{
131278 + misc_deregister(&usdpaa_miscdev);
131279 +}
131280 +
131281 +module_init(usdpaa_init);
131282 +module_exit(usdpaa_exit);
131283 +
131284 +MODULE_LICENSE("GPL");
131285 +MODULE_AUTHOR("Freescale Semiconductor");
131286 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
131287 --- /dev/null
131288 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
131289 @@ -0,0 +1,289 @@
131290 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
131291 + * All rights reserved.
131292 + *
131293 + * Redistribution and use in source and binary forms, with or without
131294 + * modification, are permitted provided that the following conditions are met:
131295 + * * Redistributions of source code must retain the above copyright
131296 + * notice, this list of conditions and the following disclaimer.
131297 + * * Redistributions in binary form must reproduce the above copyright
131298 + * notice, this list of conditions and the following disclaimer in the
131299 + * documentation and/or other materials provided with the distribution.
131300 + * * Neither the name of Freescale Semiconductor nor the
131301 + * names of its contributors may be used to endorse or promote products
131302 + * derived from this software without specific prior written permission.
131303 + *
131304 + *
131305 + * ALTERNATIVELY, this software may be distributed under the terms of the
131306 + * GNU General Public License ("GPL") as published by the Free Software
131307 + * Foundation, either version 2 of that License or (at your option) any
131308 + * later version.
131309 + *
131310 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131311 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131312 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131313 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131314 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131315 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131316 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131317 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131318 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131319 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131320 + */
131321 +
131322 +/* define a device that allows USPDAA processes to open a file
131323 + descriptor and specify which IRQ it wants to montior using an ioctl()
131324 + When an IRQ is received, the device becomes readable so that a process
131325 + can use read() or select() type calls to monitor for IRQs */
131326 +
131327 +#include <linux/miscdevice.h>
131328 +#include <linux/fs.h>
131329 +#include <linux/cdev.h>
131330 +#include <linux/slab.h>
131331 +#include <linux/interrupt.h>
131332 +#include <linux/poll.h>
131333 +#include <linux/uaccess.h>
131334 +#include <linux/fsl_usdpaa.h>
131335 +#include <linux/module.h>
131336 +#include <linux/fdtable.h>
131337 +#include <linux/file.h>
131338 +
131339 +#include "qman_low.h"
131340 +#include "bman_low.h"
131341 +
131342 +struct usdpaa_irq_ctx {
131343 + int irq_set; /* Set to true once the irq is set via ioctl */
131344 + unsigned int irq_num;
131345 + u32 last_irq_count; /* Last value returned from read */
131346 + u32 irq_count; /* Number of irqs since last read */
131347 + wait_queue_head_t wait_queue; /* Waiting processes */
131348 + spinlock_t lock;
131349 + void *inhibit_addr; /* inhibit register address */
131350 + struct file *usdpaa_filp;
131351 + char irq_name[128];
131352 +};
131353 +
131354 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
131355 +{
131356 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
131357 + if (!ctx)
131358 + return -ENOMEM;
131359 + ctx->irq_set = 0;
131360 + ctx->irq_count = 0;
131361 + ctx->last_irq_count = 0;
131362 + init_waitqueue_head(&ctx->wait_queue);
131363 + spin_lock_init(&ctx->lock);
131364 + filp->private_data = ctx;
131365 + return 0;
131366 +}
131367 +
131368 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
131369 +{
131370 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131371 + if (ctx->irq_set) {
131372 + /* Inhibit the IRQ */
131373 + out_be32(ctx->inhibit_addr, 0x1);
131374 + irq_set_affinity_hint(ctx->irq_num, NULL);
131375 + free_irq(ctx->irq_num, ctx);
131376 + ctx->irq_set = 0;
131377 + fput(ctx->usdpaa_filp);
131378 + }
131379 + kfree(filp->private_data);
131380 + return 0;
131381 +}
131382 +
131383 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
131384 +{
131385 + unsigned long flags;
131386 + struct usdpaa_irq_ctx *ctx = _ctx;
131387 + spin_lock_irqsave(&ctx->lock, flags);
131388 + ++ctx->irq_count;
131389 + spin_unlock_irqrestore(&ctx->lock, flags);
131390 + wake_up_all(&ctx->wait_queue);
131391 + /* Set the inhibit register. This will be reenabled
131392 + once the USDPAA code handles the IRQ */
131393 + out_be32(ctx->inhibit_addr, 0x1);
131394 + pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
131395 + return IRQ_HANDLED;
131396 +}
131397 +
131398 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
131399 +{
131400 + struct usdpaa_irq_ctx *ctx = fp->private_data;
131401 + int ret;
131402 +
131403 + if (ctx->irq_set) {
131404 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
131405 + return -EBUSY;
131406 + }
131407 +
131408 + ctx->usdpaa_filp = fget(irq_map->fd);
131409 + if (!ctx->usdpaa_filp) {
131410 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
131411 + return -EINVAL;
131412 + }
131413 +
131414 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
131415 + irq_map->type, &ctx->irq_num,
131416 + &ctx->inhibit_addr);
131417 + if (ret) {
131418 + pr_debug("USDPAA IRQ couldn't identify portal\n");
131419 + fput(ctx->usdpaa_filp);
131420 + return ret;
131421 + }
131422 +
131423 + ctx->irq_set = 1;
131424 +
131425 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
131426 + "usdpaa_irq %d", ctx->irq_num);
131427 +
131428 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
131429 + ctx->irq_name, ctx);
131430 + if (ret) {
131431 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
131432 + ctx->irq_num, ret);
131433 + ctx->irq_set = 0;
131434 + fput(ctx->usdpaa_filp);
131435 + return ret;
131436 + }
131437 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
131438 + if (ret)
131439 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
131440 +
131441 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
131442 + if (ret)
131443 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
131444 +
131445 + return 0;
131446 +}
131447 +
131448 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
131449 + unsigned long arg)
131450 +{
131451 + int ret;
131452 + struct usdpaa_ioctl_irq_map irq_map;
131453 +
131454 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
131455 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
131456 + return -EINVAL;
131457 + }
131458 +
131459 + ret = copy_from_user(&irq_map, (void __user *)arg,
131460 + sizeof(irq_map));
131461 + if (ret)
131462 + return ret;
131463 + return map_irq(fp, &irq_map);
131464 +}
131465 +
131466 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
131467 + size_t count, loff_t *offp)
131468 +{
131469 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131470 + int ret;
131471 +
131472 + if (!ctx->irq_set) {
131473 + pr_debug("Reading USDPAA IRQ before it was set\n");
131474 + return -EINVAL;
131475 + }
131476 +
131477 + if (count < sizeof(ctx->irq_count)) {
131478 + pr_debug("USDPAA IRQ Read too small\n");
131479 + return -EINVAL;
131480 + }
131481 + if (ctx->irq_count == ctx->last_irq_count) {
131482 + if (filp->f_flags & O_NONBLOCK)
131483 + return -EAGAIN;
131484 +
131485 + ret = wait_event_interruptible(ctx->wait_queue,
131486 + ctx->irq_count != ctx->last_irq_count);
131487 + if (ret == -ERESTARTSYS)
131488 + return ret;
131489 + }
131490 +
131491 + ctx->last_irq_count = ctx->irq_count;
131492 +
131493 + if (copy_to_user(buff, &ctx->last_irq_count,
131494 + sizeof(ctx->last_irq_count)))
131495 + return -EFAULT;
131496 + return sizeof(ctx->irq_count);
131497 +}
131498 +
131499 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
131500 +{
131501 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131502 + unsigned int ret = 0;
131503 + unsigned long flags;
131504 +
131505 + if (!ctx->irq_set)
131506 + return POLLHUP;
131507 +
131508 + poll_wait(filp, &ctx->wait_queue, wait);
131509 +
131510 + spin_lock_irqsave(&ctx->lock, flags);
131511 + if (ctx->irq_count != ctx->last_irq_count)
131512 + ret |= POLLIN | POLLRDNORM;
131513 + spin_unlock_irqrestore(&ctx->lock, flags);
131514 + return ret;
131515 +}
131516 +
131517 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
131518 + unsigned long arg)
131519 +{
131520 +#ifdef CONFIG_COMPAT
131521 + void __user *a = (void __user *)arg;
131522 +#endif
131523 + switch (cmd) {
131524 +#ifdef CONFIG_COMPAT
131525 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
131526 + {
131527 + struct compat_ioctl_irq_map input;
131528 + struct usdpaa_ioctl_irq_map converted;
131529 + if (copy_from_user(&input, a, sizeof(input)))
131530 + return -EFAULT;
131531 + converted.type = input.type;
131532 + converted.fd = input.fd;
131533 + converted.portal_cinh = compat_ptr(input.portal_cinh);
131534 + return map_irq(fp, &converted);
131535 + }
131536 +#endif
131537 + default:
131538 + return usdpaa_irq_ioctl(fp, cmd, arg);
131539 + }
131540 +}
131541 +
131542 +static const struct file_operations usdpaa_irq_fops = {
131543 + .open = usdpaa_irq_open,
131544 + .release = usdpaa_irq_release,
131545 + .unlocked_ioctl = usdpaa_irq_ioctl,
131546 + .compat_ioctl = usdpaa_irq_ioctl_compat,
131547 + .read = usdpaa_irq_read,
131548 + .poll = usdpaa_irq_poll
131549 +};
131550 +
131551 +static struct miscdevice usdpaa_miscdev = {
131552 + .name = "fsl-usdpaa-irq",
131553 + .fops = &usdpaa_irq_fops,
131554 + .minor = MISC_DYNAMIC_MINOR,
131555 +};
131556 +
131557 +static int __init usdpaa_irq_init(void)
131558 +{
131559 + int ret;
131560 +
131561 + pr_info("Freescale USDPAA process IRQ driver\n");
131562 + ret = misc_register(&usdpaa_miscdev);
131563 + if (ret)
131564 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
131565 + return ret;
131566 +}
131567 +
131568 +static void __exit usdpaa_irq_exit(void)
131569 +{
131570 + misc_deregister(&usdpaa_miscdev);
131571 +}
131572 +
131573 +module_init(usdpaa_irq_init);
131574 +module_exit(usdpaa_irq_exit);
131575 +
131576 +MODULE_LICENSE("GPL");
131577 +MODULE_AUTHOR("Freescale Semiconductor");
131578 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
131579 --- /dev/null
131580 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
131581 @@ -0,0 +1,88 @@
131582 +/* Copyright 2013 Freescale Semiconductor, Inc.
131583 + *
131584 + * Redistribution and use in source and binary forms, with or without
131585 + * modification, are permitted provided that the following conditions are met:
131586 + * * Redistributions of source code must retain the above copyright
131587 + * notice, this list of conditions and the following disclaimer.
131588 + * * Redistributions in binary form must reproduce the above copyright
131589 + * notice, this list of conditions and the following disclaimer in the
131590 + * documentation and/or other materials provided with the distribution.
131591 + * * Neither the name of Freescale Semiconductor nor the
131592 + * names of its contributors may be used to endorse or promote products
131593 + * derived from this software without specific prior written permission.
131594 + *
131595 + *
131596 + * ALTERNATIVELY, this software may be distributed under the terms of the
131597 + * GNU General Public License ("GPL") as published by the Free Software
131598 + * Foundation, either version 2 of that License or (at your option) any
131599 + * later version.
131600 + *
131601 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131602 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131603 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131604 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131605 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131606 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131607 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131608 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131609 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131610 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131611 + */
131612 +
131613 +#include <linux/time.h>
131614 +#include "qman_private.h"
131615 +#include "bman_private.h"
131616 +__init void qman_init_early(void);
131617 +__init void bman_init_early(void);
131618 +
131619 +static __init int qbman_init(void)
131620 +{
131621 + struct device_node *dn;
131622 + u32 is_portal_available;
131623 +
131624 + bman_init();
131625 + qman_init();
131626 +
131627 + is_portal_available = 0;
131628 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
131629 + if (!of_device_is_available(dn))
131630 + continue;
131631 + else
131632 + is_portal_available = 1;
131633 + }
131634 +
131635 + if (!qman_have_ccsr() && is_portal_available) {
131636 + struct qman_fq fq = {
131637 + .fqid = 1
131638 + };
131639 + struct qm_mcr_queryfq_np np;
131640 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
131641 + struct timespec nowts, diffts, startts = current_kernel_time();
131642 + /* Loop while querying given fqid succeeds or time out */
131643 + while (1) {
131644 + err = qman_query_fq_np(&fq, &np);
131645 + if (!err) {
131646 + /* success, control-plane has configured QMan */
131647 + break;
131648 + } else if (err != -ERANGE) {
131649 + pr_err("QMan: I/O error, continuing anyway\n");
131650 + break;
131651 + }
131652 + nowts = current_kernel_time();
131653 + diffts = timespec_sub(nowts, startts);
131654 + if (diffts.tv_sec > 0) {
131655 + if (!retry--) {
131656 + pr_err("QMan: time out, control-plane"
131657 + " dead?\n");
131658 + break;
131659 + }
131660 + pr_warn("QMan: polling for the control-plane"
131661 + " (%d)\n", retry);
131662 + }
131663 + }
131664 + }
131665 + bman_resource_init();
131666 + qman_resource_init();
131667 + return 0;
131668 +}
131669 +subsys_initcall(qbman_init);
131670 --- /dev/null
131671 +++ b/drivers/staging/fsl_qbman/qman_config.c
131672 @@ -0,0 +1,1224 @@
131673 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
131674 + *
131675 + * Redistribution and use in source and binary forms, with or without
131676 + * modification, are permitted provided that the following conditions are met:
131677 + * * Redistributions of source code must retain the above copyright
131678 + * notice, this list of conditions and the following disclaimer.
131679 + * * Redistributions in binary form must reproduce the above copyright
131680 + * notice, this list of conditions and the following disclaimer in the
131681 + * documentation and/or other materials provided with the distribution.
131682 + * * Neither the name of Freescale Semiconductor nor the
131683 + * names of its contributors may be used to endorse or promote products
131684 + * derived from this software without specific prior written permission.
131685 + *
131686 + *
131687 + * ALTERNATIVELY, this software may be distributed under the terms of the
131688 + * GNU General Public License ("GPL") as published by the Free Software
131689 + * Foundation, either version 2 of that License or (at your option) any
131690 + * later version.
131691 + *
131692 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131693 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131694 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131695 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131696 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131697 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131698 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131699 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131700 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131701 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131702 + */
131703 +
131704 +#include <asm/cacheflush.h>
131705 +#include "qman_private.h"
131706 +#include <linux/highmem.h>
131707 +#include <linux/of_reserved_mem.h>
131708 +
131709 +/* Last updated for v00.800 of the BG */
131710 +
131711 +/* Register offsets */
131712 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
131713 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
131714 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
131715 +#define REG_DD_CFG 0x0200
131716 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
131717 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
131718 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
131719 +#define REG_PFDR_FPC 0x0400
131720 +#define REG_PFDR_FP_HEAD 0x0404
131721 +#define REG_PFDR_FP_TAIL 0x0408
131722 +#define REG_PFDR_FP_LWIT 0x0410
131723 +#define REG_PFDR_CFG 0x0414
131724 +#define REG_SFDR_CFG 0x0500
131725 +#define REG_SFDR_IN_USE 0x0504
131726 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
131727 +#define REG_WQ_DEF_ENC_WQID 0x0630
131728 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
131729 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
131730 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
131731 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
131732 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
131733 +#define REG_CM_CFG 0x0800
131734 +#define REG_ECSR 0x0a00
131735 +#define REG_ECIR 0x0a04
131736 +#define REG_EADR 0x0a08
131737 +#define REG_ECIR2 0x0a0c
131738 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
131739 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
131740 +#define REG_MCR 0x0b00
131741 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
131742 +#define REG_MISC_CFG 0x0be0
131743 +#define REG_HID_CFG 0x0bf0
131744 +#define REG_IDLE_STAT 0x0bf4
131745 +#define REG_IP_REV_1 0x0bf8
131746 +#define REG_IP_REV_2 0x0bfc
131747 +#define REG_FQD_BARE 0x0c00
131748 +#define REG_PFDR_BARE 0x0c20
131749 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
131750 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
131751 +#define REG_QCSP_BARE 0x0c80
131752 +#define REG_QCSP_BAR 0x0c84
131753 +#define REG_CI_SCHED_CFG 0x0d00
131754 +#define REG_SRCIDR 0x0d04
131755 +#define REG_LIODNR 0x0d08
131756 +#define REG_CI_RLM_AVG 0x0d14
131757 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
131758 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
131759 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
131760 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
131761 +#define REG_CEETM_CFG_IDX 0x900
131762 +#define REG_CEETM_CFG_PRES 0x904
131763 +#define REG_CEETM_XSFDR_IN_USE 0x908
131764 +
131765 +/* Assists for QMAN_MCR */
131766 +#define MCR_INIT_PFDR 0x01000000
131767 +#define MCR_get_rslt(v) (u8)((v) >> 24)
131768 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
131769 +#define MCR_rslt_ok(r) (rslt == 0xf0)
131770 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
131771 +#define MCR_rslt_inval(r) (rslt == 0xff)
131772 +
131773 +struct qman;
131774 +
131775 +/* Follows WQ_CS_CFG0-5 */
131776 +enum qm_wq_class {
131777 + qm_wq_portal = 0,
131778 + qm_wq_pool = 1,
131779 + qm_wq_fman0 = 2,
131780 + qm_wq_fman1 = 3,
131781 + qm_wq_caam = 4,
131782 + qm_wq_pme = 5,
131783 + qm_wq_first = qm_wq_portal,
131784 + qm_wq_last = qm_wq_pme
131785 +};
131786 +
131787 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
131788 +enum qm_memory {
131789 + qm_memory_fqd,
131790 + qm_memory_pfdr
131791 +};
131792 +
131793 +/* Used by all error interrupt registers except 'inhibit' */
131794 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
131795 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
131796 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
131797 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
131798 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
131799 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
131800 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
131801 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
131802 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
131803 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
131804 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
131805 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
131806 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
131807 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
131808 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
131809 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
131810 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
131811 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
131812 +
131813 +/* QMAN_ECIR valid error bit */
131814 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
131815 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
131816 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
131817 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
131818 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
131819 + QM_EIRQ_IFSI)
131820 +
131821 +union qman_ecir {
131822 + u32 ecir_raw;
131823 + struct {
131824 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
131825 + u32 __reserved:2;
131826 + u32 portal_type:1;
131827 + u32 portal_num:5;
131828 + u32 fqid:24;
131829 +#else
131830 + u32 fqid:24;
131831 + u32 portal_num:5;
131832 + u32 portal_type:1;
131833 + u32 __reserved:2;
131834 +#endif
131835 + } __packed info;
131836 +};
131837 +
131838 +union qman_ecir2 {
131839 + u32 ecir2_raw;
131840 + struct {
131841 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
131842 + u32 portal_type:1;
131843 + u32 __reserved:21;
131844 + u32 portal_num:10;
131845 +#else
131846 + u32 portal_num:10;
131847 + u32 __reserved:21;
131848 + u32 portal_type:1;
131849 +#endif
131850 + } __packed info;
131851 +};
131852 +
131853 +union qman_eadr {
131854 + u32 eadr_raw;
131855 + struct {
131856 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
131857 + u32 __reserved1:4;
131858 + u32 memid:4;
131859 + u32 __reserved2:12;
131860 + u32 eadr:12;
131861 +#else
131862 + u32 eadr:12;
131863 + u32 __reserved2:12;
131864 + u32 memid:4;
131865 + u32 __reserved1:4;
131866 +#endif
131867 + } __packed info;
131868 + struct {
131869 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
131870 + u32 __reserved1:3;
131871 + u32 memid:5;
131872 + u32 __reserved:8;
131873 + u32 eadr:16;
131874 +#else
131875 + u32 eadr:16;
131876 + u32 __reserved:8;
131877 + u32 memid:5;
131878 + u32 __reserved1:3;
131879 +#endif
131880 + } __packed info_rev3;
131881 +};
131882 +
131883 +struct qman_hwerr_txt {
131884 + u32 mask;
131885 + const char *txt;
131886 +};
131887 +
131888 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
131889 +
131890 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
131891 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
131892 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
131893 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
131894 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
131895 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
131896 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
131897 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
131898 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
131899 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
131900 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
131901 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
131902 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
131903 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
131904 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
131905 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
131906 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
131907 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
131908 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
131909 +};
131910 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
131911 +
131912 +struct qman_error_info_mdata {
131913 + u16 addr_mask;
131914 + u16 bits;
131915 + const char *txt;
131916 +};
131917 +
131918 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
131919 +static const struct qman_error_info_mdata error_mdata[] = {
131920 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
131921 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
131922 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
131923 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
131924 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
131925 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
131926 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
131927 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
131928 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
131929 + QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"),
131930 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
131931 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
131932 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
131933 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
131934 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
131935 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
131936 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
131937 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
131938 +};
131939 +#define QMAN_ERR_MDATA_COUNT \
131940 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
131941 +
131942 +/* Add this in Kconfig */
131943 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
131944 +
131945 +/**
131946 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
131947 + * @v: for accessors that write values, this is the 32-bit value
131948 + *
131949 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
131950 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
131951 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
131952 + * "write the enable register" rather than "enable the write register"!
131953 + */
131954 +#define qm_err_isr_status_read(qm) \
131955 + __qm_err_isr_read(qm, qm_isr_status)
131956 +#define qm_err_isr_status_clear(qm, m) \
131957 + __qm_err_isr_write(qm, qm_isr_status, m)
131958 +#define qm_err_isr_enable_read(qm) \
131959 + __qm_err_isr_read(qm, qm_isr_enable)
131960 +#define qm_err_isr_enable_write(qm, v) \
131961 + __qm_err_isr_write(qm, qm_isr_enable, v)
131962 +#define qm_err_isr_disable_read(qm) \
131963 + __qm_err_isr_read(qm, qm_isr_disable)
131964 +#define qm_err_isr_disable_write(qm, v) \
131965 + __qm_err_isr_write(qm, qm_isr_disable, v)
131966 +#define qm_err_isr_inhibit(qm) \
131967 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
131968 +#define qm_err_isr_uninhibit(qm) \
131969 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
131970 +
131971 +/*
131972 + * TODO: unimplemented registers
131973 + *
131974 + * Keeping a list here of Qman registers I have not yet covered;
131975 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
131976 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
131977 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
131978 + */
131979 +
131980 +/* Encapsulate "struct qman *" as a cast of the register space address. */
131981 +
131982 +static struct qman *qm_create(void *regs)
131983 +{
131984 + return (struct qman *)regs;
131985 +}
131986 +
131987 +static inline u32 __qm_in(struct qman *qm, u32 offset)
131988 +{
131989 + return in_be32((void *)qm + offset);
131990 +}
131991 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
131992 +{
131993 + out_be32((void *)qm + offset, val);
131994 +}
131995 +#define qm_in(reg) __qm_in(qm, REG_##reg)
131996 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
131997 +
131998 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
131999 +{
132000 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
132001 +}
132002 +
132003 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
132004 +{
132005 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
132006 +}
132007 +
132008 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
132009 + int ed, u8 sernd)
132010 +{
132011 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
132012 + (portal == qm_dc_portal_fman1));
132013 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132014 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
132015 + else
132016 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
132017 +}
132018 +
132019 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
132020 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
132021 + u8 csw6, u8 csw7)
132022 +{
132023 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
132024 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
132025 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
132026 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
132027 +}
132028 +
132029 +static void qm_set_hid(struct qman *qm)
132030 +{
132031 + qm_out(HID_CFG, 0);
132032 +}
132033 +
132034 +static void qm_set_corenet_initiator(struct qman *qm)
132035 +{
132036 + qm_out(CI_SCHED_CFG,
132037 + 0x80000000 | /* write srcciv enable */
132038 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
132039 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
132040 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
132041 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
132042 +}
132043 +
132044 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
132045 + u8 *cfg)
132046 +{
132047 + u32 v = qm_in(IP_REV_1);
132048 + u32 v2 = qm_in(IP_REV_2);
132049 + *id = (v >> 16);
132050 + *major = (v >> 8) & 0xff;
132051 + *minor = v & 0xff;
132052 + *cfg = v2 & 0xff;
132053 +}
132054 +
132055 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
132056 + int enable, int prio, int stash, u32 size)
132057 +{
132058 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
132059 + u32 exp = ilog2(size);
132060 + /* choke if size isn't within range */
132061 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
132062 + is_power_of_2(size));
132063 + /* choke if 'ba' has lower-alignment than 'size' */
132064 + DPA_ASSERT(!(ba & (size - 1)));
132065 + __qm_out(qm, offset, upper_32_bits(ba));
132066 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
132067 + __qm_out(qm, offset + REG_offset_AR,
132068 + (enable ? 0x80000000 : 0) |
132069 + (prio ? 0x40000000 : 0) |
132070 + (stash ? 0x20000000 : 0) |
132071 + (exp - 1));
132072 +}
132073 +
132074 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
132075 +{
132076 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
132077 + qm_out(PFDR_CFG, k);
132078 +}
132079 +
132080 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
132081 +{
132082 + qm_out(SFDR_CFG, th & 0x3ff);
132083 +}
132084 +
132085 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
132086 +{
132087 + u8 rslt = MCR_get_rslt(qm_in(MCR));
132088 +
132089 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
132090 + /* Make sure the command interface is 'idle' */
132091 + if (!MCR_rslt_idle(rslt))
132092 + panic("QMAN_MCR isn't idle");
132093 +
132094 + /* Write the MCR command params then the verb */
132095 + qm_out(MCP(0), pfdr_start);
132096 + /* TODO: remove this - it's a workaround for a model bug that is
132097 + * corrected in more recent versions. We use the workaround until
132098 + * everyone has upgraded. */
132099 + qm_out(MCP(1), (pfdr_start + num - 16));
132100 + lwsync();
132101 + qm_out(MCR, MCR_INIT_PFDR);
132102 + /* Poll for the result */
132103 + do {
132104 + rslt = MCR_get_rslt(qm_in(MCR));
132105 + } while (!MCR_rslt_idle(rslt));
132106 + if (MCR_rslt_ok(rslt))
132107 + return 0;
132108 + if (MCR_rslt_eaccess(rslt))
132109 + return -EACCES;
132110 + if (MCR_rslt_inval(rslt))
132111 + return -EINVAL;
132112 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
132113 + return -ENOSYS;
132114 +}
132115 +
132116 +/*****************/
132117 +/* Config driver */
132118 +/*****************/
132119 +
132120 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
132121 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
132122 +
132123 +/* We support only one of these */
132124 +static struct qman *qm;
132125 +static struct device_node *qm_node;
132126 +
132127 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
132128 + * during qman_init_ccsr(). */
132129 +static dma_addr_t fqd_a, pfdr_a;
132130 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
132131 +
132132 +static int qman_fqd(struct reserved_mem *rmem)
132133 +{
132134 + fqd_a = rmem->base;
132135 + fqd_sz = rmem->size;
132136 +
132137 + WARN_ON(!(fqd_a && fqd_sz));
132138 +
132139 + return 0;
132140 +}
132141 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
132142 +
132143 +static int qman_pfdr(struct reserved_mem *rmem)
132144 +{
132145 + pfdr_a = rmem->base;
132146 + pfdr_sz = rmem->size;
132147 +
132148 + WARN_ON(!(pfdr_a && pfdr_sz));
132149 +
132150 + return 0;
132151 +}
132152 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
132153 +
132154 +size_t get_qman_fqd_size()
132155 +{
132156 + return fqd_sz;
132157 +}
132158 +
132159 +/* Parse the <name> property to extract the memory location and size and
132160 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
132161 + * size. Also flush this memory range from data cache so that QMAN originated
132162 + * transactions for this memory region could be marked non-coherent.
132163 + */
132164 +static __init int parse_mem_property(struct device_node *node, const char *name,
132165 + dma_addr_t *addr, size_t *sz, int zero)
132166 +{
132167 + int ret;
132168 +
132169 + /* If using a "zero-pma", don't try to zero it, even if you asked */
132170 + if (zero && of_find_property(node, "zero-pma", &ret)) {
132171 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
132172 + zero = 0;
132173 + }
132174 +
132175 + if (zero) {
132176 + /* map as cacheable, non-guarded */
132177 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132178 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
132179 +#else
132180 + void __iomem *tmpp = ioremap(*addr, *sz);
132181 +#endif
132182 +
132183 + if (!tmpp)
132184 + return -ENOMEM;
132185 + memset_io(tmpp, 0, *sz);
132186 + flush_dcache_range((unsigned long)tmpp,
132187 + (unsigned long)tmpp + *sz);
132188 + iounmap(tmpp);
132189 + }
132190 +
132191 + return 0;
132192 +}
132193 +
132194 +/* TODO:
132195 + * - there is obviously no handling of errors,
132196 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
132197 + * both memory resources to zero.
132198 + */
132199 +static int __init fsl_qman_init(struct device_node *node)
132200 +{
132201 + struct resource res;
132202 + resource_size_t len;
132203 + u32 __iomem *regs;
132204 + const char *s;
132205 + int ret, standby = 0;
132206 + u16 id;
132207 + u8 major, minor, cfg;
132208 + ret = of_address_to_resource(node, 0, &res);
132209 + if (ret) {
132210 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
132211 + return ret;
132212 + }
132213 + s = of_get_property(node, "fsl,hv-claimable", &ret);
132214 + if (s && !strcmp(s, "standby"))
132215 + standby = 1;
132216 + if (!standby) {
132217 + ret = parse_mem_property(node, "fsl,qman-fqd",
132218 + &fqd_a, &fqd_sz, 1);
132219 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
132220 + BUG_ON(ret);
132221 + ret = parse_mem_property(node, "fsl,qman-pfdr",
132222 + &pfdr_a, &pfdr_sz, 0);
132223 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
132224 + BUG_ON(ret);
132225 + }
132226 + /* Global configuration */
132227 + len = resource_size(&res);
132228 + if (len != (unsigned long)len)
132229 + return -EINVAL;
132230 + regs = ioremap(res.start, (unsigned long)len);
132231 + qm = qm_create(regs);
132232 + qm_node = node;
132233 + qm_get_version(qm, &id, &major, &minor, &cfg);
132234 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
132235 + if (!qman_ip_rev) {
132236 + if ((major == 1) && (minor == 0)) {
132237 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
132238 + iounmap(regs);
132239 + return -ENODEV;
132240 + } else if ((major == 1) && (minor == 1))
132241 + qman_ip_rev = QMAN_REV11;
132242 + else if ((major == 1) && (minor == 2))
132243 + qman_ip_rev = QMAN_REV12;
132244 + else if ((major == 2) && (minor == 0))
132245 + qman_ip_rev = QMAN_REV20;
132246 + else if ((major == 3) && (minor == 0))
132247 + qman_ip_rev = QMAN_REV30;
132248 + else if ((major == 3) && (minor == 1))
132249 + qman_ip_rev = QMAN_REV31;
132250 + else if ((major == 3) && (minor == 2))
132251 + qman_ip_rev = QMAN_REV32;
132252 + else {
132253 + pr_warn("unknown Qman version, default to rev1.1\n");
132254 + qman_ip_rev = QMAN_REV11;
132255 + }
132256 + qman_ip_cfg = cfg;
132257 + }
132258 +
132259 + if (standby) {
132260 + pr_info(" -> in standby mode\n");
132261 + return 0;
132262 + }
132263 + return 0;
132264 +}
132265 +
132266 +int qman_have_ccsr(void)
132267 +{
132268 + return qm ? 1 : 0;
132269 +}
132270 +
132271 +__init int qman_init_early(void)
132272 +{
132273 + struct device_node *dn;
132274 + int ret;
132275 +
132276 + for_each_compatible_node(dn, NULL, "fsl,qman") {
132277 + if (qm)
132278 + pr_err("%s: only one 'fsl,qman' allowed\n",
132279 + dn->full_name);
132280 + else {
132281 + if (!of_device_is_available(dn))
132282 + continue;
132283 +
132284 + ret = fsl_qman_init(dn);
132285 + BUG_ON(ret);
132286 + }
132287 + }
132288 + return 0;
132289 +}
132290 +postcore_initcall_sync(qman_init_early);
132291 +
132292 +static void log_edata_bits(u32 bit_count)
132293 +{
132294 + u32 i, j, mask = 0xffffffff;
132295 +
132296 + pr_warn("Qman ErrInt, EDATA:\n");
132297 + i = bit_count/32;
132298 + if (bit_count%32) {
132299 + i++;
132300 + mask = ~(mask << bit_count%32);
132301 + }
132302 + j = 16-i;
132303 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
132304 + j++;
132305 + for (; j < 16; j++)
132306 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
132307 +}
132308 +
132309 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
132310 +{
132311 + union qman_ecir ecir_val;
132312 + union qman_eadr eadr_val;
132313 +
132314 + ecir_val.ecir_raw = qm_in(ECIR);
132315 + /* Is portal info valid */
132316 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132317 + union qman_ecir2 ecir2_val;
132318 + ecir2_val.ecir2_raw = qm_in(ECIR2);
132319 + if (ecsr_val & PORTAL_ECSR_ERR) {
132320 + pr_warn("Qman ErrInt: %s id %d\n",
132321 + (ecir2_val.info.portal_type) ?
132322 + "DCP" : "SWP", ecir2_val.info.portal_num);
132323 + }
132324 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
132325 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132326 + ecir_val.info.fqid);
132327 + }
132328 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132329 + eadr_val.eadr_raw = qm_in(EADR);
132330 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132331 + error_mdata[eadr_val.info_rev3.memid].txt,
132332 + error_mdata[eadr_val.info_rev3.memid].addr_mask
132333 + & eadr_val.info_rev3.eadr);
132334 + log_edata_bits(
132335 + error_mdata[eadr_val.info_rev3.memid].bits);
132336 + }
132337 + } else {
132338 + if (ecsr_val & PORTAL_ECSR_ERR) {
132339 + pr_warn("Qman ErrInt: %s id %d\n",
132340 + (ecir_val.info.portal_type) ?
132341 + "DCP" : "SWP", ecir_val.info.portal_num);
132342 + }
132343 + if (ecsr_val & FQID_ECSR_ERR) {
132344 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132345 + ecir_val.info.fqid);
132346 + }
132347 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132348 + eadr_val.eadr_raw = qm_in(EADR);
132349 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132350 + error_mdata[eadr_val.info.memid].txt,
132351 + error_mdata[eadr_val.info.memid].addr_mask
132352 + & eadr_val.info.eadr);
132353 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
132354 + }
132355 + }
132356 +}
132357 +
132358 +/* Qman interrupt handler */
132359 +static irqreturn_t qman_isr(int irq, void *ptr)
132360 +{
132361 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
132362 +
132363 + ier_val = qm_err_isr_enable_read(qm);
132364 + isr_val = qm_err_isr_status_read(qm);
132365 + ecsr_val = qm_in(ECSR);
132366 + isr_mask = isr_val & ier_val;
132367 +
132368 + if (!isr_mask)
132369 + return IRQ_NONE;
132370 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
132371 + if (qman_hwerr_txts[i].mask & isr_mask) {
132372 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
132373 + if (qman_hwerr_txts[i].mask & ecsr_val) {
132374 + log_additional_error_info(isr_mask, ecsr_val);
132375 + /* Re-arm error capture registers */
132376 + qm_out(ECSR, ecsr_val);
132377 + }
132378 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
132379 + pr_devel("Qman un-enabling error 0x%x\n",
132380 + qman_hwerr_txts[i].mask);
132381 + ier_val &= ~qman_hwerr_txts[i].mask;
132382 + qm_err_isr_enable_write(qm, ier_val);
132383 + }
132384 + }
132385 + }
132386 + qm_err_isr_status_clear(qm, isr_val);
132387 + return IRQ_HANDLED;
132388 +}
132389 +
132390 +static int __bind_irq(void)
132391 +{
132392 + int ret, err_irq;
132393 +
132394 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
132395 + if (err_irq == 0) {
132396 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
132397 + "interrupts");
132398 + return -ENODEV;
132399 + }
132400 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
132401 + if (ret) {
132402 + pr_err("request_irq() failed %d for '%s'\n", ret,
132403 + qm_node->full_name);
132404 + return -ENODEV;
132405 + }
132406 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
132407 + * to resource allocation during driver init). */
132408 + qm_err_isr_status_clear(qm, 0xffffffff);
132409 + /* Enable Error Interrupts */
132410 + qm_err_isr_enable_write(qm, 0xffffffff);
132411 + return 0;
132412 +}
132413 +
132414 +int qman_init_ccsr(struct device_node *node)
132415 +{
132416 + int ret;
132417 + if (!qman_have_ccsr())
132418 + return 0;
132419 + if (node != qm_node)
132420 + return -EINVAL;
132421 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132422 + /* TEMP for LS1043 : should be done in uboot */
132423 + qm_out(QCSP_BARE, 0x5);
132424 + qm_out(QCSP_BAR, 0x0);
132425 +#endif
132426 + /* FQD memory */
132427 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
132428 + /* PFDR memory */
132429 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
132430 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
132431 + /* thresholds */
132432 + qm_set_pfdr_threshold(qm, 512, 64);
132433 + qm_set_sfdr_threshold(qm, 128);
132434 + /* clear stale PEBI bit from interrupt status register */
132435 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
132436 + /* corenet initiator settings */
132437 + qm_set_corenet_initiator(qm);
132438 + /* HID settings */
132439 + qm_set_hid(qm);
132440 + /* Set scheduling weights to defaults */
132441 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
132442 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
132443 + /* We are not prepared to accept ERNs for hardware enqueues */
132444 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
132445 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
132446 + /* Initialise Error Interrupt Handler */
132447 + ret = __bind_irq();
132448 + if (ret)
132449 + return ret;
132450 + return 0;
132451 +}
132452 +
132453 +#define LIO_CFG_LIODN_MASK 0x0fff0000
132454 +void qman_liodn_fixup(u16 channel)
132455 +{
132456 + static int done;
132457 + static u32 liodn_offset;
132458 + u32 before, after;
132459 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132460 +
132461 + if (!qman_have_ccsr())
132462 + return;
132463 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132464 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
132465 + else
132466 + before = qm_in(QCSP_LIO_CFG(idx));
132467 + if (!done) {
132468 + liodn_offset = before & LIO_CFG_LIODN_MASK;
132469 + done = 1;
132470 + return;
132471 + }
132472 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
132473 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132474 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
132475 + else
132476 + qm_out(QCSP_LIO_CFG(idx), after);
132477 +}
132478 +
132479 +#define IO_CFG_SDEST_MASK 0x00ff0000
132480 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
132481 +{
132482 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132483 + u32 before, after;
132484 +
132485 + if (!qman_have_ccsr())
132486 + return -ENODEV;
132487 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
132488 + /* LS1043A - only one L2 cache */
132489 + cpu_idx = 0;
132490 + }
132491 +
132492 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132493 + before = qm_in(REV3_QCSP_IO_CFG(idx));
132494 + /* Each pair of vcpu share the same SRQ(SDEST) */
132495 + cpu_idx /= 2;
132496 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132497 + qm_out(REV3_QCSP_IO_CFG(idx), after);
132498 + } else {
132499 + before = qm_in(QCSP_IO_CFG(idx));
132500 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132501 + qm_out(QCSP_IO_CFG(idx), after);
132502 + }
132503 + return 0;
132504 +}
132505 +
132506 +#define MISC_CFG_WPM_MASK 0x00000002
132507 +int qm_set_wpm(int wpm)
132508 +{
132509 + u32 before;
132510 + u32 after;
132511 +
132512 + if (!qman_have_ccsr())
132513 + return -ENODEV;
132514 +
132515 + before = qm_in(MISC_CFG);
132516 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
132517 + qm_out(MISC_CFG, after);
132518 + return 0;
132519 +}
132520 +
132521 +int qm_get_wpm(int *wpm)
132522 +{
132523 + u32 before;
132524 +
132525 + if (!qman_have_ccsr())
132526 + return -ENODEV;
132527 +
132528 + before = qm_in(MISC_CFG);
132529 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
132530 + return 0;
132531 +}
132532 +
132533 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
132534 + * PRES = (2^22 / credit update reference period) * QMan clock period
132535 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
132536 + */
132537 +
132538 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
132539 +{
132540 + u64 temp;
132541 + u16 pres;
132542 +
132543 + if (!qman_have_ccsr())
132544 + return -ENODEV;
132545 +
132546 + temp = 0x400000 * 100;
132547 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
132548 + temp *= 10000000;
132549 + do_div(temp, qman_clk);
132550 + pres = (u16) temp;
132551 + qm_out(CEETM_CFG_IDX, portal);
132552 + qm_out(CEETM_CFG_PRES, pres);
132553 + return 0;
132554 +}
132555 +
132556 +int qman_ceetm_get_prescaler(u16 *pres)
132557 +{
132558 + if (!qman_have_ccsr())
132559 + return -ENODEV;
132560 + *pres = (u16)qm_in(CEETM_CFG_PRES);
132561 + return 0;
132562 +}
132563 +
132564 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
132565 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
132566 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
132567 +{
132568 + u32 dcp_cfg;
132569 +
132570 + if (!qman_have_ccsr())
132571 + return -ENODEV;
132572 +
132573 + dcp_cfg = qm_in(DCP_CFG(portal));
132574 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
132575 + qm_out(DCP_CFG(portal), dcp_cfg);
132576 + return 0;
132577 +}
132578 +
132579 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
132580 +{
132581 + u32 dcp_cfg;
132582 +
132583 + if (!qman_have_ccsr())
132584 + return -ENODEV;
132585 + dcp_cfg = qm_in(DCP_CFG(portal));
132586 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
132587 + qm_out(DCP_CFG(portal), dcp_cfg);
132588 + return 0;
132589 +}
132590 +
132591 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
132592 +{
132593 + if (!qman_have_ccsr())
132594 + return -ENODEV;
132595 + *num = qm_in(CEETM_XSFDR_IN_USE);
132596 + return 0;
132597 +}
132598 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
132599 +
132600 +#ifdef CONFIG_SYSFS
132601 +
132602 +#define DRV_NAME "fsl-qman"
132603 +#define DCP_MAX_ID 3
132604 +#define DCP_MIN_ID 0
132605 +
132606 +static ssize_t show_pfdr_fpc(struct device *dev,
132607 + struct device_attribute *dev_attr, char *buf)
132608 +{
132609 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
132610 +};
132611 +
132612 +static ssize_t show_dlm_avg(struct device *dev,
132613 + struct device_attribute *dev_attr, char *buf)
132614 +{
132615 + u32 data;
132616 + int i;
132617 +
132618 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
132619 + return -EINVAL;
132620 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
132621 + return -EINVAL;
132622 + data = qm_in(DCP_DLM_AVG(i));
132623 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
132624 + (data & 0x000000ff)*390625);
132625 +};
132626 +
132627 +static ssize_t set_dlm_avg(struct device *dev,
132628 + struct device_attribute *dev_attr, const char *buf, size_t count)
132629 +{
132630 + unsigned long val;
132631 + int i;
132632 +
132633 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
132634 + return -EINVAL;
132635 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
132636 + return -EINVAL;
132637 + if (kstrtoul(buf, 0, &val)) {
132638 + dev_dbg(dev, "invalid input %s\n", buf);
132639 + return -EINVAL;
132640 + }
132641 + qm_out(DCP_DLM_AVG(i), val);
132642 + return count;
132643 +};
132644 +
132645 +static ssize_t show_pfdr_cfg(struct device *dev,
132646 + struct device_attribute *dev_attr, char *buf)
132647 +{
132648 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
132649 +};
132650 +
132651 +static ssize_t set_pfdr_cfg(struct device *dev,
132652 + struct device_attribute *dev_attr, const char *buf, size_t count)
132653 +{
132654 + unsigned long val;
132655 +
132656 + if (kstrtoul(buf, 0, &val)) {
132657 + dev_dbg(dev, "invalid input %s\n", buf);
132658 + return -EINVAL;
132659 + }
132660 + qm_out(PFDR_CFG, val);
132661 + return count;
132662 +};
132663 +
132664 +static ssize_t show_sfdr_in_use(struct device *dev,
132665 + struct device_attribute *dev_attr, char *buf)
132666 +{
132667 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
132668 +};
132669 +
132670 +static ssize_t show_idle_stat(struct device *dev,
132671 + struct device_attribute *dev_attr, char *buf)
132672 +{
132673 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
132674 +};
132675 +
132676 +static ssize_t show_ci_rlm_avg(struct device *dev,
132677 + struct device_attribute *dev_attr, char *buf)
132678 +{
132679 + u32 data = qm_in(CI_RLM_AVG);
132680 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
132681 + (data & 0x000000ff)*390625);
132682 +};
132683 +
132684 +static ssize_t set_ci_rlm_avg(struct device *dev,
132685 + struct device_attribute *dev_attr, const char *buf, size_t count)
132686 +{
132687 + unsigned long val;
132688 +
132689 + if (kstrtoul(buf, 0, &val)) {
132690 + dev_dbg(dev, "invalid input %s\n", buf);
132691 + return -EINVAL;
132692 + }
132693 + qm_out(CI_RLM_AVG, val);
132694 + return count;
132695 +};
132696 +
132697 +static ssize_t show_err_isr(struct device *dev,
132698 + struct device_attribute *dev_attr, char *buf)
132699 +{
132700 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
132701 +};
132702 +
132703 +#define SBEC_MAX_ID 14
132704 +#define SBEC_MIN_ID 0
132705 +
132706 +static ssize_t show_sbec(struct device *dev,
132707 + struct device_attribute *dev_attr, char *buf)
132708 +{
132709 + int i;
132710 +
132711 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
132712 + return -EINVAL;
132713 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
132714 + return -EINVAL;
132715 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
132716 +};
132717 +
132718 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
132719 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
132720 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
132721 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
132722 + show_ci_rlm_avg, set_ci_rlm_avg);
132723 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
132724 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
132725 +
132726 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132727 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132728 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132729 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
132730 +
132731 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
132732 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
132733 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
132734 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
132735 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
132736 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
132737 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
132738 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
132739 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
132740 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
132741 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
132742 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
132743 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
132744 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
132745 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
132746 +
132747 +static struct attribute *qman_dev_attributes[] = {
132748 + &dev_attr_pfdr_fpc.attr,
132749 + &dev_attr_pfdr_cfg.attr,
132750 + &dev_attr_idle_stat.attr,
132751 + &dev_attr_ci_rlm_avg.attr,
132752 + &dev_attr_err_isr.attr,
132753 + &dev_attr_dcp0_dlm_avg.attr,
132754 + &dev_attr_dcp1_dlm_avg.attr,
132755 + &dev_attr_dcp2_dlm_avg.attr,
132756 + &dev_attr_dcp3_dlm_avg.attr,
132757 + /* sfdr_in_use will be added if necessary */
132758 + NULL
132759 +};
132760 +
132761 +static struct attribute *qman_dev_ecr_attributes[] = {
132762 + &dev_attr_sbec_0.attr,
132763 + &dev_attr_sbec_1.attr,
132764 + &dev_attr_sbec_2.attr,
132765 + &dev_attr_sbec_3.attr,
132766 + &dev_attr_sbec_4.attr,
132767 + &dev_attr_sbec_5.attr,
132768 + &dev_attr_sbec_6.attr,
132769 + &dev_attr_sbec_7.attr,
132770 + &dev_attr_sbec_8.attr,
132771 + &dev_attr_sbec_9.attr,
132772 + &dev_attr_sbec_10.attr,
132773 + &dev_attr_sbec_11.attr,
132774 + &dev_attr_sbec_12.attr,
132775 + &dev_attr_sbec_13.attr,
132776 + &dev_attr_sbec_14.attr,
132777 + NULL
132778 +};
132779 +
132780 +/* root level */
132781 +static const struct attribute_group qman_dev_attr_grp = {
132782 + .name = NULL,
132783 + .attrs = qman_dev_attributes
132784 +};
132785 +static const struct attribute_group qman_dev_ecr_grp = {
132786 + .name = "error_capture",
132787 + .attrs = qman_dev_ecr_attributes
132788 +};
132789 +
132790 +static int of_fsl_qman_remove(struct platform_device *ofdev)
132791 +{
132792 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
132793 + return 0;
132794 +};
132795 +
132796 +static int of_fsl_qman_probe(struct platform_device *ofdev)
132797 +{
132798 + int ret;
132799 +
132800 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
132801 + if (ret)
132802 + goto done;
132803 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
132804 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
132805 + if (ret)
132806 + goto del_group_0;
132807 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
132808 + if (ret)
132809 + goto del_group_0;
132810 +
132811 + goto done;
132812 +
132813 +del_group_0:
132814 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
132815 +done:
132816 + if (ret)
132817 + dev_err(&ofdev->dev,
132818 + "Cannot create dev attributes ret=%d\n", ret);
132819 + return ret;
132820 +};
132821 +
132822 +static struct of_device_id of_fsl_qman_ids[] = {
132823 + {
132824 + .compatible = "fsl,qman",
132825 + },
132826 + {}
132827 +};
132828 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
132829 +
132830 +#ifdef CONFIG_SUSPEND
132831 +
132832 +static u32 saved_isdr;
132833 +static int qman_pm_suspend_noirq(struct device *dev)
132834 +{
132835 + uint32_t idle_state;
132836 +
132837 + suspend_unused_qportal();
132838 + /* save isdr, disable all, clear isr */
132839 + saved_isdr = qm_err_isr_disable_read(qm);
132840 + qm_err_isr_disable_write(qm, 0xffffffff);
132841 + qm_err_isr_status_clear(qm, 0xffffffff);
132842 + idle_state = qm_in(IDLE_STAT);
132843 + if (!(idle_state & 0x1)) {
132844 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
132845 + qm_err_isr_disable_write(qm, saved_isdr);
132846 + resume_unused_qportal();
132847 + return -EBUSY;
132848 + }
132849 +#ifdef CONFIG_PM_DEBUG
132850 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
132851 +#endif
132852 + return 0;
132853 +}
132854 +
132855 +static int qman_pm_resume_noirq(struct device *dev)
132856 +{
132857 + /* restore isdr */
132858 + qm_err_isr_disable_write(qm, saved_isdr);
132859 + resume_unused_qportal();
132860 + return 0;
132861 +}
132862 +#else
132863 +#define qman_pm_suspend_noirq NULL
132864 +#define qman_pm_resume_noirq NULL
132865 +#endif
132866 +
132867 +static const struct dev_pm_ops qman_pm_ops = {
132868 + .suspend_noirq = qman_pm_suspend_noirq,
132869 + .resume_noirq = qman_pm_resume_noirq,
132870 +};
132871 +
132872 +static struct platform_driver of_fsl_qman_driver = {
132873 + .driver = {
132874 + .owner = THIS_MODULE,
132875 + .name = DRV_NAME,
132876 + .of_match_table = of_fsl_qman_ids,
132877 + .pm = &qman_pm_ops,
132878 + },
132879 + .probe = of_fsl_qman_probe,
132880 + .remove = of_fsl_qman_remove,
132881 +};
132882 +
132883 +static int qman_ctrl_init(void)
132884 +{
132885 + return platform_driver_register(&of_fsl_qman_driver);
132886 +}
132887 +
132888 +static void qman_ctrl_exit(void)
132889 +{
132890 + platform_driver_unregister(&of_fsl_qman_driver);
132891 +}
132892 +
132893 +module_init(qman_ctrl_init);
132894 +module_exit(qman_ctrl_exit);
132895 +
132896 +#endif /* CONFIG_SYSFS */
132897 --- /dev/null
132898 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
132899 @@ -0,0 +1,1594 @@
132900 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
132901 + *
132902 + * Redistribution and use in source and binary forms, with or without
132903 + * modification, are permitted provided that the following conditions are met:
132904 + * * Redistributions of source code must retain the above copyright
132905 + * notice, this list of conditions and the following disclaimer.
132906 + * * Redistributions in binary form must reproduce the above copyright
132907 + * notice, this list of conditions and the following disclaimer in the
132908 + * documentation and/or other materials provided with the distribution.
132909 + * * Neither the name of Freescale Semiconductor nor the
132910 + * names of its contributors may be used to endorse or promote products
132911 + * derived from this software without specific prior written permission.
132912 + *
132913 + *
132914 + * ALTERNATIVELY, this software may be distributed under the terms of the
132915 + * GNU General Public License ("GPL") as published by the Free Software
132916 + * Foundation, either version 2 of that License or (at your option) any
132917 + * later version.
132918 + *
132919 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132920 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132921 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132922 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132923 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132924 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132925 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132926 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132927 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132928 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132929 + */
132930 +#include "qman_private.h"
132931 +
132932 +#define MAX_FQID (0x00ffffff)
132933 +#define QM_FQD_BLOCK_SIZE 64
132934 +#define QM_FQD_AR (0xC10)
132935 +
132936 +static u32 fqid_max;
132937 +static u64 qman_ccsr_start;
132938 +static u64 qman_ccsr_size;
132939 +
132940 +static const char * const state_txt[] = {
132941 + "Out of Service",
132942 + "Retired",
132943 + "Tentatively Scheduled",
132944 + "Truly Scheduled",
132945 + "Parked",
132946 + "Active, Active Held or Held Suspended",
132947 + "Unknown State 6",
132948 + "Unknown State 7",
132949 + NULL,
132950 +};
132951 +
132952 +static const u8 fqd_states[] = {
132953 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
132954 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
132955 + QM_MCR_NP_STATE_ACTIVE};
132956 +
132957 +struct mask_to_text {
132958 + u16 mask;
132959 + const char *txt;
132960 +};
132961 +
132962 +struct mask_filter_s {
132963 + u16 mask;
132964 + u8 filter;
132965 +};
132966 +
132967 +static const struct mask_filter_s mask_filter[] = {
132968 + {QM_FQCTRL_PREFERINCACHE, 0},
132969 + {QM_FQCTRL_PREFERINCACHE, 1},
132970 + {QM_FQCTRL_HOLDACTIVE, 0},
132971 + {QM_FQCTRL_HOLDACTIVE, 1},
132972 + {QM_FQCTRL_AVOIDBLOCK, 0},
132973 + {QM_FQCTRL_AVOIDBLOCK, 1},
132974 + {QM_FQCTRL_FORCESFDR, 0},
132975 + {QM_FQCTRL_FORCESFDR, 1},
132976 + {QM_FQCTRL_CPCSTASH, 0},
132977 + {QM_FQCTRL_CPCSTASH, 1},
132978 + {QM_FQCTRL_CTXASTASHING, 0},
132979 + {QM_FQCTRL_CTXASTASHING, 1},
132980 + {QM_FQCTRL_ORP, 0},
132981 + {QM_FQCTRL_ORP, 1},
132982 + {QM_FQCTRL_TDE, 0},
132983 + {QM_FQCTRL_TDE, 1},
132984 + {QM_FQCTRL_CGE, 0},
132985 + {QM_FQCTRL_CGE, 1}
132986 +};
132987 +
132988 +static const struct mask_to_text fq_ctrl_text_list[] = {
132989 + {
132990 + .mask = QM_FQCTRL_PREFERINCACHE,
132991 + .txt = "Prefer in cache",
132992 + },
132993 + {
132994 + .mask = QM_FQCTRL_HOLDACTIVE,
132995 + .txt = "Hold active in portal",
132996 + },
132997 + {
132998 + .mask = QM_FQCTRL_AVOIDBLOCK,
132999 + .txt = "Avoid Blocking",
133000 + },
133001 + {
133002 + .mask = QM_FQCTRL_FORCESFDR,
133003 + .txt = "High-priority SFDRs",
133004 + },
133005 + {
133006 + .mask = QM_FQCTRL_CPCSTASH,
133007 + .txt = "CPC Stash Enable",
133008 + },
133009 + {
133010 + .mask = QM_FQCTRL_CTXASTASHING,
133011 + .txt = "Context-A stashing",
133012 + },
133013 + {
133014 + .mask = QM_FQCTRL_ORP,
133015 + .txt = "ORP Enable",
133016 + },
133017 + {
133018 + .mask = QM_FQCTRL_TDE,
133019 + .txt = "Tail-Drop Enable",
133020 + },
133021 + {
133022 + .mask = QM_FQCTRL_CGE,
133023 + .txt = "Congestion Group Enable",
133024 + },
133025 + {
133026 + .mask = 0,
133027 + .txt = NULL,
133028 + }
133029 +};
133030 +
133031 +static const char *get_fqd_ctrl_text(u16 mask)
133032 +{
133033 + int i = 0;
133034 +
133035 + while (fq_ctrl_text_list[i].txt != NULL) {
133036 + if (fq_ctrl_text_list[i].mask == mask)
133037 + return fq_ctrl_text_list[i].txt;
133038 + i++;
133039 + }
133040 + return NULL;
133041 +}
133042 +
133043 +static const struct mask_to_text stashing_text_list[] = {
133044 + {
133045 + .mask = QM_STASHING_EXCL_CTX,
133046 + .txt = "FQ Ctx Stash"
133047 + },
133048 + {
133049 + .mask = QM_STASHING_EXCL_DATA,
133050 + .txt = "Frame Data Stash",
133051 + },
133052 + {
133053 + .mask = QM_STASHING_EXCL_ANNOTATION,
133054 + .txt = "Frame Annotation Stash",
133055 + },
133056 + {
133057 + .mask = 0,
133058 + .txt = NULL,
133059 + },
133060 +};
133061 +
133062 +static int user_input_convert(const char __user *user_buf, size_t count,
133063 + unsigned long *val)
133064 +{
133065 + char buf[12];
133066 +
133067 + if (count > sizeof(buf) - 1)
133068 + return -EINVAL;
133069 + if (copy_from_user(buf, user_buf, count))
133070 + return -EFAULT;
133071 + buf[count] = '\0';
133072 + if (kstrtoul(buf, 0, val))
133073 + return -EINVAL;
133074 + return 0;
133075 +}
133076 +
133077 +struct line_buffer_fq {
133078 + u32 buf[8];
133079 + u32 buf_cnt;
133080 + int line_cnt;
133081 +};
133082 +
133083 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
133084 + struct seq_file *file)
133085 +{
133086 + line_buf->buf[line_buf->buf_cnt] = fqid;
133087 + line_buf->buf_cnt++;
133088 + if (line_buf->buf_cnt == 8) {
133089 + /* Buffer is full, flush it */
133090 + if (line_buf->line_cnt != 0)
133091 + seq_puts(file, ",\n");
133092 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
133093 + "0x%06x,0x%06x,0x%06x",
133094 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
133095 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
133096 + line_buf->buf[6], line_buf->buf[7]);
133097 + line_buf->buf_cnt = 0;
133098 + line_buf->line_cnt++;
133099 + }
133100 +}
133101 +
133102 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
133103 + struct seq_file *file)
133104 +{
133105 + if (line_buf->buf_cnt) {
133106 + int y = 0;
133107 + if (line_buf->line_cnt != 0)
133108 + seq_puts(file, ",\n");
133109 + while (y != line_buf->buf_cnt) {
133110 + if (y+1 == line_buf->buf_cnt)
133111 + seq_printf(file, "0x%06x", line_buf->buf[y]);
133112 + else
133113 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
133114 + y++;
133115 + }
133116 + line_buf->line_cnt++;
133117 + }
133118 + if (line_buf->line_cnt)
133119 + seq_putc(file, '\n');
133120 +}
133121 +
133122 +static struct dentry *dfs_root; /* debugfs root directory */
133123 +
133124 +/*******************************************************************************
133125 + * Query Frame Queue Non Programmable Fields
133126 + ******************************************************************************/
133127 +struct query_fq_np_fields_data_s {
133128 + u32 fqid;
133129 +};
133130 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
133131 + .fqid = 1,
133132 +};
133133 +
133134 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
133135 +{
133136 + int ret;
133137 + struct qm_mcr_queryfq_np np;
133138 + struct qman_fq fq;
133139 +
133140 + fq.fqid = query_fq_np_fields_data.fqid;
133141 + ret = qman_query_fq_np(&fq, &np);
133142 + if (ret)
133143 + return ret;
133144 + /* Print state */
133145 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
133146 + fq.fqid);
133147 + seq_printf(file, " force eligible pending: %s\n",
133148 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
133149 + seq_printf(file, " retirement pending: %s\n",
133150 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
133151 + seq_printf(file, " state: %s\n",
133152 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
133153 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
133154 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
133155 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
133156 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
133157 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
133158 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
133159 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
133160 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
133161 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
133162 + seq_printf(file, " is: ics_surp contains a %s\n",
133163 + (np.is) ? "deficit" : "surplus");
133164 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
133165 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
133166 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
133167 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
133168 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
133169 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
133170 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
133171 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
133172 + return 0;
133173 +}
133174 +
133175 +static int query_fq_np_fields_open(struct inode *inode,
133176 + struct file *file)
133177 +{
133178 + return single_open(file, query_fq_np_fields_show, NULL);
133179 +}
133180 +
133181 +static ssize_t query_fq_np_fields_write(struct file *f,
133182 + const char __user *buf, size_t count, loff_t *off)
133183 +{
133184 + int ret;
133185 + unsigned long val;
133186 +
133187 + ret = user_input_convert(buf, count, &val);
133188 + if (ret)
133189 + return ret;
133190 + if (val > MAX_FQID)
133191 + return -EINVAL;
133192 + query_fq_np_fields_data.fqid = (u32)val;
133193 + return count;
133194 +}
133195 +
133196 +static const struct file_operations query_fq_np_fields_fops = {
133197 + .owner = THIS_MODULE,
133198 + .open = query_fq_np_fields_open,
133199 + .read = seq_read,
133200 + .write = query_fq_np_fields_write,
133201 + .release = single_release,
133202 +};
133203 +
133204 +/*******************************************************************************
133205 + * Frame Queue Programmable Fields
133206 + ******************************************************************************/
133207 +struct query_fq_fields_data_s {
133208 + u32 fqid;
133209 +};
133210 +
133211 +static struct query_fq_fields_data_s query_fq_fields_data = {
133212 + .fqid = 1,
133213 +};
133214 +
133215 +static int query_fq_fields_show(struct seq_file *file, void *offset)
133216 +{
133217 + int ret;
133218 + struct qm_fqd fqd;
133219 + struct qman_fq fq;
133220 + int i = 0;
133221 +
133222 + memset(&fqd, 0, sizeof(struct qm_fqd));
133223 + fq.fqid = query_fq_fields_data.fqid;
133224 + ret = qman_query_fq(&fq, &fqd);
133225 + if (ret)
133226 + return ret;
133227 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
133228 + fq.fqid);
133229 + seq_printf(file, " orprws: %u\n", fqd.orprws);
133230 + seq_printf(file, " oa: %u\n", fqd.oa);
133231 + seq_printf(file, " olws: %u\n", fqd.olws);
133232 +
133233 + seq_printf(file, " cgid: %u\n", fqd.cgid);
133234 +
133235 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
133236 + seq_puts(file, " fq_ctrl: None\n");
133237 + else {
133238 + i = 0;
133239 + seq_puts(file, " fq_ctrl:\n");
133240 + while (fq_ctrl_text_list[i].txt != NULL) {
133241 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
133242 + fq_ctrl_text_list[i].mask)
133243 + seq_printf(file, " %s\n",
133244 + fq_ctrl_text_list[i].txt);
133245 + i++;
133246 + }
133247 + }
133248 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
133249 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
133250 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
133251 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
133252 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
133253 +
133254 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
133255 +
133256 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
133257 + /* Any stashing configured */
133258 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
133259 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
133260 + else {
133261 + seq_puts(file, " ctx_a_stash_exclusive:\n");
133262 + i = 0;
133263 + while (stashing_text_list[i].txt != NULL) {
133264 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
133265 + seq_printf(file, " %s\n",
133266 + stashing_text_list[i].txt);
133267 + i++;
133268 + }
133269 + }
133270 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
133271 + fqd.context_a.stashing.annotation_cl);
133272 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
133273 + fqd.context_a.stashing.data_cl);
133274 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
133275 + fqd.context_a.stashing.context_cl);
133276 + return 0;
133277 +}
133278 +
133279 +static int query_fq_fields_open(struct inode *inode,
133280 + struct file *file)
133281 +{
133282 + return single_open(file, query_fq_fields_show, NULL);
133283 +}
133284 +
133285 +static ssize_t query_fq_fields_write(struct file *f,
133286 + const char __user *buf, size_t count, loff_t *off)
133287 +{
133288 + int ret;
133289 + unsigned long val;
133290 +
133291 + ret = user_input_convert(buf, count, &val);
133292 + if (ret)
133293 + return ret;
133294 + if (val > MAX_FQID)
133295 + return -EINVAL;
133296 + query_fq_fields_data.fqid = (u32)val;
133297 + return count;
133298 +}
133299 +
133300 +static const struct file_operations query_fq_fields_fops = {
133301 + .owner = THIS_MODULE,
133302 + .open = query_fq_fields_open,
133303 + .read = seq_read,
133304 + .write = query_fq_fields_write,
133305 + .release = single_release,
133306 +};
133307 +
133308 +/*******************************************************************************
133309 + * Query WQ lengths
133310 + ******************************************************************************/
133311 +struct query_wq_lengths_data_s {
133312 + union {
133313 + u16 channel_wq; /* ignores wq (3 lsbits) */
133314 + struct {
133315 + u16 id:13; /* qm_channel */
133316 + u16 __reserved:3;
133317 + } __packed channel;
133318 + };
133319 +};
133320 +static struct query_wq_lengths_data_s query_wq_lengths_data;
133321 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
133322 +{
133323 + int ret;
133324 + struct qm_mcr_querywq wq;
133325 + int i;
133326 +
133327 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
133328 + wq.channel.id = query_wq_lengths_data.channel.id;
133329 + ret = qman_query_wq(0, &wq);
133330 + if (ret)
133331 + return ret;
133332 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
133333 + for (i = 0; i < 8; i++)
133334 + /* mask out upper 4 bits since they are not part of length */
133335 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
133336 + return 0;
133337 +}
133338 +
133339 +static int query_wq_lengths_open(struct inode *inode,
133340 + struct file *file)
133341 +{
133342 + return single_open(file, query_wq_lengths_show, NULL);
133343 +}
133344 +
133345 +static ssize_t query_wq_lengths_write(struct file *f,
133346 + const char __user *buf, size_t count, loff_t *off)
133347 +{
133348 + int ret;
133349 + unsigned long val;
133350 +
133351 + ret = user_input_convert(buf, count, &val);
133352 + if (ret)
133353 + return ret;
133354 + if (val > 0xfff8)
133355 + return -EINVAL;
133356 + query_wq_lengths_data.channel.id = (u16)val;
133357 + return count;
133358 +}
133359 +
133360 +static const struct file_operations query_wq_lengths_fops = {
133361 + .owner = THIS_MODULE,
133362 + .open = query_wq_lengths_open,
133363 + .read = seq_read,
133364 + .write = query_wq_lengths_write,
133365 + .release = single_release,
133366 +};
133367 +
133368 +/*******************************************************************************
133369 + * Query CGR
133370 + ******************************************************************************/
133371 +struct query_cgr_s {
133372 + u8 cgid;
133373 +};
133374 +static struct query_cgr_s query_cgr_data;
133375 +
133376 +static int query_cgr_show(struct seq_file *file, void *offset)
133377 +{
133378 + int ret;
133379 + struct qm_mcr_querycgr cgrd;
133380 + struct qman_cgr cgr;
133381 + int i, j;
133382 + u32 mask;
133383 +
133384 + memset(&cgr, 0, sizeof(cgr));
133385 + memset(&cgrd, 0, sizeof(cgrd));
133386 + cgr.cgrid = query_cgr_data.cgid;
133387 + ret = qman_query_cgr(&cgr, &cgrd);
133388 + if (ret)
133389 + return ret;
133390 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
133391 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133392 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
133393 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
133394 + cgrd.cgr.wr_parm_g.Pn);
133395 +
133396 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133397 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
133398 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
133399 + cgrd.cgr.wr_parm_y.Pn);
133400 +
133401 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133402 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
133403 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
133404 + cgrd.cgr.wr_parm_r.Pn);
133405 +
133406 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133407 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
133408 +
133409 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
133410 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133411 + seq_puts(file, " cscn_targ_dcp:\n");
133412 + mask = 0x80000000;
133413 + for (i = 0; i < 32; i++) {
133414 + if (cgrd.cgr.cscn_targ & mask)
133415 + seq_printf(file, " send CSCN to dcp %u\n",
133416 + (31 - i));
133417 + mask >>= 1;
133418 + }
133419 +
133420 + seq_puts(file, " cscn_targ_swp:\n");
133421 + for (i = 0; i < 4; i++) {
133422 + mask = 0x80000000;
133423 + for (j = 0; j < 32; j++) {
133424 + if (cgrd.cscn_targ_swp[i] & mask)
133425 + seq_printf(file, " send CSCN to swp"
133426 + " %u\n", (127 - (i * 32) - j));
133427 + mask >>= 1;
133428 + }
133429 + }
133430 + } else {
133431 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
133432 + }
133433 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
133434 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
133435 +
133436 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133437 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
133438 +
133439 + seq_printf(file, " mode: %s\n",
133440 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133441 + "frame count" : "byte count");
133442 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
133443 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
133444 +
133445 + return 0;
133446 +}
133447 +
133448 +static int query_cgr_open(struct inode *inode, struct file *file)
133449 +{
133450 + return single_open(file, query_cgr_show, NULL);
133451 +}
133452 +
133453 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
133454 + size_t count, loff_t *off)
133455 +{
133456 + int ret;
133457 + unsigned long val;
133458 +
133459 + ret = user_input_convert(buf, count, &val);
133460 + if (ret)
133461 + return ret;
133462 + if (val > 0xff)
133463 + return -EINVAL;
133464 + query_cgr_data.cgid = (u8)val;
133465 + return count;
133466 +}
133467 +
133468 +static const struct file_operations query_cgr_fops = {
133469 + .owner = THIS_MODULE,
133470 + .open = query_cgr_open,
133471 + .read = seq_read,
133472 + .write = query_cgr_write,
133473 + .release = single_release,
133474 +};
133475 +
133476 +/*******************************************************************************
133477 + * Test Write CGR
133478 + ******************************************************************************/
133479 +struct test_write_cgr_s {
133480 + u64 i_bcnt;
133481 + u8 cgid;
133482 +};
133483 +static struct test_write_cgr_s test_write_cgr_data;
133484 +
133485 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
133486 +{
133487 + int ret;
133488 + struct qm_mcr_cgrtestwrite result;
133489 + struct qman_cgr cgr;
133490 + u64 i_bcnt;
133491 +
133492 + memset(&cgr, 0, sizeof(struct qman_cgr));
133493 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
133494 + cgr.cgrid = test_write_cgr_data.cgid;
133495 + i_bcnt = test_write_cgr_data.i_bcnt;
133496 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
133497 + if (ret)
133498 + return ret;
133499 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
133500 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133501 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
133502 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
133503 + result.cgr.wr_parm_g.Pn);
133504 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133505 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
133506 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
133507 + result.cgr.wr_parm_y.Pn);
133508 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133509 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
133510 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
133511 + result.cgr.wr_parm_r.Pn);
133512 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133513 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
133514 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
133515 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
133516 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
133517 + seq_printf(file, " cs: %u\n", result.cgr.cs);
133518 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133519 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
133520 +
133521 + /* Add Mode for Si 2 */
133522 + seq_printf(file, " mode: %s\n",
133523 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133524 + "frame count" : "byte count");
133525 +
133526 + seq_printf(file, " i_bcnt: %llu\n",
133527 + qm_mcr_cgrtestwrite_i_get64(&result));
133528 + seq_printf(file, " a_bcnt: %llu\n",
133529 + qm_mcr_cgrtestwrite_a_get64(&result));
133530 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
133531 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
133532 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
133533 + return 0;
133534 +}
133535 +
133536 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
133537 +{
133538 + return single_open(file, testwrite_cgr_show, NULL);
133539 +}
133540 +
133541 +static const struct file_operations testwrite_cgr_fops = {
133542 + .owner = THIS_MODULE,
133543 + .open = testwrite_cgr_open,
133544 + .read = seq_read,
133545 + .release = single_release,
133546 +};
133547 +
133548 +
133549 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
133550 +{
133551 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
133552 + return 0;
133553 +}
133554 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
133555 +{
133556 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
133557 +}
133558 +
133559 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
133560 + size_t count, loff_t *off)
133561 +{
133562 + int ret;
133563 + unsigned long val;
133564 +
133565 + ret = user_input_convert(buf, count, &val);
133566 + if (ret)
133567 + return ret;
133568 + test_write_cgr_data.i_bcnt = val;
133569 + return count;
133570 +}
133571 +
133572 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
133573 + .owner = THIS_MODULE,
133574 + .open = testwrite_cgr_ibcnt_open,
133575 + .read = seq_read,
133576 + .write = testwrite_cgr_ibcnt_write,
133577 + .release = single_release,
133578 +};
133579 +
133580 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
133581 +{
133582 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
133583 + return 0;
133584 +}
133585 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
133586 +{
133587 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
133588 +}
133589 +
133590 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
133591 + size_t count, loff_t *off)
133592 +{
133593 + int ret;
133594 + unsigned long val;
133595 +
133596 + ret = user_input_convert(buf, count, &val);
133597 + if (ret)
133598 + return ret;
133599 + if (val > 0xff)
133600 + return -EINVAL;
133601 + test_write_cgr_data.cgid = (u8)val;
133602 + return count;
133603 +}
133604 +
133605 +static const struct file_operations teswrite_cgr_cgrid_fops = {
133606 + .owner = THIS_MODULE,
133607 + .open = testwrite_cgr_cgrid_open,
133608 + .read = seq_read,
133609 + .write = testwrite_cgr_cgrid_write,
133610 + .release = single_release,
133611 +};
133612 +
133613 +/*******************************************************************************
133614 + * Query Congestion State
133615 + ******************************************************************************/
133616 +static int query_congestion_show(struct seq_file *file, void *offset)
133617 +{
133618 + int ret;
133619 + struct qm_mcr_querycongestion cs;
133620 + int i, j, in_cong = 0;
133621 + u32 mask;
133622 +
133623 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
133624 + ret = qman_query_congestion(&cs);
133625 + if (ret)
133626 + return ret;
133627 + seq_puts(file, "Query Congestion Result\n");
133628 + for (i = 0; i < 8; i++) {
133629 + mask = 0x80000000;
133630 + for (j = 0; j < 32; j++) {
133631 + if (cs.state.__state[i] & mask) {
133632 + in_cong = 1;
133633 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
133634 + "in congestion");
133635 + }
133636 + mask >>= 1;
133637 + }
133638 + }
133639 + if (!in_cong)
133640 + seq_puts(file, " All congestion groups not congested.\n");
133641 + return 0;
133642 +}
133643 +
133644 +static int query_congestion_open(struct inode *inode, struct file *file)
133645 +{
133646 + return single_open(file, query_congestion_show, NULL);
133647 +}
133648 +
133649 +static const struct file_operations query_congestion_fops = {
133650 + .owner = THIS_MODULE,
133651 + .open = query_congestion_open,
133652 + .read = seq_read,
133653 + .release = single_release,
133654 +};
133655 +
133656 +/*******************************************************************************
133657 + * Query CCGR
133658 + ******************************************************************************/
133659 +struct query_ccgr_s {
133660 + u32 ccgid;
133661 +};
133662 +static struct query_ccgr_s query_ccgr_data;
133663 +
133664 +static int query_ccgr_show(struct seq_file *file, void *offset)
133665 +{
133666 + int ret;
133667 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
133668 + struct qm_mcc_ceetm_ccgr_query query_opts;
133669 + int i, j;
133670 + u32 mask;
133671 +
133672 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
133673 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
133674 +
133675 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
133676 + return -EINVAL;
133677 +
133678 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
133679 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
133680 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
133681 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
133682 + if (ret)
133683 + return ret;
133684 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
133685 + query_opts.dcpid);
133686 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133687 + ccgr_query.cm_query.wr_parm_g.MA,
133688 + ccgr_query.cm_query.wr_parm_g.Mn,
133689 + ccgr_query.cm_query.wr_parm_g.SA,
133690 + ccgr_query.cm_query.wr_parm_g.Sn,
133691 + ccgr_query.cm_query.wr_parm_g.Pn);
133692 +
133693 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133694 + ccgr_query.cm_query.wr_parm_y.MA,
133695 + ccgr_query.cm_query.wr_parm_y.Mn,
133696 + ccgr_query.cm_query.wr_parm_y.SA,
133697 + ccgr_query.cm_query.wr_parm_y.Sn,
133698 + ccgr_query.cm_query.wr_parm_y.Pn);
133699 +
133700 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133701 + ccgr_query.cm_query.wr_parm_r.MA,
133702 + ccgr_query.cm_query.wr_parm_r.Mn,
133703 + ccgr_query.cm_query.wr_parm_r.SA,
133704 + ccgr_query.cm_query.wr_parm_r.Sn,
133705 + ccgr_query.cm_query.wr_parm_r.Pn);
133706 +
133707 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133708 + ccgr_query.cm_query.ctl_wr_en_g,
133709 + ccgr_query.cm_query.ctl_wr_en_y,
133710 + ccgr_query.cm_query.ctl_wr_en_r);
133711 +
133712 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
133713 + seq_puts(file, " cscn_targ_dcp:\n");
133714 + mask = 0x80000000;
133715 + for (i = 0; i < 32; i++) {
133716 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
133717 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
133718 + mask >>= 1;
133719 + }
133720 +
133721 + seq_puts(file, " cscn_targ_swp:\n");
133722 + for (i = 0; i < 4; i++) {
133723 + mask = 0x80000000;
133724 + for (j = 0; j < 32; j++) {
133725 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
133726 + seq_printf(file, " send CSCN to swp"
133727 + "%u\n", (127 - (i * 32) - j));
133728 + mask >>= 1;
133729 + }
133730 + }
133731 +
133732 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
133733 +
133734 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
133735 + ccgr_query.cm_query.cs_thres.TA,
133736 + ccgr_query.cm_query.cs_thres.Tn);
133737 +
133738 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
133739 + ccgr_query.cm_query.cs_thres_x.TA,
133740 + ccgr_query.cm_query.cs_thres_x.Tn);
133741 +
133742 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
133743 + ccgr_query.cm_query.td_thres.TA,
133744 + ccgr_query.cm_query.td_thres.Tn);
133745 +
133746 + seq_printf(file, " mode: %s\n",
133747 + (ccgr_query.cm_query.ctl_mode &
133748 + QMAN_CGR_MODE_FRAME) ?
133749 + "frame count" : "byte count");
133750 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
133751 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
133752 +
133753 + return 0;
133754 +}
133755 +
133756 +static int query_ccgr_open(struct inode *inode, struct file *file)
133757 +{
133758 + return single_open(file, query_ccgr_show, NULL);
133759 +}
133760 +
133761 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
133762 + size_t count, loff_t *off)
133763 +{
133764 + int ret;
133765 + unsigned long val;
133766 +
133767 + ret = user_input_convert(buf, count, &val);
133768 + if (ret)
133769 + return ret;
133770 + query_ccgr_data.ccgid = val;
133771 + return count;
133772 +}
133773 +
133774 +static const struct file_operations query_ccgr_fops = {
133775 + .owner = THIS_MODULE,
133776 + .open = query_ccgr_open,
133777 + .read = seq_read,
133778 + .write = query_ccgr_write,
133779 + .release = single_release,
133780 +};
133781 +/*******************************************************************************
133782 + * QMan register
133783 + ******************************************************************************/
133784 +struct qman_register_s {
133785 + u32 val;
133786 +};
133787 +static struct qman_register_s qman_register_data;
133788 +
133789 +static void init_ccsrmempeek(void)
133790 +{
133791 + struct device_node *dn;
133792 + const u32 *regaddr_p;
133793 +
133794 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
133795 + if (!dn) {
133796 + pr_info("No fsl,qman node\n");
133797 + return;
133798 + }
133799 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
133800 + if (!regaddr_p) {
133801 + of_node_put(dn);
133802 + return;
133803 + }
133804 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
133805 + of_node_put(dn);
133806 +}
133807 +/* This function provides access to QMan ccsr memory map */
133808 +static int qman_ccsrmempeek(u32 *val, u32 offset)
133809 +{
133810 + void __iomem *addr;
133811 + u64 phys_addr;
133812 +
133813 + if (!qman_ccsr_start)
133814 + return -EINVAL;
133815 +
133816 + if (offset > (qman_ccsr_size - sizeof(u32)))
133817 + return -EINVAL;
133818 +
133819 + phys_addr = qman_ccsr_start + offset;
133820 + addr = ioremap(phys_addr, sizeof(u32));
133821 + if (!addr) {
133822 + pr_err("ccsrmempeek, ioremap failed\n");
133823 + return -EINVAL;
133824 + }
133825 + *val = in_be32(addr);
133826 + iounmap(addr);
133827 + return 0;
133828 +}
133829 +
133830 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
133831 +{
133832 + u32 b;
133833 +
133834 + qman_ccsrmempeek(&b, qman_register_data.val);
133835 + seq_printf(file, "QMan register offset = 0x%x\n",
133836 + qman_register_data.val);
133837 + seq_printf(file, "value = 0x%08x\n", b);
133838 +
133839 + return 0;
133840 +}
133841 +
133842 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
133843 +{
133844 + return single_open(file, qman_ccsrmempeek_show, NULL);
133845 +}
133846 +
133847 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
133848 + size_t count, loff_t *off)
133849 +{
133850 + int ret;
133851 + unsigned long val;
133852 +
133853 + ret = user_input_convert(buf, count, &val);
133854 + if (ret)
133855 + return ret;
133856 + /* multiple of 4 */
133857 + if (val > (qman_ccsr_size - sizeof(u32))) {
133858 + pr_info("Input 0x%lx > 0x%llx\n",
133859 + val, (qman_ccsr_size - sizeof(u32)));
133860 + return -EINVAL;
133861 + }
133862 + if (val & 0x3) {
133863 + pr_info("Input 0x%lx not multiple of 4\n", val);
133864 + return -EINVAL;
133865 + }
133866 + qman_register_data.val = val;
133867 + return count;
133868 +}
133869 +
133870 +static const struct file_operations qman_ccsrmempeek_fops = {
133871 + .owner = THIS_MODULE,
133872 + .open = qman_ccsrmempeek_open,
133873 + .read = seq_read,
133874 + .write = qman_ccsrmempeek_write,
133875 +};
133876 +
133877 +/*******************************************************************************
133878 + * QMan state
133879 + ******************************************************************************/
133880 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
133881 +{
133882 + struct qm_mcr_queryfq_np np;
133883 + struct qman_fq fq;
133884 + struct line_buffer_fq line_buf;
133885 + int ret, i;
133886 + u8 *state = file->private;
133887 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
133888 +
133889 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
133890 + memset(&line_buf, 0, sizeof(line_buf));
133891 +
133892 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
133893 +
133894 + for (i = 1; i < fqid_max; i++) {
133895 + fq.fqid = i;
133896 + ret = qman_query_fq_np(&fq, &np);
133897 + if (ret)
133898 + return ret;
133899 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
133900 + add_to_line_buffer(&line_buf, fq.fqid, file);
133901 + /* Keep a summary count of all states */
133902 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
133903 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
133904 + }
133905 + flush_line_buffer(&line_buf, file);
133906 +
133907 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
133908 + seq_printf(file, "%s count = %u\n", state_txt[i],
133909 + qm_fq_state_cnt[i]);
133910 + }
133911 + return 0;
133912 +}
133913 +
133914 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
133915 +{
133916 + return single_open(file, qman_fqd_state_show, inode->i_private);
133917 +}
133918 +
133919 +static const struct file_operations qman_fqd_state_fops = {
133920 + .owner = THIS_MODULE,
133921 + .open = qman_fqd_state_open,
133922 + .read = seq_read,
133923 +};
133924 +
133925 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
133926 +{
133927 + struct qm_fqd fqd;
133928 + struct qman_fq fq;
133929 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
133930 + int ret, i;
133931 + struct mask_filter_s *data = file->private;
133932 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
133933 + struct line_buffer_fq line_buf;
133934 +
133935 + memset(&line_buf, 0, sizeof(line_buf));
133936 + seq_printf(file, "List of fq ids with: %s :%s\n",
133937 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
133938 + for (i = 1; i < fqid_max; i++) {
133939 + fq.fqid = i;
133940 + memset(&fqd, 0, sizeof(struct qm_fqd));
133941 + ret = qman_query_fq(&fq, &fqd);
133942 + if (ret)
133943 + return ret;
133944 + if (data->filter) {
133945 + if (fqd.fq_ctrl & data->mask)
133946 + add_to_line_buffer(&line_buf, fq.fqid, file);
133947 + } else {
133948 + if (!(fqd.fq_ctrl & data->mask))
133949 + add_to_line_buffer(&line_buf, fq.fqid, file);
133950 + }
133951 + if (fqd.fq_ctrl & data->mask)
133952 + fq_en_cnt++;
133953 + else
133954 + fq_di_cnt++;
133955 + }
133956 + flush_line_buffer(&line_buf, file);
133957 +
133958 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
133959 + ctrl_txt, fq_en_cnt);
133960 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
133961 + ctrl_txt, fq_di_cnt);
133962 + return 0;
133963 +}
133964 +
133965 +/*******************************************************************************
133966 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
133967 + ******************************************************************************/
133968 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
133969 +{
133970 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
133971 +}
133972 +
133973 +static const struct file_operations qman_fqd_ctrl_fops = {
133974 + .owner = THIS_MODULE,
133975 + .open = qman_fqd_ctrl_open,
133976 + .read = seq_read,
133977 +};
133978 +
133979 +/*******************************************************************************
133980 + * QMan ctrl summary
133981 + ******************************************************************************/
133982 +/*******************************************************************************
133983 + * QMan summary state
133984 + ******************************************************************************/
133985 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
133986 +{
133987 + struct qm_mcr_queryfq_np np;
133988 + struct qman_fq fq;
133989 + int ret, i;
133990 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
133991 +
133992 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
133993 +
133994 + for (i = 1; i < fqid_max; i++) {
133995 + fq.fqid = i;
133996 + ret = qman_query_fq_np(&fq, &np);
133997 + if (ret)
133998 + return ret;
133999 + /* Keep a summary count of all states */
134000 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134001 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134002 + }
134003 +
134004 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134005 + seq_printf(file, "%s count = %u\n", state_txt[i],
134006 + qm_fq_state_cnt[i]);
134007 + }
134008 + return 0;
134009 +}
134010 +
134011 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
134012 +{
134013 + struct qm_fqd fqd;
134014 + struct qman_fq fq;
134015 + int ret, i , j;
134016 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
134017 +
134018 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
134019 +
134020 + for (i = 1; i < fqid_max; i++) {
134021 + memset(&fqd, 0, sizeof(struct qm_fqd));
134022 + fq.fqid = i;
134023 + ret = qman_query_fq(&fq, &fqd);
134024 + if (ret)
134025 + return ret;
134026 + /* Keep a summary count of all states */
134027 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
134028 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134029 + mask_filter[j].mask)
134030 + qm_prog_cnt[j/2]++;
134031 + }
134032 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
134033 + seq_printf(file, "%s count = %u\n",
134034 + get_fqd_ctrl_text(mask_filter[i*2].mask),
134035 + qm_prog_cnt[i]);
134036 + }
134037 + return 0;
134038 +}
134039 +
134040 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
134041 +{
134042 + int ret;
134043 +
134044 + /* Display summary of non programmable fields */
134045 + ret = qman_fqd_non_prog_summary_show(file, offset);
134046 + if (ret)
134047 + return ret;
134048 + seq_puts(file, "-----------------------------------------\n");
134049 + /* Display programmable fields */
134050 + ret = qman_fqd_prog_summary_show(file, offset);
134051 + if (ret)
134052 + return ret;
134053 + return 0;
134054 +}
134055 +
134056 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
134057 +{
134058 + return single_open(file, qman_fqd_summary_show, NULL);
134059 +}
134060 +
134061 +static const struct file_operations qman_fqd_summary_fops = {
134062 + .owner = THIS_MODULE,
134063 + .open = qman_fqd_summary_open,
134064 + .read = seq_read,
134065 +};
134066 +
134067 +/*******************************************************************************
134068 + * QMan destination work queue
134069 + ******************************************************************************/
134070 +struct qman_dest_wq_s {
134071 + u16 wq_id;
134072 +};
134073 +static struct qman_dest_wq_s qman_dest_wq_data = {
134074 + .wq_id = 0,
134075 +};
134076 +
134077 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
134078 +{
134079 + struct qm_fqd fqd;
134080 + struct qman_fq fq;
134081 + int ret, i;
134082 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
134083 + struct line_buffer_fq line_buf;
134084 +
134085 + memset(&line_buf, 0, sizeof(line_buf));
134086 + /* use vmalloc : need to allocate large memory region and don't
134087 + * require the memory to be physically contiguous. */
134088 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
134089 + if (!wq)
134090 + return -ENOMEM;
134091 +
134092 + seq_printf(file, "List of fq ids with destination work queue id"
134093 + " = 0x%x\n", wq_id);
134094 +
134095 + for (i = 1; i < fqid_max; i++) {
134096 + fq.fqid = i;
134097 + memset(&fqd, 0, sizeof(struct qm_fqd));
134098 + ret = qman_query_fq(&fq, &fqd);
134099 + if (ret) {
134100 + vfree(wq);
134101 + return ret;
134102 + }
134103 + if (wq_id == fqd.dest_wq)
134104 + add_to_line_buffer(&line_buf, fq.fqid, file);
134105 + wq[fqd.dest_wq]++;
134106 + }
134107 + flush_line_buffer(&line_buf, file);
134108 +
134109 + seq_puts(file, "Summary of all FQD destination work queue values\n");
134110 + for (i = 0; i < 0xFFFF; i++) {
134111 + if (wq[i])
134112 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
134113 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
134114 + }
134115 + vfree(wq);
134116 + return 0;
134117 +}
134118 +
134119 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
134120 + size_t count, loff_t *off)
134121 +{
134122 + int ret;
134123 + unsigned long val;
134124 +
134125 + ret = user_input_convert(buf, count, &val);
134126 + if (ret)
134127 + return ret;
134128 + if (val > 0xFFFF)
134129 + return -EINVAL;
134130 + qman_dest_wq_data.wq_id = val;
134131 + return count;
134132 +}
134133 +
134134 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
134135 +{
134136 + return single_open(file, qman_fqd_dest_wq_show, NULL);
134137 +}
134138 +
134139 +static const struct file_operations qman_fqd_dest_wq_fops = {
134140 + .owner = THIS_MODULE,
134141 + .open = qman_fqd_dest_wq_open,
134142 + .read = seq_read,
134143 + .write = qman_fqd_dest_wq_write,
134144 +};
134145 +
134146 +/*******************************************************************************
134147 + * QMan Intra-Class Scheduling Credit
134148 + ******************************************************************************/
134149 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
134150 +{
134151 + struct qm_fqd fqd;
134152 + struct qman_fq fq;
134153 + int ret, i;
134154 + u32 fq_cnt = 0;
134155 + struct line_buffer_fq line_buf;
134156 +
134157 + memset(&line_buf, 0, sizeof(line_buf));
134158 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
134159 + "\n");
134160 +
134161 + for (i = 1; i < fqid_max; i++) {
134162 + fq.fqid = i;
134163 + memset(&fqd, 0, sizeof(struct qm_fqd));
134164 + ret = qman_query_fq(&fq, &fqd);
134165 + if (ret)
134166 + return ret;
134167 + if (fqd.ics_cred > 0) {
134168 + add_to_line_buffer(&line_buf, fq.fqid, file);
134169 + fq_cnt++;
134170 + }
134171 + }
134172 + flush_line_buffer(&line_buf, file);
134173 +
134174 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
134175 + return 0;
134176 +}
134177 +
134178 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
134179 +{
134180 + return single_open(file, qman_fqd_cred_show, NULL);
134181 +}
134182 +
134183 +static const struct file_operations qman_fqd_cred_fops = {
134184 + .owner = THIS_MODULE,
134185 + .open = qman_fqd_cred_open,
134186 + .read = seq_read,
134187 +};
134188 +
134189 +/*******************************************************************************
134190 + * Class Queue Fields
134191 + ******************************************************************************/
134192 +struct query_cq_fields_data_s {
134193 + u32 cqid;
134194 +};
134195 +
134196 +static struct query_cq_fields_data_s query_cq_fields_data = {
134197 + .cqid = 1,
134198 +};
134199 +
134200 +static int query_cq_fields_show(struct seq_file *file, void *offset)
134201 +{
134202 + int ret;
134203 + struct qm_mcr_ceetm_cq_query query_result;
134204 + unsigned int cqid;
134205 + unsigned int portal;
134206 +
134207 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134208 + return -EINVAL;
134209 +
134210 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
134211 + portal = query_cq_fields_data.cqid >> 24;
134212 + if (portal > qm_dc_portal_fman1)
134213 + return -EINVAL;
134214 +
134215 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
134216 + if (ret)
134217 + return ret;
134218 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
134219 + cqid, portal);
134220 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
134221 + seq_printf(file, " state: %u\n", query_result.state);
134222 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
134223 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
134224 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
134225 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
134226 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
134227 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
134228 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
134229 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
134230 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
134231 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
134232 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
134233 +
134234 + return 0;
134235 +}
134236 +
134237 +static int query_cq_fields_open(struct inode *inode,
134238 + struct file *file)
134239 +{
134240 + return single_open(file, query_cq_fields_show, NULL);
134241 +}
134242 +
134243 +static ssize_t query_cq_fields_write(struct file *f,
134244 + const char __user *buf, size_t count, loff_t *off)
134245 +{
134246 + int ret;
134247 + unsigned long val;
134248 +
134249 + ret = user_input_convert(buf, count, &val);
134250 + if (ret)
134251 + return ret;
134252 + query_cq_fields_data.cqid = (u32)val;
134253 + return count;
134254 +}
134255 +
134256 +static const struct file_operations query_cq_fields_fops = {
134257 + .owner = THIS_MODULE,
134258 + .open = query_cq_fields_open,
134259 + .read = seq_read,
134260 + .write = query_cq_fields_write,
134261 + .release = single_release,
134262 +};
134263 +
134264 +/*******************************************************************************
134265 + * READ CEETM_XSFDR_IN_USE
134266 + ******************************************************************************/
134267 +struct query_ceetm_xsfdr_data_s {
134268 + enum qm_dc_portal dcp_portal;
134269 +};
134270 +
134271 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
134272 +
134273 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
134274 +{
134275 + int ret;
134276 + unsigned int xsfdr_in_use;
134277 + enum qm_dc_portal portal;
134278 +
134279 +
134280 + if (qman_ip_rev < QMAN_REV31)
134281 + return -EINVAL;
134282 +
134283 + portal = query_ceetm_xsfdr_data.dcp_portal;
134284 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
134285 + if (ret) {
134286 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
134287 + portal);
134288 + return ret;
134289 + }
134290 +
134291 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
134292 + (xsfdr_in_use & 0x1FFF));
134293 + return 0;
134294 +}
134295 +
134296 +static int query_ceetm_xsfdr_open(struct inode *inode,
134297 + struct file *file)
134298 +{
134299 + return single_open(file, query_ceetm_xsfdr_show, NULL);
134300 +}
134301 +
134302 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
134303 + const char __user *buf, size_t count, loff_t *off)
134304 +{
134305 + int ret;
134306 + unsigned long val;
134307 +
134308 + ret = user_input_convert(buf, count, &val);
134309 + if (ret)
134310 + return ret;
134311 + if (val > qm_dc_portal_fman1)
134312 + return -EINVAL;
134313 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
134314 + return count;
134315 +}
134316 +
134317 +static const struct file_operations query_ceetm_xsfdr_fops = {
134318 + .owner = THIS_MODULE,
134319 + .open = query_ceetm_xsfdr_open,
134320 + .read = seq_read,
134321 + .write = query_ceetm_xsfdr_write,
134322 + .release = single_release,
134323 +};
134324 +
134325 +/* helper macros used in qman_debugfs_module_init */
134326 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
134327 + do { \
134328 + d = debugfs_create_file(name, \
134329 + mode, parent, \
134330 + data, \
134331 + fops); \
134332 + if (d == NULL) { \
134333 + ret = -ENOMEM; \
134334 + goto _return; \
134335 + } \
134336 + } while (0)
134337 +
134338 +/* dfs_root as parent */
134339 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
134340 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
134341 +
134342 +/* fqd_root as parent */
134343 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
134344 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
134345 +
134346 +/* fqd state */
134347 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
134348 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
134349 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
134350 +
134351 +static int __init qman_debugfs_module_init(void)
134352 +{
134353 + int ret = 0;
134354 + struct dentry *d, *fqd_root;
134355 + u32 reg;
134356 +
134357 + fqid_max = 0;
134358 + init_ccsrmempeek();
134359 + if (qman_ccsr_start) {
134360 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
134361 + /* extract the size of the FQD window */
134362 + reg = reg & 0x3f;
134363 + /* calculate valid frame queue descriptor range */
134364 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
134365 + }
134366 + }
134367 + dfs_root = debugfs_create_dir("qman", NULL);
134368 + fqd_root = debugfs_create_dir("fqd", dfs_root);
134369 + if (dfs_root == NULL || fqd_root == NULL) {
134370 + ret = -ENOMEM;
134371 + pr_err("Cannot create qman/fqd debugfs dir\n");
134372 + goto _return;
134373 + }
134374 + if (fqid_max) {
134375 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
134376 + NULL, &qman_ccsrmempeek_fops);
134377 + }
134378 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
134379 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
134380 +
134381 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
134382 + &query_fq_fields_data, &query_fq_fields_fops);
134383 +
134384 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
134385 + &query_wq_lengths_data, &query_wq_lengths_fops);
134386 +
134387 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
134388 + &query_cgr_data, &query_cgr_fops);
134389 +
134390 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
134391 + NULL, &query_congestion_fops);
134392 +
134393 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
134394 + NULL, &testwrite_cgr_fops);
134395 +
134396 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
134397 + NULL, &teswrite_cgr_cgrid_fops);
134398 +
134399 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
134400 + NULL, &teswrite_cgr_ibcnt_fops);
134401 +
134402 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
134403 + &query_ccgr_data, &query_ccgr_fops);
134404 + /* Create files with fqd_root as parent */
134405 +
134406 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
134407 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
134408 +
134409 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
134410 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
134411 + &qman_fqd_state_fops);
134412 +
134413 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
134414 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
134415 + &qman_fqd_state_fops);
134416 +
134417 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
134418 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
134419 + &qman_fqd_state_fops);
134420 +
134421 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
134422 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
134423 + &qman_fqd_state_fops);
134424 +
134425 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
134426 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
134427 + &qman_fqd_state_fops);
134428 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
134429 + &query_cq_fields_data, &query_cq_fields_fops);
134430 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
134431 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
134432 +
134433 +
134434 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
134435 +
134436 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
134437 +
134438 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
134439 +
134440 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
134441 +
134442 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
134443 +
134444 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
134445 +
134446 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
134447 +
134448 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
134449 +
134450 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
134451 +
134452 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
134453 +
134454 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
134455 +
134456 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
134457 +
134458 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
134459 +
134460 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
134461 +
134462 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
134463 +
134464 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
134465 +
134466 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
134467 +
134468 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
134469 +
134470 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
134471 + NULL, &qman_fqd_summary_fops);
134472 +
134473 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
134474 + NULL, &qman_fqd_dest_wq_fops);
134475 +
134476 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
134477 + NULL, &qman_fqd_cred_fops);
134478 +
134479 + return 0;
134480 +
134481 +_return:
134482 + debugfs_remove_recursive(dfs_root);
134483 + return ret;
134484 +}
134485 +
134486 +static void __exit qman_debugfs_module_exit(void)
134487 +{
134488 + debugfs_remove_recursive(dfs_root);
134489 +}
134490 +
134491 +module_init(qman_debugfs_module_init);
134492 +module_exit(qman_debugfs_module_exit);
134493 +MODULE_LICENSE("Dual BSD/GPL");
134494 --- /dev/null
134495 +++ b/drivers/staging/fsl_qbman/qman_driver.c
134496 @@ -0,0 +1,977 @@
134497 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
134498 + *
134499 + * Redistribution and use in source and binary forms, with or without
134500 + * modification, are permitted provided that the following conditions are met:
134501 + * * Redistributions of source code must retain the above copyright
134502 + * notice, this list of conditions and the following disclaimer.
134503 + * * Redistributions in binary form must reproduce the above copyright
134504 + * notice, this list of conditions and the following disclaimer in the
134505 + * documentation and/or other materials provided with the distribution.
134506 + * * Neither the name of Freescale Semiconductor nor the
134507 + * names of its contributors may be used to endorse or promote products
134508 + * derived from this software without specific prior written permission.
134509 + *
134510 + *
134511 + * ALTERNATIVELY, this software may be distributed under the terms of the
134512 + * GNU General Public License ("GPL") as published by the Free Software
134513 + * Foundation, either version 2 of that License or (at your option) any
134514 + * later version.
134515 + *
134516 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
134517 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
134518 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
134519 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
134520 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
134521 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
134522 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
134523 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
134524 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
134525 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
134526 + */
134527 +
134528 +#include "qman_private.h"
134529 +
134530 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
134531 +#ifdef CONFIG_HOTPLUG_CPU
134532 +#include <linux/cpu.h>
134533 +#endif
134534 +
134535 +/* Global variable containing revision id (even on non-control plane systems
134536 + * where CCSR isn't available) */
134537 +u16 qman_ip_rev;
134538 +EXPORT_SYMBOL(qman_ip_rev);
134539 +u8 qman_ip_cfg;
134540 +EXPORT_SYMBOL(qman_ip_cfg);
134541 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
134542 +EXPORT_SYMBOL(qm_channel_pool1);
134543 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
134544 +EXPORT_SYMBOL(qm_channel_caam);
134545 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
134546 +EXPORT_SYMBOL(qm_channel_pme);
134547 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
134548 +EXPORT_SYMBOL(qm_channel_dce);
134549 +u16 qman_portal_max;
134550 +EXPORT_SYMBOL(qman_portal_max);
134551 +
134552 +u32 qman_clk;
134553 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
134554 +/* the qman ceetm instances on the given SoC */
134555 +u8 num_ceetms;
134556 +
134557 +/* For these variables, and the portal-initialisation logic, the
134558 + * comments in bman_driver.c apply here so won't be repeated. */
134559 +static struct qman_portal *shared_portals[NR_CPUS];
134560 +static int num_shared_portals;
134561 +static int shared_portals_idx;
134562 +static LIST_HEAD(unused_pcfgs);
134563 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
134564 +
134565 +/* A SDQCR mask comprising all the available/visible pool channels */
134566 +static u32 pools_sdqcr;
134567 +
134568 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
134569 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
134570 +#define STR_FQID_RANGE "fsl,fqid-range"
134571 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
134572 +#define STR_CGRID_RANGE "fsl,cgrid-range"
134573 +
134574 +/* A "fsl,fqid-range" node; release the given range to the allocator */
134575 +static __init int fsl_fqid_range_init(struct device_node *node)
134576 +{
134577 + int ret;
134578 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
134579 + if (!range) {
134580 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
134581 + return -EINVAL;
134582 + }
134583 + if (ret != 8) {
134584 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
134585 + return -EINVAL;
134586 + }
134587 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134588 + pr_info("Qman: FQID allocator includes range %d:%d\n",
134589 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134590 + return 0;
134591 +}
134592 +
134593 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
134594 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
134595 +{
134596 + int ret;
134597 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
134598 + if (!chanid) {
134599 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
134600 + return -EINVAL;
134601 + }
134602 + if (ret != 8) {
134603 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
134604 + return -EINVAL;
134605 + }
134606 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
134607 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
134608 + return 0;
134609 +}
134610 +
134611 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
134612 +static __init int fsl_pool_channel_range_init(struct device_node *node)
134613 +{
134614 + int ret;
134615 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
134616 + if (!chanid) {
134617 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
134618 + return -EINVAL;
134619 + }
134620 + if (ret != 8) {
134621 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
134622 + return -EINVAL;
134623 + }
134624 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
134625 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
134626 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
134627 + return 0;
134628 +}
134629 +
134630 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
134631 +static __init int fsl_cgrid_range_init(struct device_node *node)
134632 +{
134633 + struct qman_cgr cgr;
134634 + int ret, errors = 0;
134635 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
134636 + if (!range) {
134637 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
134638 + return -EINVAL;
134639 + }
134640 + if (ret != 8) {
134641 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
134642 + return -EINVAL;
134643 + }
134644 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134645 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
134646 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134647 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
134648 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
134649 + if (ret)
134650 + errors++;
134651 + }
134652 + if (errors)
134653 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
134654 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
134655 + return 0;
134656 +}
134657 +
134658 +static __init int fsl_ceetm_init(struct device_node *node)
134659 +{
134660 + enum qm_dc_portal dcp_portal;
134661 + struct qm_ceetm_sp *sp;
134662 + struct qm_ceetm_lni *lni;
134663 + int ret, i;
134664 + const u32 *range;
134665 +
134666 + /* Find LFQID range */
134667 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
134668 + if (!range) {
134669 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
134670 + node->full_name);
134671 + return -EINVAL;
134672 + }
134673 + if (ret != 8) {
134674 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
134675 + " %s\n", node->full_name);
134676 + return -EINVAL;
134677 + }
134678 +
134679 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
134680 + if (dcp_portal > qm_dc_portal_fman1) {
134681 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
134682 + return -EINVAL;
134683 + }
134684 +
134685 + if (dcp_portal == qm_dc_portal_fman0)
134686 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134687 + if (dcp_portal == qm_dc_portal_fman1)
134688 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134689 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
134690 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134691 +
134692 + qman_ceetms[dcp_portal].idx = dcp_portal;
134693 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
134694 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
134695 +
134696 + /* Find Sub-portal range */
134697 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
134698 + if (!range) {
134699 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
134700 + return -EINVAL;
134701 + }
134702 + if (ret != 8) {
134703 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
134704 + node->full_name);
134705 + return -EINVAL;
134706 + }
134707 +
134708 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
134709 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
134710 + if (!sp) {
134711 + pr_err("Can't alloc memory for sub-portal %d\n",
134712 + range[0] + i);
134713 + return -ENOMEM;
134714 + }
134715 + sp->idx = be32_to_cpu(range[0]) + i;
134716 + sp->dcp_idx = dcp_portal;
134717 + sp->is_claimed = 0;
134718 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
134719 + sp++;
134720 + }
134721 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
134722 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
134723 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
134724 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
134725 +
134726 + /* Find LNI range */
134727 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
134728 + if (!range) {
134729 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
134730 + return -EINVAL;
134731 + }
134732 + if (ret != 8) {
134733 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
134734 + node->full_name);
134735 + return -EINVAL;
134736 + }
134737 +
134738 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
134739 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
134740 + if (!lni) {
134741 + pr_err("Can't alloc memory for LNI %d\n",
134742 + range[0] + i);
134743 + return -ENOMEM;
134744 + }
134745 + lni->idx = be32_to_cpu(range[0]) + i;
134746 + lni->dcp_idx = dcp_portal;
134747 + lni->is_claimed = 0;
134748 + INIT_LIST_HEAD(&lni->channels);
134749 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
134750 + lni++;
134751 + }
134752 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
134753 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
134754 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
134755 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
134756 +
134757 + /* Find CEETM channel range */
134758 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
134759 + if (!range) {
134760 + pr_err("No fsl,ceetm-channel-range in node %s\n",
134761 + node->full_name);
134762 + return -EINVAL;
134763 + }
134764 + if (ret != 8) {
134765 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
134766 + "%s\n", node->full_name);
134767 + return -EINVAL;
134768 + }
134769 +
134770 + if (dcp_portal == qm_dc_portal_fman0)
134771 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134772 + if (dcp_portal == qm_dc_portal_fman1)
134773 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134774 + pr_debug("Qman: The channel allocator of CEETM %d includes"
134775 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
134776 +
134777 + /* Set CEETM PRES register */
134778 + ret = qman_ceetm_set_prescaler(dcp_portal);
134779 + if (ret)
134780 + return ret;
134781 + return 0;
134782 +}
134783 +
134784 +static void qman_get_ip_revision(struct device_node *dn)
134785 +{
134786 + u16 ip_rev = 0;
134787 + u8 ip_cfg = QMAN_REV_CFG_0;
134788 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
134789 + if (!of_device_is_available(dn))
134790 + continue;
134791 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
134792 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
134793 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
134794 + BUG_ON(1);
134795 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
134796 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
134797 + ip_rev = QMAN_REV11;
134798 + qman_portal_max = 10;
134799 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
134800 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
134801 + ip_rev = QMAN_REV12;
134802 + qman_portal_max = 10;
134803 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
134804 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
134805 + ip_rev = QMAN_REV20;
134806 + qman_portal_max = 3;
134807 + } else if (of_device_is_compatible(dn,
134808 + "fsl,qman-portal-3.0.0")) {
134809 + ip_rev = QMAN_REV30;
134810 + qman_portal_max = 50;
134811 + } else if (of_device_is_compatible(dn,
134812 + "fsl,qman-portal-3.0.1")) {
134813 + ip_rev = QMAN_REV30;
134814 + qman_portal_max = 25;
134815 + ip_cfg = QMAN_REV_CFG_1;
134816 + } else if (of_device_is_compatible(dn,
134817 + "fsl,qman-portal-3.1.0")) {
134818 + ip_rev = QMAN_REV31;
134819 + qman_portal_max = 50;
134820 + } else if (of_device_is_compatible(dn,
134821 + "fsl,qman-portal-3.1.1")) {
134822 + ip_rev = QMAN_REV31;
134823 + qman_portal_max = 25;
134824 + ip_cfg = QMAN_REV_CFG_1;
134825 + } else if (of_device_is_compatible(dn,
134826 + "fsl,qman-portal-3.1.2")) {
134827 + ip_rev = QMAN_REV31;
134828 + qman_portal_max = 18;
134829 + ip_cfg = QMAN_REV_CFG_2;
134830 + } else if (of_device_is_compatible(dn,
134831 + "fsl,qman-portal-3.1.3")) {
134832 + ip_rev = QMAN_REV31;
134833 + qman_portal_max = 10;
134834 + ip_cfg = QMAN_REV_CFG_3;
134835 + } else if (of_device_is_compatible(dn,
134836 + "fsl,qman-portal-3.2.0")) {
134837 + ip_rev = QMAN_REV32;
134838 + qman_portal_max = 10;
134839 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
134840 + } else if (of_device_is_compatible(dn,
134841 + "fsl,qman-portal-3.2.1")) {
134842 + ip_rev = QMAN_REV32;
134843 + qman_portal_max = 10;
134844 + ip_cfg = QMAN_REV_CFG_3;
134845 + } else {
134846 + pr_warn("unknown QMan version in portal node,"
134847 + "default to rev1.1\n");
134848 + ip_rev = QMAN_REV11;
134849 + qman_portal_max = 10;
134850 + }
134851 +
134852 + if (!qman_ip_rev) {
134853 + if (ip_rev) {
134854 + qman_ip_rev = ip_rev;
134855 + qman_ip_cfg = ip_cfg;
134856 + } else {
134857 + pr_warn("unknown Qman version,"
134858 + " default to rev1.1\n");
134859 + qman_ip_rev = QMAN_REV11;
134860 + qman_ip_cfg = QMAN_REV_CFG_0;
134861 + }
134862 + } else if (ip_rev && (qman_ip_rev != ip_rev))
134863 + pr_warn("Revision=0x%04x, but portal '%s' has"
134864 + " 0x%04x\n",
134865 + qman_ip_rev, dn->full_name, ip_rev);
134866 + if (qman_ip_rev == ip_rev)
134867 + break;
134868 + }
134869 +}
134870 +
134871 +/* Parse a portal node, perform generic mapping duties and return the config. It
134872 + * is not known at this stage for what purpose (or even if) the portal will be
134873 + * used. */
134874 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
134875 +{
134876 + struct qm_portal_config *pcfg;
134877 + const u32 *index_p;
134878 + u32 index, channel;
134879 + int irq, ret;
134880 + resource_size_t len;
134881 +
134882 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
134883 + if (!pcfg) {
134884 + pr_err("can't allocate portal config");
134885 + return NULL;
134886 + }
134887 +
134888 + /*
134889 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
134890 + * 'struct device' in order to get the PAMU stashing setup and the QMan
134891 + * portal [driver] won't function at all without ring stashing
134892 + *
134893 + * Making the QMan portal driver nice and proper is part of the
134894 + * upstreaming effort
134895 + */
134896 + pcfg->dev.bus = &platform_bus_type;
134897 + pcfg->dev.of_node = node;
134898 +#ifdef CONFIG_FSL_PAMU
134899 + pcfg->dev.archdata.iommu_domain = NULL;
134900 +#endif
134901 +
134902 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
134903 + &pcfg->addr_phys[DPA_PORTAL_CE]);
134904 + if (ret) {
134905 + pr_err("Can't get %s property '%s'\n", node->full_name,
134906 + "reg::CE");
134907 + goto err;
134908 + }
134909 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
134910 + &pcfg->addr_phys[DPA_PORTAL_CI]);
134911 + if (ret) {
134912 + pr_err("Can't get %s property '%s'\n", node->full_name,
134913 + "reg::CI");
134914 + goto err;
134915 + }
134916 + index_p = of_get_property(node, "cell-index", &ret);
134917 + if (!index_p || (ret != 4)) {
134918 + pr_err("Can't get %s property '%s'\n", node->full_name,
134919 + "cell-index");
134920 + goto err;
134921 + }
134922 + index = be32_to_cpu(*index_p);
134923 + if (index >= qman_portal_max) {
134924 + pr_err("QMan portal index %d is beyond max (%d)\n",
134925 + index, qman_portal_max);
134926 + goto err;
134927 + }
134928 +
134929 + channel = index + QM_CHANNEL_SWPORTAL0;
134930 + pcfg->public_cfg.channel = channel;
134931 + pcfg->public_cfg.cpu = -1;
134932 + irq = irq_of_parse_and_map(node, 0);
134933 + if (irq == 0) {
134934 + pr_err("Can't get %s property '%s'\n", node->full_name,
134935 + "interrupts");
134936 + goto err;
134937 + }
134938 + pcfg->public_cfg.irq = irq;
134939 + pcfg->public_cfg.index = index;
134940 +#ifdef CONFIG_FSL_QMAN_CONFIG
134941 + /* We need the same LIODN offset for all portals */
134942 + qman_liodn_fixup(pcfg->public_cfg.channel);
134943 +#endif
134944 +
134945 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
134946 + if (len != (unsigned long)len)
134947 + goto err;
134948 +
134949 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
134950 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
134951 + pcfg->addr_phys[DPA_PORTAL_CE].start,
134952 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
134953 +
134954 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
134955 + pcfg->addr_phys[DPA_PORTAL_CI].start,
134956 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
134957 +#else
134958 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
134959 + pcfg->addr_phys[DPA_PORTAL_CE].start,
134960 + (unsigned long)len,
134961 + 0);
134962 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
134963 + pcfg->addr_phys[DPA_PORTAL_CI].start,
134964 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
134965 + _PAGE_GUARDED | _PAGE_NO_CACHE);
134966 +#endif
134967 + return pcfg;
134968 +err:
134969 + kfree(pcfg);
134970 + return NULL;
134971 +}
134972 +
134973 +static struct qm_portal_config *get_pcfg(struct list_head *list)
134974 +{
134975 + struct qm_portal_config *pcfg;
134976 + if (list_empty(list))
134977 + return NULL;
134978 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
134979 + list_del(&pcfg->list);
134980 + return pcfg;
134981 +}
134982 +
134983 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
134984 +{
134985 + struct qm_portal_config *pcfg;
134986 + if (list_empty(list))
134987 + return NULL;
134988 + list_for_each_entry(pcfg, list, list) {
134989 + if (pcfg->public_cfg.index == idx) {
134990 + list_del(&pcfg->list);
134991 + return pcfg;
134992 + }
134993 + }
134994 + return NULL;
134995 +}
134996 +
134997 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
134998 +{
134999 +#ifdef CONFIG_FSL_PAMU
135000 + int ret;
135001 + int window_count = 1;
135002 + struct iommu_domain_geometry geom_attr;
135003 + struct pamu_stash_attribute stash_attr;
135004 +
135005 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
135006 + if (!pcfg->iommu_domain) {
135007 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
135008 + __func__);
135009 + goto _no_iommu;
135010 + }
135011 + geom_attr.aperture_start = 0;
135012 + geom_attr.aperture_end =
135013 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
135014 + geom_attr.force_aperture = true;
135015 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
135016 + &geom_attr);
135017 + if (ret < 0) {
135018 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135019 + __func__, ret);
135020 + goto _iommu_domain_free;
135021 + }
135022 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
135023 + &window_count);
135024 + if (ret < 0) {
135025 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135026 + __func__, ret);
135027 + goto _iommu_domain_free;
135028 + }
135029 + stash_attr.cpu = cpu;
135030 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135031 + /* set stash information for the window */
135032 + stash_attr.window = 0;
135033 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135034 + DOMAIN_ATTR_FSL_PAMU_STASH,
135035 + &stash_attr);
135036 + if (ret < 0) {
135037 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135038 + __func__, ret);
135039 + goto _iommu_domain_free;
135040 + }
135041 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
135042 + IOMMU_READ | IOMMU_WRITE);
135043 + if (ret < 0) {
135044 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
135045 + __func__, ret);
135046 + goto _iommu_domain_free;
135047 + }
135048 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
135049 + if (ret < 0) {
135050 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
135051 + __func__, ret);
135052 + goto _iommu_domain_free;
135053 + }
135054 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135055 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
135056 + &window_count);
135057 + if (ret < 0) {
135058 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135059 + __func__, ret);
135060 + goto _iommu_detach_device;
135061 + }
135062 +
135063 +_no_iommu:
135064 +#endif
135065 +#ifdef CONFIG_FSL_QMAN_CONFIG
135066 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135067 +#endif
135068 + pr_warn("Failed to set QMan portal's stash request queue\n");
135069 +
135070 + return;
135071 +
135072 +#ifdef CONFIG_FSL_PAMU
135073 +_iommu_detach_device:
135074 + iommu_detach_device(pcfg->iommu_domain, NULL);
135075 +_iommu_domain_free:
135076 + iommu_domain_free(pcfg->iommu_domain);
135077 +#endif
135078 +}
135079 +
135080 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
135081 +{
135082 + struct qm_portal_config *ret;
135083 + spin_lock(&unused_pcfgs_lock);
135084 + if (idx == QBMAN_ANY_PORTAL_IDX)
135085 + ret = get_pcfg(&unused_pcfgs);
135086 + else
135087 + ret = get_pcfg_idx(&unused_pcfgs, idx);
135088 + spin_unlock(&unused_pcfgs_lock);
135089 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
135090 + * set the portal to use the stashing request queue corresonding to the
135091 + * cpu as well. The user-space driver assumption is that the pthread has
135092 + * to already be affine to one cpu only before opening a portal. If that
135093 + * check is circumvented, the only risk is a performance degradation -
135094 + * stashing will go to whatever cpu they happened to be running on when
135095 + * opening the device file, and if that isn't the cpu they subsequently
135096 + * bind to and do their polling on, tough. */
135097 + if (ret)
135098 + portal_set_cpu(ret, hard_smp_processor_id());
135099 + return ret;
135100 +}
135101 +
135102 +struct qm_portal_config *qm_get_unused_portal(void)
135103 +{
135104 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
135105 +}
135106 +
135107 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
135108 +{
135109 + spin_lock(&unused_pcfgs_lock);
135110 + list_add(&pcfg->list, &unused_pcfgs);
135111 + spin_unlock(&unused_pcfgs_lock);
135112 +}
135113 +
135114 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
135115 +{
135116 + struct qman_portal *p;
135117 +
135118 + pcfg->iommu_domain = NULL;
135119 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
135120 + p = qman_create_affine_portal(pcfg, NULL);
135121 + if (p) {
135122 + u32 irq_sources = 0;
135123 + /* Determine what should be interrupt-vs-poll driven */
135124 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
135125 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
135126 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
135127 +#endif
135128 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
135129 + irq_sources |= QM_PIRQ_DQRI;
135130 +#endif
135131 + qman_p_irqsource_add(p, irq_sources);
135132 + pr_info("Qman portal %sinitialised, cpu %d\n",
135133 + pcfg->public_cfg.is_shared ? "(shared) " : "",
135134 + pcfg->public_cfg.cpu);
135135 + } else
135136 + pr_crit("Qman portal failure on cpu %d\n",
135137 + pcfg->public_cfg.cpu);
135138 + return p;
135139 +}
135140 +
135141 +static void init_slave(int cpu)
135142 +{
135143 + struct qman_portal *p;
135144 + struct cpumask oldmask = current->cpus_allowed;
135145 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
135146 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
135147 + if (!p)
135148 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
135149 + else
135150 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
135151 + set_cpus_allowed_ptr(current, &oldmask);
135152 + if (shared_portals_idx >= num_shared_portals)
135153 + shared_portals_idx = 0;
135154 +}
135155 +
135156 +static struct cpumask want_unshared __initdata;
135157 +static struct cpumask want_shared __initdata;
135158 +
135159 +static int __init parse_qportals(char *str)
135160 +{
135161 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
135162 + "qportals");
135163 +}
135164 +__setup("qportals=", parse_qportals);
135165 +
135166 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
135167 + unsigned int cpu)
135168 +{
135169 +#ifdef CONFIG_FSL_PAMU
135170 + struct pamu_stash_attribute stash_attr;
135171 + int ret;
135172 +
135173 + if (pcfg->iommu_domain) {
135174 + stash_attr.cpu = cpu;
135175 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135176 + /* set stash information for the window */
135177 + stash_attr.window = 0;
135178 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135179 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
135180 + if (ret < 0) {
135181 + pr_err("Failed to update pamu stash setting\n");
135182 + return;
135183 + }
135184 + }
135185 +#endif
135186 +#ifdef CONFIG_FSL_QMAN_CONFIG
135187 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135188 + pr_warn("Failed to update portal's stash request queue\n");
135189 +#endif
135190 +}
135191 +
135192 +static int qman_offline_cpu(unsigned int cpu)
135193 +{
135194 + struct qman_portal *p;
135195 + const struct qm_portal_config *pcfg;
135196 + p = (struct qman_portal *)affine_portals[cpu];
135197 + if (p) {
135198 + pcfg = qman_get_qm_portal_config(p);
135199 + if (pcfg) {
135200 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
135201 + qman_portal_update_sdest(pcfg, 0);
135202 + }
135203 + }
135204 + return 0;
135205 +}
135206 +
135207 +#ifdef CONFIG_HOTPLUG_CPU
135208 +static int qman_online_cpu(unsigned int cpu)
135209 +{
135210 + struct qman_portal *p;
135211 + const struct qm_portal_config *pcfg;
135212 + p = (struct qman_portal *)affine_portals[cpu];
135213 + if (p) {
135214 + pcfg = qman_get_qm_portal_config(p);
135215 + if (pcfg) {
135216 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
135217 + qman_portal_update_sdest(pcfg, cpu);
135218 + }
135219 + }
135220 + return 0;
135221 +}
135222 +
135223 +static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
135224 + unsigned long action, void *hcpu)
135225 +{
135226 + unsigned int cpu = (unsigned long)hcpu;
135227 +
135228 + switch (action) {
135229 + case CPU_ONLINE:
135230 + case CPU_ONLINE_FROZEN:
135231 + qman_online_cpu(cpu);
135232 + break;
135233 + case CPU_DOWN_PREPARE:
135234 + case CPU_DOWN_PREPARE_FROZEN:
135235 + qman_offline_cpu(cpu);
135236 + default:
135237 + break;
135238 + }
135239 + return NOTIFY_OK;
135240 +}
135241 +
135242 +static struct notifier_block qman_hotplug_cpu_notifier = {
135243 + .notifier_call = qman_hotplug_cpu_callback,
135244 +};
135245 +#endif /* CONFIG_HOTPLUG_CPU */
135246 +
135247 +__init int qman_init(void)
135248 +{
135249 + struct cpumask slave_cpus;
135250 + struct cpumask unshared_cpus = *cpu_none_mask;
135251 + struct cpumask shared_cpus = *cpu_none_mask;
135252 + LIST_HEAD(unshared_pcfgs);
135253 + LIST_HEAD(shared_pcfgs);
135254 + struct device_node *dn;
135255 + struct qm_portal_config *pcfg;
135256 + struct qman_portal *p;
135257 + int cpu, ret;
135258 + const u32 *clk;
135259 + struct cpumask offline_cpus;
135260 +
135261 + /* Initialise the Qman (CCSR) device */
135262 + for_each_compatible_node(dn, NULL, "fsl,qman") {
135263 + if (!qman_init_ccsr(dn))
135264 + pr_info("Qman err interrupt handler present\n");
135265 + else
135266 + pr_err("Qman CCSR setup failed\n");
135267 +
135268 + clk = of_get_property(dn, "clock-frequency", NULL);
135269 + if (!clk)
135270 + pr_warn("Can't find Qman clock frequency\n");
135271 + else
135272 + qman_clk = be32_to_cpu(*clk);
135273 + }
135274 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135275 + /* Setup lookup table for FQ demux */
135276 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
135277 + if (ret)
135278 + return ret;
135279 +#endif
135280 +
135281 + /* Get qman ip revision */
135282 + qman_get_ip_revision(dn);
135283 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
135284 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
135285 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
135286 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
135287 + }
135288 +
135289 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
135290 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
135291 +
135292 + /*
135293 + * Parse the ceetm node to get how many ceetm instances are supported
135294 + * on the current silicon. num_ceetms must be confirmed before portals
135295 + * are intiailized.
135296 + */
135297 + num_ceetms = 0;
135298 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
135299 + num_ceetms++;
135300 +
135301 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
135302 + * are initialised.) */
135303 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135304 + ret = fsl_pool_channel_range_sdqcr(dn);
135305 + if (ret)
135306 + return ret;
135307 + }
135308 +
135309 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
135310 + /* Initialise portals. See bman_driver.c for comments */
135311 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135312 + if (!of_device_is_available(dn))
135313 + continue;
135314 + pcfg = parse_pcfg(dn);
135315 + if (pcfg) {
135316 + pcfg->public_cfg.pools = pools_sdqcr;
135317 + list_add_tail(&pcfg->list, &unused_pcfgs);
135318 + }
135319 + }
135320 + for_each_possible_cpu(cpu) {
135321 + if (cpumask_test_cpu(cpu, &want_shared)) {
135322 + pcfg = get_pcfg(&unused_pcfgs);
135323 + if (!pcfg)
135324 + break;
135325 + pcfg->public_cfg.cpu = cpu;
135326 + list_add_tail(&pcfg->list, &shared_pcfgs);
135327 + cpumask_set_cpu(cpu, &shared_cpus);
135328 + }
135329 + if (cpumask_test_cpu(cpu, &want_unshared)) {
135330 + if (cpumask_test_cpu(cpu, &shared_cpus))
135331 + continue;
135332 + pcfg = get_pcfg(&unused_pcfgs);
135333 + if (!pcfg)
135334 + break;
135335 + pcfg->public_cfg.cpu = cpu;
135336 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135337 + cpumask_set_cpu(cpu, &unshared_cpus);
135338 + }
135339 + }
135340 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
135341 + for_each_online_cpu(cpu) {
135342 + pcfg = get_pcfg(&unused_pcfgs);
135343 + if (!pcfg)
135344 + break;
135345 + pcfg->public_cfg.cpu = cpu;
135346 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135347 + cpumask_set_cpu(cpu, &unshared_cpus);
135348 + }
135349 + }
135350 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
135351 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
135352 + if (cpumask_empty(&slave_cpus)) {
135353 + if (!list_empty(&shared_pcfgs)) {
135354 + cpumask_or(&unshared_cpus, &unshared_cpus,
135355 + &shared_cpus);
135356 + cpumask_clear(&shared_cpus);
135357 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
135358 + INIT_LIST_HEAD(&shared_pcfgs);
135359 + }
135360 + } else {
135361 + if (list_empty(&shared_pcfgs)) {
135362 + pcfg = get_pcfg(&unshared_pcfgs);
135363 + if (!pcfg) {
135364 + pr_crit("No QMan portals available!\n");
135365 + return 0;
135366 + }
135367 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
135368 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
135369 + list_add_tail(&pcfg->list, &shared_pcfgs);
135370 + }
135371 + }
135372 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
135373 + pcfg->public_cfg.is_shared = 0;
135374 + p = init_pcfg(pcfg);
135375 + if (!p) {
135376 + pr_crit("Unable to configure portals\n");
135377 + return 0;
135378 + }
135379 + }
135380 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
135381 + pcfg->public_cfg.is_shared = 1;
135382 + p = init_pcfg(pcfg);
135383 + if (p)
135384 + shared_portals[num_shared_portals++] = p;
135385 + }
135386 + if (!cpumask_empty(&slave_cpus))
135387 + for_each_cpu(cpu, &slave_cpus)
135388 + init_slave(cpu);
135389 + pr_info("Qman portals initialised\n");
135390 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
135391 + for_each_cpu(cpu, &offline_cpus)
135392 + qman_offline_cpu(cpu);
135393 +#ifdef CONFIG_HOTPLUG_CPU
135394 + register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
135395 +#endif
135396 + return 0;
135397 +}
135398 +
135399 +__init int qman_resource_init(void)
135400 +{
135401 + struct device_node *dn;
135402 + int ret;
135403 +
135404 + /* Initialise FQID allocation ranges */
135405 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
135406 + ret = fsl_fqid_range_init(dn);
135407 + if (ret)
135408 + return ret;
135409 + }
135410 + /* Initialise CGRID allocation ranges */
135411 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
135412 + ret = fsl_cgrid_range_init(dn);
135413 + if (ret)
135414 + return ret;
135415 + }
135416 + /* Parse pool channels into the allocator. (Must happen after portals
135417 + * are initialised.) */
135418 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135419 + ret = fsl_pool_channel_range_init(dn);
135420 + if (ret)
135421 + return ret;
135422 + }
135423 +
135424 + /* Parse CEETM */
135425 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
135426 + ret = fsl_ceetm_init(dn);
135427 + if (ret)
135428 + return ret;
135429 + }
135430 + return 0;
135431 +}
135432 +
135433 +#ifdef CONFIG_SUSPEND
135434 +void suspend_unused_qportal(void)
135435 +{
135436 + struct qm_portal_config *pcfg;
135437 +
135438 + if (list_empty(&unused_pcfgs))
135439 + return;
135440 +
135441 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135442 +#ifdef CONFIG_PM_DEBUG
135443 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
135444 +#endif
135445 + /* save isdr, disable all via isdr, clear isr */
135446 + pcfg->saved_isdr =
135447 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135448 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135449 + 0xe08);
135450 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135451 + 0xe00);
135452 + }
135453 + return;
135454 +}
135455 +
135456 +void resume_unused_qportal(void)
135457 +{
135458 + struct qm_portal_config *pcfg;
135459 +
135460 + if (list_empty(&unused_pcfgs))
135461 + return;
135462 +
135463 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135464 +#ifdef CONFIG_PM_DEBUG
135465 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
135466 +#endif
135467 + /* restore isdr */
135468 + __raw_writel(pcfg->saved_isdr,
135469 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135470 + }
135471 + return;
135472 +}
135473 +#endif
135474 --- /dev/null
135475 +++ b/drivers/staging/fsl_qbman/qman_high.c
135476 @@ -0,0 +1,5669 @@
135477 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
135478 + *
135479 + * Redistribution and use in source and binary forms, with or without
135480 + * modification, are permitted provided that the following conditions are met:
135481 + * * Redistributions of source code must retain the above copyright
135482 + * notice, this list of conditions and the following disclaimer.
135483 + * * Redistributions in binary form must reproduce the above copyright
135484 + * notice, this list of conditions and the following disclaimer in the
135485 + * documentation and/or other materials provided with the distribution.
135486 + * * Neither the name of Freescale Semiconductor nor the
135487 + * names of its contributors may be used to endorse or promote products
135488 + * derived from this software without specific prior written permission.
135489 + *
135490 + *
135491 + * ALTERNATIVELY, this software may be distributed under the terms of the
135492 + * GNU General Public License ("GPL") as published by the Free Software
135493 + * Foundation, either version 2 of that License or (at your option) any
135494 + * later version.
135495 + *
135496 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135497 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135498 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135499 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135500 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135501 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135502 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135503 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135504 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135505 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135506 + */
135507 +
135508 +#include "qman_low.h"
135509 +
135510 +/* Compilation constants */
135511 +#define DQRR_MAXFILL 15
135512 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
135513 +#define IRQNAME "QMan portal %d"
135514 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
135515 +
135516 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
135517 + * positive, and rounding to the closest value if it's zero. NB, this macro
135518 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
135519 + * that are compatible with this. NB, these arguments should not be expressions
135520 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
135521 + * in "some_value++" as a parameter to the macro! */
135522 +#define ROUNDING(n, d, r) \
135523 + (((r) < 0) ? div64_u64((n), (d)) : \
135524 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
135525 + div64_u64(((n) + ((d) / 2)), (d))))
135526 +
135527 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
135528 + * inter-processor locking only. Note, FQLOCK() is always called either under a
135529 + * local_irq_save() or from interrupt context - hence there's no need for irq
135530 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
135531 + * the "irq en/disable" machinery isn't recursive...). */
135532 +#define FQLOCK(fq) \
135533 + do { \
135534 + struct qman_fq *__fq478 = (fq); \
135535 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
135536 + spin_lock(&__fq478->fqlock); \
135537 + } while (0)
135538 +#define FQUNLOCK(fq) \
135539 + do { \
135540 + struct qman_fq *__fq478 = (fq); \
135541 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
135542 + spin_unlock(&__fq478->fqlock); \
135543 + } while (0)
135544 +
135545 +static inline void fq_set(struct qman_fq *fq, u32 mask)
135546 +{
135547 + set_bits(mask, &fq->flags);
135548 +}
135549 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
135550 +{
135551 + clear_bits(mask, &fq->flags);
135552 +}
135553 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
135554 +{
135555 + return fq->flags & mask;
135556 +}
135557 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
135558 +{
135559 + return !(fq->flags & mask);
135560 +}
135561 +
135562 +struct qman_portal {
135563 + struct qm_portal p;
135564 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
135565 + unsigned long irq_sources;
135566 + u32 use_eqcr_ci_stashing;
135567 + u32 slowpoll; /* only used when interrupts are off */
135568 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
135569 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
135570 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
135571 +#endif
135572 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135573 + raw_spinlock_t sharing_lock; /* only used if is_shared */
135574 + int is_shared;
135575 + struct qman_portal *sharing_redirect;
135576 +#endif
135577 + u32 sdqcr;
135578 + int dqrr_disable_ref;
135579 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
135580 + * handler is called instead. */
135581 + qman_cb_dc_ern cb_dc_ern;
135582 + /* When the cpu-affine portal is activated, this is non-NULL */
135583 + const struct qm_portal_config *config;
135584 + /* This is needed for providing a non-NULL device to dma_map_***() */
135585 + struct platform_device *pdev;
135586 + struct dpa_rbtree retire_table;
135587 + char irqname[MAX_IRQNAME];
135588 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
135589 + struct qman_cgrs *cgrs;
135590 + /* linked-list of CSCN handlers. */
135591 + struct list_head cgr_cbs;
135592 + /* list lock */
135593 + spinlock_t cgr_lock;
135594 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
135595 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
135596 + /* 256-element array, each is a linked-list of CCSCN handlers. */
135597 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
135598 + /* list lock */
135599 + spinlock_t ccgr_lock;
135600 + /* track if memory was allocated by the driver */
135601 + u8 alloced;
135602 + /* power management data */
135603 + u32 save_isdr;
135604 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
135605 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
135606 + * do byte swaps of DQRR read only memory. First entry must be aligned
135607 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
135608 + * address (6 bits for address shift + 4 bits for the DQRR size).
135609 + */
135610 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
135611 +#endif
135612 +};
135613 +
135614 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135615 +#define PORTAL_IRQ_LOCK(p, irqflags) \
135616 + do { \
135617 + if ((p)->is_shared) \
135618 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
135619 + else \
135620 + local_irq_save(irqflags); \
135621 + } while (0)
135622 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
135623 + do { \
135624 + if ((p)->is_shared) \
135625 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
135626 + irqflags); \
135627 + else \
135628 + local_irq_restore(irqflags); \
135629 + } while (0)
135630 +#else
135631 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
135632 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
135633 +#endif
135634 +
135635 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
135636 + * not have a portal-specific handler. */
135637 +static qman_cb_dc_ern cb_dc_ern;
135638 +
135639 +static cpumask_t affine_mask;
135640 +static DEFINE_SPINLOCK(affine_mask_lock);
135641 +static u16 affine_channels[NR_CPUS];
135642 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
135643 +void *affine_portals[NR_CPUS];
135644 +
135645 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
135646 +static inline struct qman_portal *get_raw_affine_portal(void)
135647 +{
135648 + return &get_cpu_var(qman_affine_portal);
135649 +}
135650 +/* For ops that can redirect, this obtains the portal to use */
135651 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
135652 +static inline struct qman_portal *get_affine_portal(void)
135653 +{
135654 + struct qman_portal *p = get_raw_affine_portal();
135655 + if (p->sharing_redirect)
135656 + return p->sharing_redirect;
135657 + return p;
135658 +}
135659 +#else
135660 +#define get_affine_portal() get_raw_affine_portal()
135661 +#endif
135662 +/* For every "get", there must be a "put" */
135663 +static inline void put_affine_portal(void)
135664 +{
135665 + put_cpu_var(qman_affine_portal);
135666 +}
135667 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
135668 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
135669 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
135670 + * context to remain as non-atomic during poll-triggered callbacks as it was
135671 + * when the poll API was first called (eg. NAPI), so we go out of our way in
135672 + * this case to not disable pre-emption. */
135673 +static inline struct qman_portal *get_poll_portal(void)
135674 +{
135675 + return &get_cpu_var(qman_affine_portal);
135676 +}
135677 +#define put_poll_portal()
135678 +
135679 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
135680 + * retirement notifications (the fact they are sometimes h/w-consumed means that
135681 + * contextB isn't always a s/w demux - and as we can't know which case it is
135682 + * when looking at the notification, we have to use the slow lookup for all of
135683 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
135684 + * (though at most one of them should be the consumer), so this table isn't for
135685 + * all FQs - FQs are added when retirement commands are issued, and removed when
135686 + * they complete, which also massively reduces the size of this table. */
135687 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
135688 +
135689 +/* This is what everything can wait on, even if it migrates to a different cpu
135690 + * to the one whose affine portal it is waiting on. */
135691 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
135692 +
135693 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
135694 +{
135695 + int ret = fqtree_push(&p->retire_table, fq);
135696 + if (ret)
135697 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
135698 + return ret;
135699 +}
135700 +
135701 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
135702 +{
135703 + fqtree_del(&p->retire_table, fq);
135704 +}
135705 +
135706 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
135707 +{
135708 + return fqtree_find(&p->retire_table, fqid);
135709 +}
135710 +
135711 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135712 +static void **qman_fq_lookup_table;
135713 +static size_t qman_fq_lookup_table_size;
135714 +
135715 +int qman_setup_fq_lookup_table(size_t num_entries)
135716 +{
135717 + num_entries++;
135718 + /* Allocate 1 more entry since the first entry is not used */
135719 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
135720 + if (!qman_fq_lookup_table) {
135721 + pr_err("QMan: Could not allocate fq lookup table\n");
135722 + return -ENOMEM;
135723 + }
135724 + qman_fq_lookup_table_size = num_entries;
135725 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
135726 + qman_fq_lookup_table,
135727 + (unsigned long)qman_fq_lookup_table_size);
135728 + return 0;
135729 +}
135730 +
135731 +/* global structure that maintains fq object mapping */
135732 +static DEFINE_SPINLOCK(fq_hash_table_lock);
135733 +
135734 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
135735 +{
135736 + u32 i;
135737 +
135738 + spin_lock(&fq_hash_table_lock);
135739 + /* Can't use index zero because this has special meaning
135740 + * in context_b field. */
135741 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
135742 + if (qman_fq_lookup_table[i] == NULL) {
135743 + *entry = i;
135744 + qman_fq_lookup_table[i] = fq;
135745 + spin_unlock(&fq_hash_table_lock);
135746 + return 0;
135747 + }
135748 + }
135749 + spin_unlock(&fq_hash_table_lock);
135750 + return -ENOMEM;
135751 +}
135752 +
135753 +static void clear_fq_table_entry(u32 entry)
135754 +{
135755 + spin_lock(&fq_hash_table_lock);
135756 + BUG_ON(entry >= qman_fq_lookup_table_size);
135757 + qman_fq_lookup_table[entry] = NULL;
135758 + spin_unlock(&fq_hash_table_lock);
135759 +}
135760 +
135761 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
135762 +{
135763 + BUG_ON(entry >= qman_fq_lookup_table_size);
135764 + return qman_fq_lookup_table[entry];
135765 +}
135766 +#endif
135767 +
135768 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
135769 +{
135770 + /* Byteswap the FQD to HW format */
135771 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
135772 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
135773 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
135774 + fqd->context_b = cpu_to_be32(fqd->context_b);
135775 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
135776 +}
135777 +
135778 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
135779 +{
135780 + /* Byteswap the FQD to CPU format */
135781 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
135782 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
135783 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
135784 + fqd->context_b = be32_to_cpu(fqd->context_b);
135785 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
135786 +}
135787 +
135788 +/* Swap a 40 bit address */
135789 +static inline u64 cpu_to_be40(u64 in)
135790 +{
135791 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
135792 + return in;
135793 +#else
135794 + u64 out = 0;
135795 + u8 *p = (u8 *) &out;
135796 + p[0] = in >> 32;
135797 + p[1] = in >> 24;
135798 + p[2] = in >> 16;
135799 + p[3] = in >> 8;
135800 + p[4] = in >> 0;
135801 + return out;
135802 +#endif
135803 +}
135804 +static inline u64 be40_to_cpu(u64 in)
135805 +{
135806 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
135807 + return in;
135808 +#else
135809 + u64 out = 0;
135810 + u8 *pout = (u8 *) &out;
135811 + u8 *pin = (u8 *) &in;
135812 + pout[0] = pin[4];
135813 + pout[1] = pin[3];
135814 + pout[2] = pin[2];
135815 + pout[3] = pin[1];
135816 + pout[4] = pin[0];
135817 + return out;
135818 +#endif
135819 +}
135820 +
135821 +/* Swap a 24 bit value */
135822 +static inline u32 cpu_to_be24(u32 in)
135823 +{
135824 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
135825 + return in;
135826 +#else
135827 + u32 out = 0;
135828 + u8 *p = (u8 *) &out;
135829 + p[0] = in >> 16;
135830 + p[1] = in >> 8;
135831 + p[2] = in >> 0;
135832 + return out;
135833 +#endif
135834 +}
135835 +
135836 +static inline u32 be24_to_cpu(u32 in)
135837 +{
135838 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
135839 + return in;
135840 +#else
135841 + u32 out = 0;
135842 + u8 *pout = (u8 *) &out;
135843 + u8 *pin = (u8 *) &in;
135844 + pout[0] = pin[2];
135845 + pout[1] = pin[1];
135846 + pout[2] = pin[0];
135847 + return out;
135848 +#endif
135849 +}
135850 +
135851 +static inline u64 be48_to_cpu(u64 in)
135852 +{
135853 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
135854 + return in;
135855 +#else
135856 + u64 out = 0;
135857 + u8 *pout = (u8 *) &out;
135858 + u8 *pin = (u8 *) &in;
135859 +
135860 + pout[0] = pin[5];
135861 + pout[1] = pin[4];
135862 + pout[2] = pin[3];
135863 + pout[3] = pin[2];
135864 + pout[4] = pin[1];
135865 + pout[5] = pin[0];
135866 + return out;
135867 +#endif
135868 +}
135869 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
135870 +{
135871 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
135872 + fd->status = cpu_to_be32(fd->status);
135873 + fd->opaque = cpu_to_be32(fd->opaque);
135874 +}
135875 +
135876 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
135877 +{
135878 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
135879 + fd->status = be32_to_cpu(fd->status);
135880 + fd->opaque = be32_to_cpu(fd->opaque);
135881 +}
135882 +
135883 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
135884 +{
135885 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
135886 + cq_query->state = be16_to_cpu(cq_query->state);
135887 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
135888 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
135889 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
135890 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
135891 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
135892 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
135893 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
135894 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
135895 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
135896 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
135897 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
135898 +}
135899 +
135900 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
135901 +{
135902 + int i;
135903 +
135904 + ccgr_q->cm_query.cs_thres.hword =
135905 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
135906 + ccgr_q->cm_query.cs_thres_x.hword =
135907 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
135908 + ccgr_q->cm_query.td_thres.hword =
135909 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
135910 + ccgr_q->cm_query.wr_parm_g.word =
135911 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
135912 + ccgr_q->cm_query.wr_parm_y.word =
135913 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
135914 + ccgr_q->cm_query.wr_parm_r.word =
135915 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
135916 + ccgr_q->cm_query.cscn_targ_dcp =
135917 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
135918 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
135919 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
135920 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
135921 + ccgr_q->cm_query.cscn_targ_swp[i] =
135922 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
135923 +}
135924 +
135925 +/* In the case that slow- and fast-path handling are both done by qman_poll()
135926 + * (ie. because there is no interrupt handling), we ought to balance how often
135927 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
135928 + * sources, so we call the fast poll 'n' times before calling the slow poll
135929 + * once. The idle decrementer constant is used when the last slow-poll detected
135930 + * no work to do, and the busy decrementer constant when the last slow-poll had
135931 + * work to do. */
135932 +#define SLOW_POLL_IDLE 1000
135933 +#define SLOW_POLL_BUSY 10
135934 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
135935 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
135936 + unsigned int poll_limit);
135937 +
135938 +/* Portal interrupt handler */
135939 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
135940 +{
135941 + struct qman_portal *p = ptr;
135942 + /*
135943 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
135944 + * it could race against a Query Congestion State command also given
135945 + * as part of the handling of this interrupt source. We mustn't
135946 + * clear it a second time in this top-level function.
135947 + */
135948 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
135949 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
135950 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
135951 + /* DQRR-handling if it's interrupt-driven */
135952 + if (is & QM_PIRQ_DQRI)
135953 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
135954 + /* Handling of anything else that's interrupt-driven */
135955 + clear |= __poll_portal_slow(p, is);
135956 + qm_isr_status_clear(&p->p, clear);
135957 + return IRQ_HANDLED;
135958 +}
135959 +
135960 +/* This inner version is used privately by qman_create_affine_portal(), as well
135961 + * as by the exported qman_stop_dequeues(). */
135962 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
135963 +{
135964 + unsigned long irqflags __maybe_unused;
135965 + PORTAL_IRQ_LOCK(p, irqflags);
135966 + if (!(p->dqrr_disable_ref++))
135967 + qm_dqrr_set_maxfill(&p->p, 0);
135968 + PORTAL_IRQ_UNLOCK(p, irqflags);
135969 +}
135970 +
135971 +static int drain_mr_fqrni(struct qm_portal *p)
135972 +{
135973 + const struct qm_mr_entry *msg;
135974 +loop:
135975 + msg = qm_mr_current(p);
135976 + if (!msg) {
135977 + /* if MR was full and h/w had other FQRNI entries to produce, we
135978 + * need to allow it time to produce those entries once the
135979 + * existing entries are consumed. A worst-case situation
135980 + * (fully-loaded system) means h/w sequencers may have to do 3-4
135981 + * other things before servicing the portal's MR pump, each of
135982 + * which (if slow) may take ~50 qman cycles (which is ~200
135983 + * processor cycles). So rounding up and then multiplying this
135984 + * worst-case estimate by a factor of 10, just to be
135985 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
135986 + * one entry at a time, so h/w has an opportunity to produce new
135987 + * entries well before the ring has been fully consumed, so
135988 + * we're being *really* paranoid here. */
135989 + u64 now, then = mfatb();
135990 + do {
135991 + now = mfatb();
135992 + } while ((then + 10000) > now);
135993 + msg = qm_mr_current(p);
135994 + if (!msg)
135995 + return 0;
135996 + }
135997 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
135998 + /* We aren't draining anything but FQRNIs */
135999 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
136000 + return -1;
136001 + }
136002 + qm_mr_next(p);
136003 + qm_mr_cci_consume(p, 1);
136004 + goto loop;
136005 +}
136006 +
136007 +#ifdef CONFIG_SUSPEND
136008 +static int _qman_portal_suspend_noirq(struct device *dev)
136009 +{
136010 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136011 +#ifdef CONFIG_PM_DEBUG
136012 + struct platform_device *pdev = to_platform_device(dev);
136013 +#endif
136014 +
136015 + p->save_isdr = qm_isr_disable_read(&p->p);
136016 + qm_isr_disable_write(&p->p, 0xffffffff);
136017 + qm_isr_status_clear(&p->p, 0xffffffff);
136018 +#ifdef CONFIG_PM_DEBUG
136019 + pr_info("Suspend for %s\n", pdev->name);
136020 +#endif
136021 + return 0;
136022 +}
136023 +
136024 +static int _qman_portal_resume_noirq(struct device *dev)
136025 +{
136026 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136027 +
136028 + /* restore isdr */
136029 + qm_isr_disable_write(&p->p, p->save_isdr);
136030 + return 0;
136031 +}
136032 +#else
136033 +#define _qman_portal_suspend_noirq NULL
136034 +#define _qman_portal_resume_noirq NULL
136035 +#endif
136036 +
136037 +struct dev_pm_domain qman_portal_device_pm_domain = {
136038 + .ops = {
136039 + USE_PLATFORM_PM_SLEEP_OPS
136040 + .suspend_noirq = _qman_portal_suspend_noirq,
136041 + .resume_noirq = _qman_portal_resume_noirq,
136042 + }
136043 +};
136044 +
136045 +struct qman_portal *qman_create_portal(
136046 + struct qman_portal *portal,
136047 + const struct qm_portal_config *config,
136048 + const struct qman_cgrs *cgrs)
136049 +{
136050 + struct qm_portal *__p;
136051 + char buf[16];
136052 + int ret;
136053 + u32 isdr;
136054 +
136055 + if (!portal) {
136056 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
136057 + if (!portal)
136058 + return portal;
136059 + portal->alloced = 1;
136060 + } else
136061 + portal->alloced = 0;
136062 +
136063 + __p = &portal->p;
136064 +
136065 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
136066 + /* PAMU is required for stashing */
136067 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
136068 + 1 : 0);
136069 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136070 + portal->use_eqcr_ci_stashing = 1;
136071 +#else
136072 + portal->use_eqcr_ci_stashing = 0;
136073 +#endif
136074 +
136075 + /* prep the low-level portal struct with the mapped addresses from the
136076 + * config, everything that follows depends on it and "config" is more
136077 + * for (de)reference... */
136078 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
136079 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
136080 + /*
136081 + * If CI-stashing is used, the current defaults use a threshold of 3,
136082 + * and stash with high-than-DQRR priority.
136083 + */
136084 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
136085 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
136086 + pr_err("Qman EQCR initialisation failed\n");
136087 + goto fail_eqcr;
136088 + }
136089 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
136090 + qm_dqrr_cdc, DQRR_MAXFILL)) {
136091 + pr_err("Qman DQRR initialisation failed\n");
136092 + goto fail_dqrr;
136093 + }
136094 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
136095 + pr_err("Qman MR initialisation failed\n");
136096 + goto fail_mr;
136097 + }
136098 + if (qm_mc_init(__p)) {
136099 + pr_err("Qman MC initialisation failed\n");
136100 + goto fail_mc;
136101 + }
136102 + if (qm_isr_init(__p)) {
136103 + pr_err("Qman ISR initialisation failed\n");
136104 + goto fail_isr;
136105 + }
136106 + /* static interrupt-gating controls */
136107 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
136108 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
136109 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
136110 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
136111 + if (!portal->cgrs)
136112 + goto fail_cgrs;
136113 + /* initial snapshot is no-depletion */
136114 + qman_cgrs_init(&portal->cgrs[1]);
136115 + if (cgrs)
136116 + portal->cgrs[0] = *cgrs;
136117 + else
136118 + /* if the given mask is NULL, assume all CGRs can be seen */
136119 + qman_cgrs_fill(&portal->cgrs[0]);
136120 + INIT_LIST_HEAD(&portal->cgr_cbs);
136121 + spin_lock_init(&portal->cgr_lock);
136122 + if (num_ceetms) {
136123 + for (ret = 0; ret < num_ceetms; ret++) {
136124 + portal->ccgrs[ret] = kmalloc(2 *
136125 + sizeof(struct qman_ccgrs), GFP_KERNEL);
136126 + if (!portal->ccgrs[ret])
136127 + goto fail_ccgrs;
136128 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
136129 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
136130 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
136131 + }
136132 + }
136133 + spin_lock_init(&portal->ccgr_lock);
136134 + portal->bits = 0;
136135 + portal->slowpoll = 0;
136136 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136137 + portal->eqci_owned = NULL;
136138 +#endif
136139 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136140 + raw_spin_lock_init(&portal->sharing_lock);
136141 + portal->is_shared = config->public_cfg.is_shared;
136142 + portal->sharing_redirect = NULL;
136143 +#endif
136144 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
136145 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
136146 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
136147 + portal->dqrr_disable_ref = 0;
136148 + portal->cb_dc_ern = NULL;
136149 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
136150 + portal->pdev = platform_device_alloc(buf, -1);
136151 + if (!portal->pdev) {
136152 + pr_err("qman_portal - platform_device_alloc() failed\n");
136153 + goto fail_devalloc;
136154 + }
136155 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136156 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
136157 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
136158 +#else
136159 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
136160 + pr_err("qman_portal - dma_set_mask() failed\n");
136161 + goto fail_devadd;
136162 + }
136163 +#endif
136164 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
136165 + portal->pdev->dev.platform_data = portal;
136166 + ret = platform_device_add(portal->pdev);
136167 + if (ret) {
136168 + pr_err("qman_portal - platform_device_add() failed\n");
136169 + goto fail_devadd;
136170 + }
136171 + dpa_rbtree_init(&portal->retire_table);
136172 + isdr = 0xffffffff;
136173 + qm_isr_disable_write(__p, isdr);
136174 + portal->irq_sources = 0;
136175 + qm_isr_enable_write(__p, portal->irq_sources);
136176 + qm_isr_status_clear(__p, 0xffffffff);
136177 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
136178 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
136179 + portal)) {
136180 + pr_err("request_irq() failed\n");
136181 + goto fail_irq;
136182 + }
136183 + if ((config->public_cfg.cpu != -1) &&
136184 + irq_can_set_affinity(config->public_cfg.irq) &&
136185 + irq_set_affinity(config->public_cfg.irq,
136186 + cpumask_of(config->public_cfg.cpu))) {
136187 + pr_err("irq_set_affinity() failed\n");
136188 + goto fail_affinity;
136189 + }
136190 +
136191 + /* Need EQCR to be empty before continuing */
136192 + isdr ^= QM_PIRQ_EQCI;
136193 + qm_isr_disable_write(__p, isdr);
136194 + ret = qm_eqcr_get_fill(__p);
136195 + if (ret) {
136196 + pr_err("Qman EQCR unclean\n");
136197 + goto fail_eqcr_empty;
136198 + }
136199 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
136200 + qm_isr_disable_write(__p, isdr);
136201 + if (qm_dqrr_current(__p) != NULL) {
136202 + pr_err("Qman DQRR unclean\n");
136203 + qm_dqrr_cdc_consume_n(__p, 0xffff);
136204 + }
136205 + if (qm_mr_current(__p) != NULL) {
136206 + /* special handling, drain just in case it's a few FQRNIs */
136207 + if (drain_mr_fqrni(__p)) {
136208 + const struct qm_mr_entry *e = qm_mr_current(__p);
136209 + /*
136210 + * Message ring cannot be empty no need to check
136211 + * qm_mr_current returned successfully
136212 + */
136213 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
136214 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
136215 + goto fail_dqrr_mr_empty;
136216 + }
136217 + }
136218 + /* Success */
136219 + portal->config = config;
136220 + qm_isr_disable_write(__p, 0);
136221 + qm_isr_uninhibit(__p);
136222 + /* Write a sane SDQCR */
136223 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
136224 + return portal;
136225 +fail_dqrr_mr_empty:
136226 +fail_eqcr_empty:
136227 +fail_affinity:
136228 + free_irq(config->public_cfg.irq, portal);
136229 +fail_irq:
136230 + platform_device_del(portal->pdev);
136231 +fail_devadd:
136232 + platform_device_put(portal->pdev);
136233 +fail_devalloc:
136234 + if (num_ceetms)
136235 + for (ret = 0; ret < num_ceetms; ret++)
136236 + kfree(portal->ccgrs[ret]);
136237 +fail_ccgrs:
136238 + kfree(portal->cgrs);
136239 +fail_cgrs:
136240 + qm_isr_finish(__p);
136241 +fail_isr:
136242 + qm_mc_finish(__p);
136243 +fail_mc:
136244 + qm_mr_finish(__p);
136245 +fail_mr:
136246 + qm_dqrr_finish(__p);
136247 +fail_dqrr:
136248 + qm_eqcr_finish(__p);
136249 +fail_eqcr:
136250 + if (portal->alloced)
136251 + kfree(portal);
136252 + return NULL;
136253 +}
136254 +
136255 +struct qman_portal *qman_create_affine_portal(
136256 + const struct qm_portal_config *config,
136257 + const struct qman_cgrs *cgrs)
136258 +{
136259 + struct qman_portal *res;
136260 + struct qman_portal *portal;
136261 +
136262 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
136263 + res = qman_create_portal(portal, config, cgrs);
136264 + if (res) {
136265 + spin_lock(&affine_mask_lock);
136266 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
136267 + affine_channels[config->public_cfg.cpu] =
136268 + config->public_cfg.channel;
136269 + affine_portals[config->public_cfg.cpu] = portal;
136270 + spin_unlock(&affine_mask_lock);
136271 + }
136272 + return res;
136273 +}
136274 +
136275 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
136276 + * these cases. */
136277 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
136278 + int cpu)
136279 +{
136280 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136281 + struct qman_portal *p;
136282 + p = &per_cpu(qman_affine_portal, cpu);
136283 + /* Check that we don't already have our own portal */
136284 + BUG_ON(p->config);
136285 + /* Check that we aren't already slaving to another portal */
136286 + BUG_ON(p->is_shared);
136287 + /* Check that 'redirect' is prepared to have us */
136288 + BUG_ON(!redirect->config->public_cfg.is_shared);
136289 + /* These are the only elements to initialise when redirecting */
136290 + p->irq_sources = 0;
136291 + p->sharing_redirect = redirect;
136292 + affine_portals[cpu] = p;
136293 + return p;
136294 +#else
136295 + BUG();
136296 + return NULL;
136297 +#endif
136298 +}
136299 +
136300 +void qman_destroy_portal(struct qman_portal *qm)
136301 +{
136302 + const struct qm_portal_config *pcfg;
136303 + int i;
136304 +
136305 + /* Stop dequeues on the portal */
136306 + qm_dqrr_sdqcr_set(&qm->p, 0);
136307 +
136308 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
136309 + * something related to QM_PIRQ_EQCI, this may need fixing.
136310 + * Also, due to the prefetching model used for CI updates in the enqueue
136311 + * path, this update will only invalidate the CI cacheline *after*
136312 + * working on it, so we need to call this twice to ensure a full update
136313 + * irrespective of where the enqueue processing was at when the teardown
136314 + * began. */
136315 + qm_eqcr_cce_update(&qm->p);
136316 + qm_eqcr_cce_update(&qm->p);
136317 + pcfg = qm->config;
136318 +
136319 + free_irq(pcfg->public_cfg.irq, qm);
136320 +
136321 + kfree(qm->cgrs);
136322 + if (num_ceetms)
136323 + for (i = 0; i < num_ceetms; i++)
136324 + kfree(qm->ccgrs[i]);
136325 + qm_isr_finish(&qm->p);
136326 + qm_mc_finish(&qm->p);
136327 + qm_mr_finish(&qm->p);
136328 + qm_dqrr_finish(&qm->p);
136329 + qm_eqcr_finish(&qm->p);
136330 +
136331 + platform_device_del(qm->pdev);
136332 + platform_device_put(qm->pdev);
136333 +
136334 + qm->config = NULL;
136335 + if (qm->alloced)
136336 + kfree(qm);
136337 +}
136338 +
136339 +const struct qm_portal_config *qman_destroy_affine_portal(void)
136340 +{
136341 + /* We don't want to redirect if we're a slave, use "raw" */
136342 + struct qman_portal *qm = get_raw_affine_portal();
136343 + const struct qm_portal_config *pcfg;
136344 + int cpu;
136345 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136346 + if (qm->sharing_redirect) {
136347 + qm->sharing_redirect = NULL;
136348 + put_affine_portal();
136349 + return NULL;
136350 + }
136351 + qm->is_shared = 0;
136352 +#endif
136353 + pcfg = qm->config;
136354 + cpu = pcfg->public_cfg.cpu;
136355 +
136356 + qman_destroy_portal(qm);
136357 +
136358 + spin_lock(&affine_mask_lock);
136359 + cpumask_clear_cpu(cpu, &affine_mask);
136360 + spin_unlock(&affine_mask_lock);
136361 + put_affine_portal();
136362 + return pcfg;
136363 +}
136364 +
136365 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
136366 +{
136367 + return &p->config->public_cfg;
136368 +}
136369 +EXPORT_SYMBOL(qman_p_get_portal_config);
136370 +
136371 +const struct qman_portal_config *qman_get_portal_config(void)
136372 +{
136373 + struct qman_portal *p = get_affine_portal();
136374 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
136375 + put_affine_portal();
136376 + return ret;
136377 +}
136378 +EXPORT_SYMBOL(qman_get_portal_config);
136379 +
136380 +/* Inline helper to reduce nesting in __poll_portal_slow() */
136381 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
136382 + const struct qm_mr_entry *msg, u8 verb)
136383 +{
136384 + FQLOCK(fq);
136385 + switch (verb) {
136386 + case QM_MR_VERB_FQRL:
136387 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
136388 + fq_clear(fq, QMAN_FQ_STATE_ORL);
136389 + table_del_fq(p, fq);
136390 + break;
136391 + case QM_MR_VERB_FQRN:
136392 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
136393 + (fq->state == qman_fq_state_sched));
136394 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
136395 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
136396 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
136397 + fq_set(fq, QMAN_FQ_STATE_NE);
136398 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
136399 + fq_set(fq, QMAN_FQ_STATE_ORL);
136400 + else
136401 + table_del_fq(p, fq);
136402 + fq->state = qman_fq_state_retired;
136403 + break;
136404 + case QM_MR_VERB_FQPN:
136405 + DPA_ASSERT(fq->state == qman_fq_state_sched);
136406 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
136407 + fq->state = qman_fq_state_parked;
136408 + }
136409 + FQUNLOCK(fq);
136410 +}
136411 +
136412 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
136413 +{
136414 + const struct qm_mr_entry *msg;
136415 + struct qm_mr_entry swapped_msg;
136416 + int k;
136417 +
136418 + if (is & QM_PIRQ_CSCI) {
136419 + struct qman_cgrs rr, c;
136420 + struct qm_mc_result *mcr;
136421 + struct qman_cgr *cgr;
136422 + unsigned long irqflags __maybe_unused;
136423 +
136424 + spin_lock_irqsave(&p->cgr_lock, irqflags);
136425 + /*
136426 + * The CSCI bit must be cleared _before_ issuing the
136427 + * Query Congestion State command, to ensure that a long
136428 + * CGR State Change callback cannot miss an intervening
136429 + * state change.
136430 + */
136431 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
136432 + qm_mc_start(&p->p);
136433 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
136434 + while (!(mcr = qm_mc_result(&p->p)))
136435 + cpu_relax();
136436 + for (k = 0; k < 8; k++)
136437 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
136438 + mcr->querycongestion.state.__state[k]);
136439 + /* mask out the ones I'm not interested in */
136440 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
136441 + &mcr->querycongestion.state, &p->cgrs[0]);
136442 + /* check previous snapshot for delta, enter/exit congestion */
136443 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
136444 + /* update snapshot */
136445 + qman_cgrs_cp(&p->cgrs[1], &rr);
136446 + /* Invoke callback */
136447 + list_for_each_entry(cgr, &p->cgr_cbs, node)
136448 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
136449 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
136450 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
136451 + }
136452 + if (is & QM_PIRQ_CCSCI) {
136453 + struct qman_ccgrs rr, c, congestion_result;
136454 + struct qm_mc_result *mcr;
136455 + struct qm_mc_command *mcc;
136456 + struct qm_ceetm_ccg *ccg;
136457 + unsigned long irqflags __maybe_unused;
136458 + int i, j;
136459 +
136460 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
136461 + /*
136462 + * The CCSCI bit must be cleared _before_ issuing the
136463 + * Query Congestion State command, to ensure that a long
136464 + * CCGR State Change callback cannot miss an intervening
136465 + * state change.
136466 + */
136467 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
136468 +
136469 + for (i = 0; i < num_ceetms; i++) {
136470 + for (j = 0; j < 2; j++) {
136471 + mcc = qm_mc_start(&p->p);
136472 + mcc->ccgr_query.ccgrid = cpu_to_be16(
136473 + CEETM_QUERY_CONGESTION_STATE | j);
136474 + mcc->ccgr_query.dcpid = i;
136475 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
136476 + while (!(mcr = qm_mc_result(&p->p)))
136477 + cpu_relax();
136478 + for (k = 0; k < 8; k++)
136479 + mcr->ccgr_query.congestion_state.state.
136480 + __state[k] = be32_to_cpu(
136481 + mcr->ccgr_query.
136482 + congestion_state.state.
136483 + __state[k]);
136484 + congestion_result.q[j] =
136485 + mcr->ccgr_query.congestion_state.state;
136486 + }
136487 + /* mask out the ones I'm not interested in */
136488 + qman_ccgrs_and(&rr, &congestion_result,
136489 + &p->ccgrs[i][0]);
136490 + /*
136491 + * check previous snapshot for delta, enter/exit
136492 + * congestion.
136493 + */
136494 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
136495 + /* update snapshot */
136496 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
136497 + /* Invoke callback */
136498 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
136499 + if (ccg->cb && qman_ccgrs_get(&c,
136500 + (ccg->parent->idx << 4) | ccg->idx))
136501 + ccg->cb(ccg, ccg->cb_ctx,
136502 + qman_ccgrs_get(&rr,
136503 + (ccg->parent->idx << 4)
136504 + | ccg->idx));
136505 + }
136506 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
136507 + }
136508 +
136509 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136510 + if (is & QM_PIRQ_EQCI) {
136511 + unsigned long irqflags;
136512 + PORTAL_IRQ_LOCK(p, irqflags);
136513 + p->eqci_owned = NULL;
136514 + PORTAL_IRQ_UNLOCK(p, irqflags);
136515 + wake_up(&affine_queue);
136516 + }
136517 +#endif
136518 +
136519 + if (is & QM_PIRQ_EQRI) {
136520 + unsigned long irqflags __maybe_unused;
136521 + PORTAL_IRQ_LOCK(p, irqflags);
136522 + qm_eqcr_cce_update(&p->p);
136523 + qm_eqcr_set_ithresh(&p->p, 0);
136524 + PORTAL_IRQ_UNLOCK(p, irqflags);
136525 + wake_up(&affine_queue);
136526 + }
136527 +
136528 + if (is & QM_PIRQ_MRI) {
136529 + struct qman_fq *fq;
136530 + u8 verb, num = 0;
136531 +mr_loop:
136532 + qm_mr_pvb_update(&p->p);
136533 + msg = qm_mr_current(&p->p);
136534 + if (!msg)
136535 + goto mr_done;
136536 + swapped_msg = *msg;
136537 + hw_fd_to_cpu(&swapped_msg.ern.fd);
136538 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
136539 + /* The message is a software ERN iff the 0x20 bit is set */
136540 + if (verb & 0x20) {
136541 + switch (verb) {
136542 + case QM_MR_VERB_FQRNI:
136543 + /* nada, we drop FQRNIs on the floor */
136544 + break;
136545 + case QM_MR_VERB_FQRN:
136546 + case QM_MR_VERB_FQRL:
136547 + /* Lookup in the retirement table */
136548 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
136549 + BUG_ON(!fq);
136550 + fq_state_change(p, fq, &swapped_msg, verb);
136551 + if (fq->cb.fqs)
136552 + fq->cb.fqs(p, fq, &swapped_msg);
136553 + break;
136554 + case QM_MR_VERB_FQPN:
136555 + /* Parked */
136556 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136557 + fq = get_fq_table_entry(
136558 + be32_to_cpu(msg->fq.contextB));
136559 +#else
136560 + fq = (void *)(uintptr_t)
136561 + be32_to_cpu(msg->fq.contextB);
136562 +#endif
136563 + fq_state_change(p, fq, msg, verb);
136564 + if (fq->cb.fqs)
136565 + fq->cb.fqs(p, fq, &swapped_msg);
136566 + break;
136567 + case QM_MR_VERB_DC_ERN:
136568 + /* DCP ERN */
136569 + if (p->cb_dc_ern)
136570 + p->cb_dc_ern(p, msg);
136571 + else if (cb_dc_ern)
136572 + cb_dc_ern(p, msg);
136573 + else {
136574 + static int warn_once;
136575 + if (!warn_once) {
136576 + pr_crit("Leaking DCP ERNs!\n");
136577 + warn_once = 1;
136578 + }
136579 + }
136580 + break;
136581 + default:
136582 + pr_crit("Invalid MR verb 0x%02x\n", verb);
136583 + }
136584 + } else {
136585 + /* Its a software ERN */
136586 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136587 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
136588 +#else
136589 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
136590 +#endif
136591 + fq->cb.ern(p, fq, &swapped_msg);
136592 + }
136593 + num++;
136594 + qm_mr_next(&p->p);
136595 + goto mr_loop;
136596 +mr_done:
136597 + qm_mr_cci_consume(&p->p, num);
136598 + }
136599 + /*
136600 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
136601 + * processing. If that interrupt source has meanwhile been re-asserted,
136602 + * we mustn't clear it here (or in the top-level interrupt handler).
136603 + */
136604 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
136605 +}
136606 +
136607 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
136608 + * inlined. */
136609 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
136610 +{
136611 + p->vdqcr_owned = NULL;
136612 + FQLOCK(fq);
136613 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
136614 + FQUNLOCK(fq);
136615 + wake_up(&affine_queue);
136616 +}
136617 +
136618 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
136619 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
136620 + const struct qm_dqrr_entry *src)
136621 +{
136622 + int i = 0;
136623 + const u64 *s64 = (u64*)src;
136624 + u64 *d64 = (u64*)dst;
136625 +
136626 + /* DQRR only has 32 bytes of valid data so only need to
136627 + * copy 4 - 64 bit values */
136628 + *d64 = *s64;
136629 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136630 + {
136631 + u32 res, zero = 0;
136632 + /* Create a dependancy after copying first bytes ensures no wrap
136633 + transaction generated to QBMan */
136634 + /* Logical AND the value pointed to by s64 with 0x0 and
136635 + store the result in res */
136636 + asm volatile("and %[result], %[in1], %[in2]"
136637 + : [result] "=r" (res)
136638 + : [in1] "r" (zero), [in2] "r" (*s64)
136639 + : "memory");
136640 + /* Add res to s64 - this creates a dependancy on the result of
136641 + reading the value of s64 before the next read. The side
136642 + effect of this is that the core must stall until the first
136643 + aligned read is complete therefore preventing a WRAP
136644 + transaction to be seen by the QBMan */
136645 + asm volatile("add %[result], %[in1], %[in2]"
136646 + : [result] "=r" (s64)
136647 + : [in1] "r" (res), [in2] "r" (s64)
136648 + : "memory");
136649 + }
136650 +#endif
136651 + /* Copy the last 3 64 bit parts */
136652 + d64++; s64++;
136653 + for (;i<3; i++)
136654 + *d64++ = *s64++;
136655 +}
136656 +
136657 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
136658 + * that would conflict with other things if they ran at the same time on the
136659 + * same cpu are;
136660 + *
136661 + * (i) setting/clearing vdqcr_owned, and
136662 + * (ii) clearing the NE (Not Empty) flag.
136663 + *
136664 + * Both are safe. Because;
136665 + *
136666 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
136667 + * vdqcr_owned field (which it does before setting VDQCR), and
136668 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
136669 + * done so that we can't interfere.
136670 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
136671 + * with (i) that API prevents us from interfering until it's safe.
136672 + *
136673 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
136674 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
136675 + * advantage comes from this function not having to "lock" anything at all.
136676 + *
136677 + * Note also that the callbacks are invoked at points which are safe against the
136678 + * above potential conflicts, but that this function itself is not re-entrant
136679 + * (this is because the function tracks one end of each FIFO in the portal and
136680 + * we do *not* want to lock that). So the consequence is that it is safe for
136681 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
136682 + * sole API that could be invoking the callback through this function).
136683 + */
136684 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136685 + unsigned int poll_limit)
136686 +{
136687 + const struct qm_dqrr_entry *dq;
136688 + struct qman_fq *fq;
136689 + enum qman_cb_dqrr_result res;
136690 + unsigned int limit = 0;
136691 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136692 + struct qm_dqrr_entry *shadow;
136693 + const struct qm_dqrr_entry *orig_dq;
136694 +#endif
136695 +loop:
136696 + qm_dqrr_pvb_update(&p->p);
136697 + dq = qm_dqrr_current(&p->p);
136698 + if (!dq)
136699 + goto done;
136700 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136701 + /* If running on an LE system the fields of the
136702 + dequeue entry must be swapped. Because the
136703 + QMan HW will ignore writes the DQRR entry is
136704 + copied and the index stored within the copy */
136705 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
136706 + /* Use safe copy here to avoid WRAP transaction */
136707 + safe_copy_dqrr(shadow, dq);
136708 + orig_dq = dq;
136709 + dq = shadow;
136710 + shadow->fqid = be32_to_cpu(shadow->fqid);
136711 + shadow->contextB = be32_to_cpu(shadow->contextB);
136712 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
136713 + hw_fd_to_cpu(&shadow->fd);
136714 +#endif
136715 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
136716 + /* VDQCR: don't trust contextB as the FQ may have been
136717 + * configured for h/w consumption and we're draining it
136718 + * post-retirement. */
136719 + fq = p->vdqcr_owned;
136720 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
136721 + * to check for clearing it when doing volatile dequeues. It's
136722 + * one less thing to check in the critical path (SDQCR). */
136723 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
136724 + fq_clear(fq, QMAN_FQ_STATE_NE);
136725 + /* this is duplicated from the SDQCR code, but we have stuff to
136726 + * do before *and* after this callback, and we don't want
136727 + * multiple if()s in the critical path (SDQCR). */
136728 + res = fq->cb.dqrr(p, fq, dq);
136729 + if (res == qman_cb_dqrr_stop)
136730 + goto done;
136731 + /* Check for VDQCR completion */
136732 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
136733 + clear_vdqcr(p, fq);
136734 + } else {
136735 + /* SDQCR: contextB points to the FQ */
136736 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136737 + fq = get_fq_table_entry(dq->contextB);
136738 +#else
136739 + fq = (void *)(uintptr_t)dq->contextB;
136740 +#endif
136741 + /* Now let the callback do its stuff */
136742 + res = fq->cb.dqrr(p, fq, dq);
136743 +
136744 + /* The callback can request that we exit without consuming this
136745 + * entry nor advancing; */
136746 + if (res == qman_cb_dqrr_stop)
136747 + goto done;
136748 + }
136749 + /* Interpret 'dq' from a driver perspective. */
136750 + /* Parking isn't possible unless HELDACTIVE was set. NB,
136751 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
136752 + * check for HELDACTIVE to cover both. */
136753 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
136754 + (res != qman_cb_dqrr_park));
136755 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136756 + if (res != qman_cb_dqrr_defer)
136757 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
136758 + (res == qman_cb_dqrr_park));
136759 +#else
136760 + /* Defer just means "skip it, I'll consume it myself later on" */
136761 + if (res != qman_cb_dqrr_defer)
136762 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
136763 +#endif
136764 + /* Move forward */
136765 + qm_dqrr_next(&p->p);
136766 + /* Entry processed and consumed, increment our counter. The callback can
136767 + * request that we exit after consuming the entry, and we also exit if
136768 + * we reach our processing limit, so loop back only if neither of these
136769 + * conditions is met. */
136770 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
136771 + goto loop;
136772 +done:
136773 + return limit;
136774 +}
136775 +
136776 +u32 qman_irqsource_get(void)
136777 +{
136778 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
136779 + * should shut the user out if they are not the primary CPU hosting the
136780 + * portal. That's why we use the "raw" interface. */
136781 + struct qman_portal *p = get_raw_affine_portal();
136782 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
136783 + put_affine_portal();
136784 + return ret;
136785 +}
136786 +EXPORT_SYMBOL(qman_irqsource_get);
136787 +
136788 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
136789 +{
136790 + __maybe_unused unsigned long irqflags;
136791 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136792 + if (p->sharing_redirect)
136793 + return -EINVAL;
136794 + else
136795 +#endif
136796 + {
136797 + bits = bits & QM_PIRQ_VISIBLE;
136798 + PORTAL_IRQ_LOCK(p, irqflags);
136799 +
136800 + /* Clear any previously remaining interrupt conditions in
136801 + * QCSP_ISR. This prevents raising a false interrupt when
136802 + * interrupt conditions are enabled in QCSP_IER.
136803 + */
136804 + qm_isr_status_clear(&p->p, bits);
136805 + set_bits(bits, &p->irq_sources);
136806 + qm_isr_enable_write(&p->p, p->irq_sources);
136807 + PORTAL_IRQ_UNLOCK(p, irqflags);
136808 + }
136809 + return 0;
136810 +}
136811 +EXPORT_SYMBOL(qman_p_irqsource_add);
136812 +
136813 +int qman_irqsource_add(u32 bits __maybe_unused)
136814 +{
136815 + struct qman_portal *p = get_raw_affine_portal();
136816 + int ret;
136817 + ret = qman_p_irqsource_add(p, bits);
136818 + put_affine_portal();
136819 + return ret;
136820 +}
136821 +EXPORT_SYMBOL(qman_irqsource_add);
136822 +
136823 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
136824 +{
136825 + __maybe_unused unsigned long irqflags;
136826 + u32 ier;
136827 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136828 + if (p->sharing_redirect) {
136829 + put_affine_portal();
136830 + return -EINVAL;
136831 + }
136832 +#endif
136833 + /* Our interrupt handler only processes+clears status register bits that
136834 + * are in p->irq_sources. As we're trimming that mask, if one of them
136835 + * were to assert in the status register just before we remove it from
136836 + * the enable register, there would be an interrupt-storm when we
136837 + * release the IRQ lock. So we wait for the enable register update to
136838 + * take effect in h/w (by reading it back) and then clear all other bits
136839 + * in the status register. Ie. we clear them from ISR once it's certain
136840 + * IER won't allow them to reassert. */
136841 + PORTAL_IRQ_LOCK(p, irqflags);
136842 + bits &= QM_PIRQ_VISIBLE;
136843 + clear_bits(bits, &p->irq_sources);
136844 + qm_isr_enable_write(&p->p, p->irq_sources);
136845 +
136846 + ier = qm_isr_enable_read(&p->p);
136847 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
136848 + * data-dependency, ie. to protect against re-ordering. */
136849 + qm_isr_status_clear(&p->p, ~ier);
136850 + PORTAL_IRQ_UNLOCK(p, irqflags);
136851 + return 0;
136852 +}
136853 +EXPORT_SYMBOL(qman_p_irqsource_remove);
136854 +
136855 +int qman_irqsource_remove(u32 bits)
136856 +{
136857 + struct qman_portal *p = get_raw_affine_portal();
136858 + int ret;
136859 + ret = qman_p_irqsource_remove(p, bits);
136860 + put_affine_portal();
136861 + return ret;
136862 +}
136863 +EXPORT_SYMBOL(qman_irqsource_remove);
136864 +
136865 +const cpumask_t *qman_affine_cpus(void)
136866 +{
136867 + return &affine_mask;
136868 +}
136869 +EXPORT_SYMBOL(qman_affine_cpus);
136870 +
136871 +u16 qman_affine_channel(int cpu)
136872 +{
136873 + if (cpu < 0) {
136874 + struct qman_portal *portal = get_raw_affine_portal();
136875 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136876 + BUG_ON(portal->sharing_redirect);
136877 +#endif
136878 + cpu = portal->config->public_cfg.cpu;
136879 + put_affine_portal();
136880 + }
136881 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
136882 + return affine_channels[cpu];
136883 +}
136884 +EXPORT_SYMBOL(qman_affine_channel);
136885 +
136886 +void *qman_get_affine_portal(int cpu)
136887 +{
136888 + return affine_portals[cpu];
136889 +}
136890 +EXPORT_SYMBOL(qman_get_affine_portal);
136891 +
136892 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
136893 +{
136894 + int ret;
136895 +
136896 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136897 + if (unlikely(p->sharing_redirect))
136898 + ret = -EINVAL;
136899 + else
136900 +#endif
136901 + {
136902 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
136903 + ret = __poll_portal_fast(p, limit);
136904 + }
136905 + return ret;
136906 +}
136907 +EXPORT_SYMBOL(qman_p_poll_dqrr);
136908 +
136909 +int qman_poll_dqrr(unsigned int limit)
136910 +{
136911 + struct qman_portal *p = get_poll_portal();
136912 + int ret;
136913 + ret = qman_p_poll_dqrr(p, limit);
136914 + put_poll_portal();
136915 + return ret;
136916 +}
136917 +EXPORT_SYMBOL(qman_poll_dqrr);
136918 +
136919 +u32 qman_p_poll_slow(struct qman_portal *p)
136920 +{
136921 + u32 ret;
136922 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136923 + if (unlikely(p->sharing_redirect))
136924 + ret = (u32)-1;
136925 + else
136926 +#endif
136927 + {
136928 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
136929 + ret = __poll_portal_slow(p, is);
136930 + qm_isr_status_clear(&p->p, ret);
136931 + }
136932 + return ret;
136933 +}
136934 +EXPORT_SYMBOL(qman_p_poll_slow);
136935 +
136936 +u32 qman_poll_slow(void)
136937 +{
136938 + struct qman_portal *p = get_poll_portal();
136939 + u32 ret;
136940 + ret = qman_p_poll_slow(p);
136941 + put_poll_portal();
136942 + return ret;
136943 +}
136944 +EXPORT_SYMBOL(qman_poll_slow);
136945 +
136946 +/* Legacy wrapper */
136947 +void qman_p_poll(struct qman_portal *p)
136948 +{
136949 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136950 + if (unlikely(p->sharing_redirect))
136951 + return;
136952 +#endif
136953 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
136954 + if (!(p->slowpoll--)) {
136955 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
136956 + u32 active = __poll_portal_slow(p, is);
136957 + if (active) {
136958 + qm_isr_status_clear(&p->p, active);
136959 + p->slowpoll = SLOW_POLL_BUSY;
136960 + } else
136961 + p->slowpoll = SLOW_POLL_IDLE;
136962 + }
136963 + }
136964 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
136965 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
136966 +}
136967 +EXPORT_SYMBOL(qman_p_poll);
136968 +
136969 +void qman_poll(void)
136970 +{
136971 + struct qman_portal *p = get_poll_portal();
136972 + qman_p_poll(p);
136973 + put_poll_portal();
136974 +}
136975 +EXPORT_SYMBOL(qman_poll);
136976 +
136977 +void qman_p_stop_dequeues(struct qman_portal *p)
136978 +{
136979 + qman_stop_dequeues_ex(p);
136980 +}
136981 +EXPORT_SYMBOL(qman_p_stop_dequeues);
136982 +
136983 +void qman_stop_dequeues(void)
136984 +{
136985 + struct qman_portal *p = get_affine_portal();
136986 + qman_p_stop_dequeues(p);
136987 + put_affine_portal();
136988 +}
136989 +EXPORT_SYMBOL(qman_stop_dequeues);
136990 +
136991 +void qman_p_start_dequeues(struct qman_portal *p)
136992 +{
136993 + unsigned long irqflags __maybe_unused;
136994 + PORTAL_IRQ_LOCK(p, irqflags);
136995 + DPA_ASSERT(p->dqrr_disable_ref > 0);
136996 + if (!(--p->dqrr_disable_ref))
136997 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
136998 + PORTAL_IRQ_UNLOCK(p, irqflags);
136999 +}
137000 +EXPORT_SYMBOL(qman_p_start_dequeues);
137001 +
137002 +void qman_start_dequeues(void)
137003 +{
137004 + struct qman_portal *p = get_affine_portal();
137005 + qman_p_start_dequeues(p);
137006 + put_affine_portal();
137007 +}
137008 +EXPORT_SYMBOL(qman_start_dequeues);
137009 +
137010 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
137011 +{
137012 + unsigned long irqflags __maybe_unused;
137013 + PORTAL_IRQ_LOCK(p, irqflags);
137014 + pools &= p->config->public_cfg.pools;
137015 + p->sdqcr |= pools;
137016 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137017 + PORTAL_IRQ_UNLOCK(p, irqflags);
137018 +}
137019 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
137020 +
137021 +void qman_static_dequeue_add(u32 pools)
137022 +{
137023 + struct qman_portal *p = get_affine_portal();
137024 + qman_p_static_dequeue_add(p, pools);
137025 + put_affine_portal();
137026 +}
137027 +EXPORT_SYMBOL(qman_static_dequeue_add);
137028 +
137029 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
137030 +{
137031 + unsigned long irqflags __maybe_unused;
137032 + PORTAL_IRQ_LOCK(p, irqflags);
137033 + pools &= p->config->public_cfg.pools;
137034 + p->sdqcr &= ~pools;
137035 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137036 + PORTAL_IRQ_UNLOCK(p, irqflags);
137037 +}
137038 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
137039 +
137040 +void qman_static_dequeue_del(u32 pools)
137041 +{
137042 + struct qman_portal *p = get_affine_portal();
137043 + qman_p_static_dequeue_del(p, pools);
137044 + put_affine_portal();
137045 +}
137046 +EXPORT_SYMBOL(qman_static_dequeue_del);
137047 +
137048 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
137049 +{
137050 + return p->sdqcr;
137051 +}
137052 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
137053 +
137054 +u32 qman_static_dequeue_get(void)
137055 +{
137056 + struct qman_portal *p = get_affine_portal();
137057 + u32 ret = qman_p_static_dequeue_get(p);
137058 + put_affine_portal();
137059 + return ret;
137060 +}
137061 +EXPORT_SYMBOL(qman_static_dequeue_get);
137062 +
137063 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
137064 + int park_request)
137065 +{
137066 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
137067 +}
137068 +EXPORT_SYMBOL(qman_p_dca);
137069 +
137070 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
137071 +{
137072 + struct qman_portal *p = get_affine_portal();
137073 + qman_p_dca(p, dq, park_request);
137074 + put_affine_portal();
137075 +}
137076 +EXPORT_SYMBOL(qman_dca);
137077 +
137078 +/*******************/
137079 +/* Frame queue API */
137080 +/*******************/
137081 +
137082 +static const char *mcr_result_str(u8 result)
137083 +{
137084 + switch (result) {
137085 + case QM_MCR_RESULT_NULL:
137086 + return "QM_MCR_RESULT_NULL";
137087 + case QM_MCR_RESULT_OK:
137088 + return "QM_MCR_RESULT_OK";
137089 + case QM_MCR_RESULT_ERR_FQID:
137090 + return "QM_MCR_RESULT_ERR_FQID";
137091 + case QM_MCR_RESULT_ERR_FQSTATE:
137092 + return "QM_MCR_RESULT_ERR_FQSTATE";
137093 + case QM_MCR_RESULT_ERR_NOTEMPTY:
137094 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
137095 + case QM_MCR_RESULT_PENDING:
137096 + return "QM_MCR_RESULT_PENDING";
137097 + case QM_MCR_RESULT_ERR_BADCOMMAND:
137098 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
137099 + }
137100 + return "<unknown MCR result>";
137101 +}
137102 +
137103 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
137104 +{
137105 + struct qm_fqd fqd;
137106 + struct qm_mcr_queryfq_np np;
137107 + struct qm_mc_command *mcc;
137108 + struct qm_mc_result *mcr;
137109 + struct qman_portal *p;
137110 + unsigned long irqflags __maybe_unused;
137111 +
137112 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
137113 + int ret = qman_alloc_fqid(&fqid);
137114 + if (ret)
137115 + return ret;
137116 + }
137117 + spin_lock_init(&fq->fqlock);
137118 + fq->fqid = fqid;
137119 + fq->flags = flags;
137120 + fq->state = qman_fq_state_oos;
137121 + fq->cgr_groupid = 0;
137122 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137123 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
137124 + return -ENOMEM;
137125 +#endif
137126 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
137127 + return 0;
137128 + /* Everything else is AS_IS support */
137129 + p = get_affine_portal();
137130 + PORTAL_IRQ_LOCK(p, irqflags);
137131 + mcc = qm_mc_start(&p->p);
137132 + mcc->queryfq.fqid = cpu_to_be32(fqid);
137133 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137134 + while (!(mcr = qm_mc_result(&p->p)))
137135 + cpu_relax();
137136 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
137137 + if (mcr->result != QM_MCR_RESULT_OK) {
137138 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
137139 + goto err;
137140 + }
137141 + fqd = mcr->queryfq.fqd;
137142 + hw_fqd_to_cpu(&fqd);
137143 + mcc = qm_mc_start(&p->p);
137144 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
137145 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137146 + while (!(mcr = qm_mc_result(&p->p)))
137147 + cpu_relax();
137148 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
137149 + if (mcr->result != QM_MCR_RESULT_OK) {
137150 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
137151 + goto err;
137152 + }
137153 + np = mcr->queryfq_np;
137154 + /* Phew, have queryfq and queryfq_np results, stitch together
137155 + * the FQ object from those. */
137156 + fq->cgr_groupid = fqd.cgid;
137157 + switch (np.state & QM_MCR_NP_STATE_MASK) {
137158 + case QM_MCR_NP_STATE_OOS:
137159 + break;
137160 + case QM_MCR_NP_STATE_RETIRED:
137161 + fq->state = qman_fq_state_retired;
137162 + if (np.frm_cnt)
137163 + fq_set(fq, QMAN_FQ_STATE_NE);
137164 + break;
137165 + case QM_MCR_NP_STATE_TEN_SCHED:
137166 + case QM_MCR_NP_STATE_TRU_SCHED:
137167 + case QM_MCR_NP_STATE_ACTIVE:
137168 + fq->state = qman_fq_state_sched;
137169 + if (np.state & QM_MCR_NP_STATE_R)
137170 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137171 + break;
137172 + case QM_MCR_NP_STATE_PARKED:
137173 + fq->state = qman_fq_state_parked;
137174 + break;
137175 + default:
137176 + DPA_ASSERT(NULL == "invalid FQ state");
137177 + }
137178 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
137179 + fq->state |= QMAN_FQ_STATE_CGR_EN;
137180 + PORTAL_IRQ_UNLOCK(p, irqflags);
137181 + put_affine_portal();
137182 + return 0;
137183 +err:
137184 + PORTAL_IRQ_UNLOCK(p, irqflags);
137185 + put_affine_portal();
137186 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
137187 + qman_release_fqid(fqid);
137188 + return -EIO;
137189 +}
137190 +EXPORT_SYMBOL(qman_create_fq);
137191 +
137192 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
137193 +{
137194 +
137195 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
137196 + * quiesced. Instead, run some checks. */
137197 + switch (fq->state) {
137198 + case qman_fq_state_parked:
137199 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
137200 + case qman_fq_state_oos:
137201 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
137202 + qman_release_fqid(fq->fqid);
137203 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137204 + clear_fq_table_entry(fq->key);
137205 +#endif
137206 + return;
137207 + default:
137208 + break;
137209 + }
137210 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
137211 +}
137212 +EXPORT_SYMBOL(qman_destroy_fq);
137213 +
137214 +u32 qman_fq_fqid(struct qman_fq *fq)
137215 +{
137216 + return fq->fqid;
137217 +}
137218 +EXPORT_SYMBOL(qman_fq_fqid);
137219 +
137220 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
137221 +{
137222 + if (state)
137223 + *state = fq->state;
137224 + if (flags)
137225 + *flags = fq->flags;
137226 +}
137227 +EXPORT_SYMBOL(qman_fq_state);
137228 +
137229 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
137230 +{
137231 + struct qm_mc_command *mcc;
137232 + struct qm_mc_result *mcr;
137233 + struct qman_portal *p;
137234 + unsigned long irqflags __maybe_unused;
137235 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137236 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
137237 +
137238 + if ((fq->state != qman_fq_state_oos) &&
137239 + (fq->state != qman_fq_state_parked))
137240 + return -EINVAL;
137241 +#ifdef CONFIG_FSL_DPA_CHECKING
137242 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137243 + return -EINVAL;
137244 +#endif
137245 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
137246 + /* And can't be set at the same time as TDTHRESH */
137247 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
137248 + return -EINVAL;
137249 + }
137250 + /* Issue an INITFQ_[PARKED|SCHED] management command */
137251 + p = get_affine_portal();
137252 + PORTAL_IRQ_LOCK(p, irqflags);
137253 + FQLOCK(fq);
137254 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137255 + ((fq->state != qman_fq_state_oos) &&
137256 + (fq->state != qman_fq_state_parked)))) {
137257 + FQUNLOCK(fq);
137258 + PORTAL_IRQ_UNLOCK(p, irqflags);
137259 + put_affine_portal();
137260 + return -EBUSY;
137261 + }
137262 + mcc = qm_mc_start(&p->p);
137263 + if (opts)
137264 + mcc->initfq = *opts;
137265 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
137266 + mcc->initfq.count = 0;
137267 +
137268 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
137269 + * demux pointer. Otherwise, the caller-provided value is allowed to
137270 + * stand, don't overwrite it. */
137271 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
137272 + dma_addr_t phys_fq;
137273 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
137274 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137275 + mcc->initfq.fqd.context_b = fq->key;
137276 +#else
137277 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
137278 +#endif
137279 + /* and the physical address - NB, if the user wasn't trying to
137280 + * set CONTEXTA, clear the stashing settings. */
137281 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
137282 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
137283 + memset(&mcc->initfq.fqd.context_a, 0,
137284 + sizeof(mcc->initfq.fqd.context_a));
137285 + } else {
137286 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
137287 + DMA_TO_DEVICE);
137288 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
137289 + }
137290 + }
137291 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
137292 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
137293 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
137294 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
137295 + mcc->initfq.fqd.dest.wq = 4;
137296 + }
137297 + }
137298 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
137299 + cpu_to_hw_fqd(&mcc->initfq.fqd);
137300 + qm_mc_commit(&p->p, myverb);
137301 + while (!(mcr = qm_mc_result(&p->p)))
137302 + cpu_relax();
137303 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137304 + res = mcr->result;
137305 + if (res != QM_MCR_RESULT_OK) {
137306 + FQUNLOCK(fq);
137307 + PORTAL_IRQ_UNLOCK(p, irqflags);
137308 + put_affine_portal();
137309 + return -EIO;
137310 + }
137311 + if (opts) {
137312 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
137313 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
137314 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
137315 + else
137316 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
137317 + }
137318 + if (opts->we_mask & QM_INITFQ_WE_CGID)
137319 + fq->cgr_groupid = opts->fqd.cgid;
137320 + }
137321 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137322 + qman_fq_state_sched : qman_fq_state_parked;
137323 + FQUNLOCK(fq);
137324 + PORTAL_IRQ_UNLOCK(p, irqflags);
137325 + put_affine_portal();
137326 + return 0;
137327 +}
137328 +EXPORT_SYMBOL(qman_init_fq);
137329 +
137330 +int qman_schedule_fq(struct qman_fq *fq)
137331 +{
137332 + struct qm_mc_command *mcc;
137333 + struct qm_mc_result *mcr;
137334 + struct qman_portal *p;
137335 + unsigned long irqflags __maybe_unused;
137336 + int ret = 0;
137337 + u8 res;
137338 +
137339 + if (fq->state != qman_fq_state_parked)
137340 + return -EINVAL;
137341 +#ifdef CONFIG_FSL_DPA_CHECKING
137342 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137343 + return -EINVAL;
137344 +#endif
137345 + /* Issue a ALTERFQ_SCHED management command */
137346 + p = get_affine_portal();
137347 + PORTAL_IRQ_LOCK(p, irqflags);
137348 + FQLOCK(fq);
137349 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137350 + (fq->state != qman_fq_state_parked))) {
137351 + ret = -EBUSY;
137352 + goto out;
137353 + }
137354 + mcc = qm_mc_start(&p->p);
137355 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137356 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
137357 + while (!(mcr = qm_mc_result(&p->p)))
137358 + cpu_relax();
137359 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
137360 + res = mcr->result;
137361 + if (res != QM_MCR_RESULT_OK) {
137362 + ret = -EIO;
137363 + goto out;
137364 + }
137365 + fq->state = qman_fq_state_sched;
137366 +out:
137367 + FQUNLOCK(fq);
137368 + PORTAL_IRQ_UNLOCK(p, irqflags);
137369 + put_affine_portal();
137370 + return ret;
137371 +}
137372 +EXPORT_SYMBOL(qman_schedule_fq);
137373 +
137374 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
137375 +{
137376 + struct qm_mc_command *mcc;
137377 + struct qm_mc_result *mcr;
137378 + struct qman_portal *p;
137379 + unsigned long irqflags __maybe_unused;
137380 + int rval;
137381 + u8 res;
137382 +
137383 + if ((fq->state != qman_fq_state_parked) &&
137384 + (fq->state != qman_fq_state_sched))
137385 + return -EINVAL;
137386 +#ifdef CONFIG_FSL_DPA_CHECKING
137387 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137388 + return -EINVAL;
137389 +#endif
137390 + p = get_affine_portal();
137391 + PORTAL_IRQ_LOCK(p, irqflags);
137392 + FQLOCK(fq);
137393 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137394 + (fq->state == qman_fq_state_retired) ||
137395 + (fq->state == qman_fq_state_oos))) {
137396 + rval = -EBUSY;
137397 + goto out;
137398 + }
137399 + rval = table_push_fq(p, fq);
137400 + if (rval)
137401 + goto out;
137402 + mcc = qm_mc_start(&p->p);
137403 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137404 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
137405 + while (!(mcr = qm_mc_result(&p->p)))
137406 + cpu_relax();
137407 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
137408 + res = mcr->result;
137409 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
137410 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
137411 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
137412 + * friendly, otherwise the caller doesn't necessarily have a fully
137413 + * "retired" FQ on return even if the retirement was immediate. However
137414 + * this does mean some code duplication between here and
137415 + * fq_state_change(). */
137416 + if (likely(res == QM_MCR_RESULT_OK)) {
137417 + rval = 0;
137418 + /* Process 'fq' right away, we'll ignore FQRNI */
137419 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
137420 + fq_set(fq, QMAN_FQ_STATE_NE);
137421 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
137422 + fq_set(fq, QMAN_FQ_STATE_ORL);
137423 + else
137424 + table_del_fq(p, fq);
137425 + if (flags)
137426 + *flags = fq->flags;
137427 + fq->state = qman_fq_state_retired;
137428 + if (fq->cb.fqs) {
137429 + /* Another issue with supporting "immediate" retirement
137430 + * is that we're forced to drop FQRNIs, because by the
137431 + * time they're seen it may already be "too late" (the
137432 + * fq may have been OOS'd and free()'d already). But if
137433 + * the upper layer wants a callback whether it's
137434 + * immediate or not, we have to fake a "MR" entry to
137435 + * look like an FQRNI... */
137436 + struct qm_mr_entry msg;
137437 + msg.verb = QM_MR_VERB_FQRNI;
137438 + msg.fq.fqs = mcr->alterfq.fqs;
137439 + msg.fq.fqid = fq->fqid;
137440 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137441 + msg.fq.contextB = fq->key;
137442 +#else
137443 + msg.fq.contextB = (u32)(uintptr_t)fq;
137444 +#endif
137445 + fq->cb.fqs(p, fq, &msg);
137446 + }
137447 + } else if (res == QM_MCR_RESULT_PENDING) {
137448 + rval = 1;
137449 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137450 + } else {
137451 + rval = -EIO;
137452 + table_del_fq(p, fq);
137453 + }
137454 +out:
137455 + FQUNLOCK(fq);
137456 + PORTAL_IRQ_UNLOCK(p, irqflags);
137457 + put_affine_portal();
137458 + return rval;
137459 +}
137460 +EXPORT_SYMBOL(qman_retire_fq);
137461 +
137462 +int qman_oos_fq(struct qman_fq *fq)
137463 +{
137464 + struct qm_mc_command *mcc;
137465 + struct qm_mc_result *mcr;
137466 + struct qman_portal *p;
137467 + unsigned long irqflags __maybe_unused;
137468 + int ret = 0;
137469 + u8 res;
137470 +
137471 + if (fq->state != qman_fq_state_retired)
137472 + return -EINVAL;
137473 +#ifdef CONFIG_FSL_DPA_CHECKING
137474 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137475 + return -EINVAL;
137476 +#endif
137477 + p = get_affine_portal();
137478 + PORTAL_IRQ_LOCK(p, irqflags);
137479 + FQLOCK(fq);
137480 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
137481 + (fq->state != qman_fq_state_retired))) {
137482 + ret = -EBUSY;
137483 + goto out;
137484 + }
137485 + mcc = qm_mc_start(&p->p);
137486 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137487 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
137488 + while (!(mcr = qm_mc_result(&p->p)))
137489 + cpu_relax();
137490 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
137491 + res = mcr->result;
137492 + if (res != QM_MCR_RESULT_OK) {
137493 + ret = -EIO;
137494 + goto out;
137495 + }
137496 + fq->state = qman_fq_state_oos;
137497 +out:
137498 + FQUNLOCK(fq);
137499 + PORTAL_IRQ_UNLOCK(p, irqflags);
137500 + put_affine_portal();
137501 + return ret;
137502 +}
137503 +EXPORT_SYMBOL(qman_oos_fq);
137504 +
137505 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
137506 +{
137507 + struct qm_mc_command *mcc;
137508 + struct qm_mc_result *mcr;
137509 + struct qman_portal *p;
137510 + unsigned long irqflags __maybe_unused;
137511 + int ret = 0;
137512 + u8 res;
137513 + u8 myverb;
137514 +
137515 + if ((fq->state == qman_fq_state_oos) ||
137516 + (fq->state == qman_fq_state_retired) ||
137517 + (fq->state == qman_fq_state_parked))
137518 + return -EINVAL;
137519 +
137520 +#ifdef CONFIG_FSL_DPA_CHECKING
137521 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137522 + return -EINVAL;
137523 +#endif
137524 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
137525 + p = get_affine_portal();
137526 + PORTAL_IRQ_LOCK(p, irqflags);
137527 + FQLOCK(fq);
137528 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137529 + (fq->state == qman_fq_state_parked) ||
137530 + (fq->state == qman_fq_state_oos) ||
137531 + (fq->state == qman_fq_state_retired))) {
137532 + ret = -EBUSY;
137533 + goto out;
137534 + }
137535 + mcc = qm_mc_start(&p->p);
137536 + mcc->alterfq.fqid = fq->fqid;
137537 + mcc->alterfq.count = 0;
137538 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
137539 +
137540 + qm_mc_commit(&p->p, myverb);
137541 + while (!(mcr = qm_mc_result(&p->p)))
137542 + cpu_relax();
137543 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137544 +
137545 + res = mcr->result;
137546 + if (res != QM_MCR_RESULT_OK) {
137547 + ret = -EIO;
137548 + goto out;
137549 + }
137550 +out:
137551 + FQUNLOCK(fq);
137552 + PORTAL_IRQ_UNLOCK(p, irqflags);
137553 + put_affine_portal();
137554 + return ret;
137555 +}
137556 +EXPORT_SYMBOL(qman_fq_flow_control);
137557 +
137558 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
137559 +{
137560 + struct qm_mc_command *mcc;
137561 + struct qm_mc_result *mcr;
137562 + struct qman_portal *p = get_affine_portal();
137563 + unsigned long irqflags __maybe_unused;
137564 + u8 res;
137565 +
137566 + PORTAL_IRQ_LOCK(p, irqflags);
137567 + mcc = qm_mc_start(&p->p);
137568 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
137569 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137570 + while (!(mcr = qm_mc_result(&p->p)))
137571 + cpu_relax();
137572 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
137573 + res = mcr->result;
137574 + if (res == QM_MCR_RESULT_OK)
137575 + *fqd = mcr->queryfq.fqd;
137576 + hw_fqd_to_cpu(fqd);
137577 + PORTAL_IRQ_UNLOCK(p, irqflags);
137578 + put_affine_portal();
137579 + if (res != QM_MCR_RESULT_OK)
137580 + return -EIO;
137581 + return 0;
137582 +}
137583 +EXPORT_SYMBOL(qman_query_fq);
137584 +
137585 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
137586 +{
137587 + struct qm_mc_command *mcc;
137588 + struct qm_mc_result *mcr;
137589 + struct qman_portal *p = get_affine_portal();
137590 + unsigned long irqflags __maybe_unused;
137591 + u8 res;
137592 +
137593 + PORTAL_IRQ_LOCK(p, irqflags);
137594 + mcc = qm_mc_start(&p->p);
137595 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
137596 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137597 + while (!(mcr = qm_mc_result(&p->p)))
137598 + cpu_relax();
137599 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
137600 + res = mcr->result;
137601 + if (res == QM_MCR_RESULT_OK) {
137602 + *np = mcr->queryfq_np;
137603 + np->fqd_link = be24_to_cpu(np->fqd_link);
137604 + np->odp_seq = be16_to_cpu(np->odp_seq);
137605 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
137606 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
137607 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
137608 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
137609 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
137610 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
137611 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
137612 + np->ics_surp = be16_to_cpu(np->ics_surp);
137613 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
137614 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
137615 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
137616 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
137617 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
137618 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
137619 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
137620 + }
137621 + PORTAL_IRQ_UNLOCK(p, irqflags);
137622 + put_affine_portal();
137623 + if (res == QM_MCR_RESULT_ERR_FQID)
137624 + return -ERANGE;
137625 + else if (res != QM_MCR_RESULT_OK)
137626 + return -EIO;
137627 + return 0;
137628 +}
137629 +EXPORT_SYMBOL(qman_query_fq_np);
137630 +
137631 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
137632 +{
137633 + struct qm_mc_command *mcc;
137634 + struct qm_mc_result *mcr;
137635 + struct qman_portal *p = get_affine_portal();
137636 + unsigned long irqflags __maybe_unused;
137637 + u8 res, myverb;
137638 +
137639 + PORTAL_IRQ_LOCK(p, irqflags);
137640 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
137641 + QM_MCR_VERB_QUERYWQ;
137642 + mcc = qm_mc_start(&p->p);
137643 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
137644 + qm_mc_commit(&p->p, myverb);
137645 + while (!(mcr = qm_mc_result(&p->p)))
137646 + cpu_relax();
137647 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137648 + res = mcr->result;
137649 + if (res == QM_MCR_RESULT_OK) {
137650 + int i, array_len;
137651 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
137652 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
137653 + for (i = 0; i < array_len; i++)
137654 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
137655 + }
137656 + PORTAL_IRQ_UNLOCK(p, irqflags);
137657 + put_affine_portal();
137658 + if (res != QM_MCR_RESULT_OK) {
137659 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
137660 + return -EIO;
137661 + }
137662 + return 0;
137663 +}
137664 +EXPORT_SYMBOL(qman_query_wq);
137665 +
137666 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
137667 + struct qm_mcr_cgrtestwrite *result)
137668 +{
137669 + struct qm_mc_command *mcc;
137670 + struct qm_mc_result *mcr;
137671 + struct qman_portal *p = get_affine_portal();
137672 + unsigned long irqflags __maybe_unused;
137673 + u8 res;
137674 +
137675 + PORTAL_IRQ_LOCK(p, irqflags);
137676 + mcc = qm_mc_start(&p->p);
137677 + mcc->cgrtestwrite.cgid = cgr->cgrid;
137678 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
137679 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
137680 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
137681 + while (!(mcr = qm_mc_result(&p->p)))
137682 + cpu_relax();
137683 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
137684 + res = mcr->result;
137685 + if (res == QM_MCR_RESULT_OK)
137686 + *result = mcr->cgrtestwrite;
137687 + PORTAL_IRQ_UNLOCK(p, irqflags);
137688 + put_affine_portal();
137689 + if (res != QM_MCR_RESULT_OK) {
137690 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
137691 + return -EIO;
137692 + }
137693 + return 0;
137694 +}
137695 +EXPORT_SYMBOL(qman_testwrite_cgr);
137696 +
137697 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
137698 +{
137699 + struct qm_mc_command *mcc;
137700 + struct qm_mc_result *mcr;
137701 + struct qman_portal *p = get_affine_portal();
137702 + unsigned long irqflags __maybe_unused;
137703 + u8 res;
137704 + int i;
137705 +
137706 + PORTAL_IRQ_LOCK(p, irqflags);
137707 + mcc = qm_mc_start(&p->p);
137708 + mcc->querycgr.cgid = cgr->cgrid;
137709 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
137710 + while (!(mcr = qm_mc_result(&p->p)))
137711 + cpu_relax();
137712 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
137713 + res = mcr->result;
137714 + if (res == QM_MCR_RESULT_OK)
137715 + *cgrd = mcr->querycgr;
137716 + PORTAL_IRQ_UNLOCK(p, irqflags);
137717 + put_affine_portal();
137718 + if (res != QM_MCR_RESULT_OK) {
137719 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
137720 + return -EIO;
137721 + }
137722 + cgrd->cgr.wr_parm_g.word =
137723 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
137724 + cgrd->cgr.wr_parm_y.word =
137725 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
137726 + cgrd->cgr.wr_parm_r.word =
137727 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
137728 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
137729 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
137730 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
137731 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
137732 + return 0;
137733 +}
137734 +EXPORT_SYMBOL(qman_query_cgr);
137735 +
137736 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
137737 +{
137738 + struct qm_mc_result *mcr;
137739 + struct qman_portal *p = get_affine_portal();
137740 + unsigned long irqflags __maybe_unused;
137741 + u8 res;
137742 + int i;
137743 +
137744 + PORTAL_IRQ_LOCK(p, irqflags);
137745 + qm_mc_start(&p->p);
137746 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
137747 + while (!(mcr = qm_mc_result(&p->p)))
137748 + cpu_relax();
137749 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
137750 + QM_MCC_VERB_QUERYCONGESTION);
137751 + res = mcr->result;
137752 + if (res == QM_MCR_RESULT_OK)
137753 + memcpy_fromio(congestion, &mcr->querycongestion,
137754 + sizeof(*congestion));
137755 + PORTAL_IRQ_UNLOCK(p, irqflags);
137756 + put_affine_portal();
137757 + if (res != QM_MCR_RESULT_OK) {
137758 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
137759 + return -EIO;
137760 + }
137761 +
137762 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
137763 + be32_to_cpus(&congestion->state.__state[i]);
137764 + return 0;
137765 +}
137766 +EXPORT_SYMBOL(qman_query_congestion);
137767 +
137768 +/* internal function used as a wait_event() expression */
137769 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
137770 +{
137771 + unsigned long irqflags __maybe_unused;
137772 + int ret = -EBUSY;
137773 + PORTAL_IRQ_LOCK(p, irqflags);
137774 + if (!p->vdqcr_owned) {
137775 + FQLOCK(fq);
137776 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
137777 + goto escape;
137778 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
137779 + FQUNLOCK(fq);
137780 + p->vdqcr_owned = fq;
137781 + ret = 0;
137782 + }
137783 +escape:
137784 + PORTAL_IRQ_UNLOCK(p, irqflags);
137785 + if (!ret)
137786 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
137787 + return ret;
137788 +}
137789 +
137790 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
137791 +{
137792 + int ret;
137793 + *p = get_affine_portal();
137794 + ret = set_p_vdqcr(*p, fq, vdqcr);
137795 + put_affine_portal();
137796 + return ret;
137797 +}
137798 +
137799 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
137800 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
137801 + u32 vdqcr, u32 flags)
137802 +{
137803 + int ret = 0;
137804 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
137805 + ret = wait_event_interruptible(affine_queue,
137806 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
137807 + else
137808 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
137809 + return ret;
137810 +}
137811 +
137812 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
137813 + u32 vdqcr, u32 flags)
137814 +{
137815 + int ret = 0;
137816 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
137817 + ret = wait_event_interruptible(affine_queue,
137818 + !(ret = set_vdqcr(p, fq, vdqcr)));
137819 + else
137820 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
137821 + return ret;
137822 +}
137823 +#endif
137824 +
137825 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
137826 + u32 flags __maybe_unused, u32 vdqcr)
137827 +{
137828 + int ret;
137829 +
137830 + if ((fq->state != qman_fq_state_parked) &&
137831 + (fq->state != qman_fq_state_retired))
137832 + return -EINVAL;
137833 + if (vdqcr & QM_VDQCR_FQID_MASK)
137834 + return -EINVAL;
137835 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
137836 + return -EBUSY;
137837 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
137838 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
137839 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
137840 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
137841 + else
137842 +#endif
137843 + ret = set_p_vdqcr(p, fq, vdqcr);
137844 + if (ret)
137845 + return ret;
137846 + /* VDQCR is set */
137847 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
137848 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
137849 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
137850 + /* NB: don't propagate any error - the caller wouldn't
137851 + * know whether the VDQCR was issued or not. A signal
137852 + * could arrive after returning anyway, so the caller
137853 + * can check signal_pending() if that's an issue. */
137854 + wait_event_interruptible(affine_queue,
137855 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
137856 + else
137857 + wait_event(affine_queue,
137858 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
137859 + }
137860 +#endif
137861 + return 0;
137862 +}
137863 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
137864 +
137865 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
137866 + u32 vdqcr)
137867 +{
137868 + struct qman_portal *p;
137869 + int ret;
137870 +
137871 + if ((fq->state != qman_fq_state_parked) &&
137872 + (fq->state != qman_fq_state_retired))
137873 + return -EINVAL;
137874 + if (vdqcr & QM_VDQCR_FQID_MASK)
137875 + return -EINVAL;
137876 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
137877 + return -EBUSY;
137878 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
137879 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
137880 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
137881 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
137882 + else
137883 +#endif
137884 + ret = set_vdqcr(&p, fq, vdqcr);
137885 + if (ret)
137886 + return ret;
137887 + /* VDQCR is set */
137888 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
137889 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
137890 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
137891 + /* NB: don't propagate any error - the caller wouldn't
137892 + * know whether the VDQCR was issued or not. A signal
137893 + * could arrive after returning anyway, so the caller
137894 + * can check signal_pending() if that's an issue. */
137895 + wait_event_interruptible(affine_queue,
137896 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
137897 + else
137898 + wait_event(affine_queue,
137899 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
137900 + }
137901 +#endif
137902 + return 0;
137903 +}
137904 +EXPORT_SYMBOL(qman_volatile_dequeue);
137905 +
137906 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
137907 +{
137908 + if (avail)
137909 + qm_eqcr_cce_prefetch(&p->p);
137910 + else
137911 + qm_eqcr_cce_update(&p->p);
137912 +}
137913 +
137914 +int qman_eqcr_is_empty(void)
137915 +{
137916 + unsigned long irqflags __maybe_unused;
137917 + struct qman_portal *p = get_affine_portal();
137918 + u8 avail;
137919 +
137920 + PORTAL_IRQ_LOCK(p, irqflags);
137921 + update_eqcr_ci(p, 0);
137922 + avail = qm_eqcr_get_fill(&p->p);
137923 + PORTAL_IRQ_UNLOCK(p, irqflags);
137924 + put_affine_portal();
137925 + return avail == 0;
137926 +}
137927 +EXPORT_SYMBOL(qman_eqcr_is_empty);
137928 +
137929 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
137930 +{
137931 + if (affine) {
137932 + unsigned long irqflags __maybe_unused;
137933 + struct qman_portal *p = get_affine_portal();
137934 + PORTAL_IRQ_LOCK(p, irqflags);
137935 + p->cb_dc_ern = handler;
137936 + PORTAL_IRQ_UNLOCK(p, irqflags);
137937 + put_affine_portal();
137938 + } else
137939 + cb_dc_ern = handler;
137940 +}
137941 +EXPORT_SYMBOL(qman_set_dc_ern);
137942 +
137943 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
137944 + unsigned long *irqflags __maybe_unused,
137945 + struct qman_fq *fq,
137946 + const struct qm_fd *fd,
137947 + u32 flags)
137948 +{
137949 + struct qm_eqcr_entry *eq;
137950 + u8 avail;
137951 + PORTAL_IRQ_LOCK(p, (*irqflags));
137952 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137953 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
137954 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
137955 + if (p->eqci_owned) {
137956 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
137957 + return NULL;
137958 + }
137959 + p->eqci_owned = fq;
137960 + }
137961 +#endif
137962 + if (p->use_eqcr_ci_stashing) {
137963 + /*
137964 + * The stashing case is easy, only update if we need to in
137965 + * order to try and liberate ring entries.
137966 + */
137967 + eq = qm_eqcr_start_stash(&p->p);
137968 + } else {
137969 + /*
137970 + * The non-stashing case is harder, need to prefetch ahead of
137971 + * time.
137972 + */
137973 + avail = qm_eqcr_get_avail(&p->p);
137974 + if (avail < 2)
137975 + update_eqcr_ci(p, avail);
137976 + eq = qm_eqcr_start_no_stash(&p->p);
137977 + }
137978 +
137979 + if (unlikely(!eq)) {
137980 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137981 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
137982 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
137983 + p->eqci_owned = NULL;
137984 +#endif
137985 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
137986 + return NULL;
137987 + }
137988 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
137989 + eq->dca = QM_EQCR_DCA_ENABLE |
137990 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
137991 + QM_EQCR_DCA_PARK : 0) |
137992 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
137993 + eq->fqid = cpu_to_be32(fq->fqid);
137994 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137995 + eq->tag = cpu_to_be32(fq->key);
137996 +#else
137997 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
137998 +#endif
137999 + eq->fd = *fd;
138000 + cpu_to_hw_fd(&eq->fd);
138001 + return eq;
138002 +}
138003 +
138004 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
138005 + unsigned long *irqflags __maybe_unused,
138006 + struct qman_fq *fq,
138007 + const struct qm_fd *fd,
138008 + u32 flags)
138009 +{
138010 + struct qm_eqcr_entry *eq;
138011 + *p = get_affine_portal();
138012 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
138013 + if (!eq)
138014 + put_affine_portal();
138015 + return eq;
138016 +}
138017 +
138018 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138019 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
138020 + unsigned long *irqflags __maybe_unused,
138021 + struct qman_fq *fq,
138022 + const struct qm_fd *fd,
138023 + u32 flags)
138024 +{
138025 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
138026 + if (!eq)
138027 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
138028 + return eq;
138029 +}
138030 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
138031 + unsigned long *irqflags __maybe_unused,
138032 + struct qman_fq *fq,
138033 + const struct qm_fd *fd,
138034 + u32 flags)
138035 +{
138036 + struct qm_eqcr_entry *eq;
138037 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138038 + /* NB: return NULL if signal occurs before completion. Signal
138039 + * can occur during return. Caller must check for signal */
138040 + wait_event_interruptible(affine_queue,
138041 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138042 + else
138043 + wait_event(affine_queue,
138044 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138045 + return eq;
138046 +}
138047 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
138048 + unsigned long *irqflags __maybe_unused,
138049 + struct qman_fq *fq,
138050 + const struct qm_fd *fd,
138051 + u32 flags)
138052 +{
138053 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
138054 + if (!eq)
138055 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
138056 + return eq;
138057 +}
138058 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
138059 + unsigned long *irqflags __maybe_unused,
138060 + struct qman_fq *fq,
138061 + const struct qm_fd *fd,
138062 + u32 flags)
138063 +{
138064 + struct qm_eqcr_entry *eq;
138065 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138066 + /* NB: return NULL if signal occurs before completion. Signal
138067 + * can occur during return. Caller must check for signal */
138068 + wait_event_interruptible(affine_queue,
138069 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138070 + else
138071 + wait_event(affine_queue,
138072 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138073 + return eq;
138074 +}
138075 +#endif
138076 +
138077 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
138078 + const struct qm_fd *fd, u32 flags)
138079 +{
138080 + struct qm_eqcr_entry *eq;
138081 + unsigned long irqflags __maybe_unused;
138082 +
138083 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138084 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138085 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138086 + else
138087 +#endif
138088 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138089 + if (!eq)
138090 + return -EBUSY;
138091 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138092 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138093 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138094 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138095 + PORTAL_IRQ_UNLOCK(p, irqflags);
138096 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138097 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138098 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138099 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138100 + /* NB: return success even if signal occurs before
138101 + * condition is true. pvb_commit guarantees success */
138102 + wait_event_interruptible(affine_queue,
138103 + (p->eqci_owned != fq));
138104 + else
138105 + wait_event(affine_queue, (p->eqci_owned != fq));
138106 + }
138107 +#endif
138108 + return 0;
138109 +}
138110 +EXPORT_SYMBOL(qman_p_enqueue);
138111 +
138112 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
138113 +{
138114 + struct qman_portal *p;
138115 + struct qm_eqcr_entry *eq;
138116 + unsigned long irqflags __maybe_unused;
138117 +
138118 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138119 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138120 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138121 + else
138122 +#endif
138123 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138124 + if (!eq)
138125 + return -EBUSY;
138126 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138127 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138128 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138129 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138130 + PORTAL_IRQ_UNLOCK(p, irqflags);
138131 + put_affine_portal();
138132 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138133 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138134 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138135 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138136 + /* NB: return success even if signal occurs before
138137 + * condition is true. pvb_commit guarantees success */
138138 + wait_event_interruptible(affine_queue,
138139 + (p->eqci_owned != fq));
138140 + else
138141 + wait_event(affine_queue, (p->eqci_owned != fq));
138142 + }
138143 +#endif
138144 + return 0;
138145 +}
138146 +EXPORT_SYMBOL(qman_enqueue);
138147 +
138148 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
138149 + const struct qm_fd *fd, u32 flags,
138150 + struct qman_fq *orp, u16 orp_seqnum)
138151 +{
138152 + struct qm_eqcr_entry *eq;
138153 + unsigned long irqflags __maybe_unused;
138154 +
138155 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138156 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138157 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138158 + else
138159 +#endif
138160 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138161 + if (!eq)
138162 + return -EBUSY;
138163 + /* Process ORP-specifics here */
138164 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138165 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138166 + else {
138167 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138168 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138169 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138170 + else
138171 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138172 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138173 + }
138174 + eq->seqnum = cpu_to_be16(orp_seqnum);
138175 + eq->orp = cpu_to_be32(orp->fqid);
138176 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138177 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138178 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138179 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138180 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138181 + PORTAL_IRQ_UNLOCK(p, irqflags);
138182 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138183 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138184 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138185 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138186 + /* NB: return success even if signal occurs before
138187 + * condition is true. pvb_commit guarantees success */
138188 + wait_event_interruptible(affine_queue,
138189 + (p->eqci_owned != fq));
138190 + else
138191 + wait_event(affine_queue, (p->eqci_owned != fq));
138192 + }
138193 +#endif
138194 + return 0;
138195 +}
138196 +EXPORT_SYMBOL(qman_p_enqueue_orp);
138197 +
138198 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
138199 + struct qman_fq *orp, u16 orp_seqnum)
138200 +{
138201 + struct qman_portal *p;
138202 + struct qm_eqcr_entry *eq;
138203 + unsigned long irqflags __maybe_unused;
138204 +
138205 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138206 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138207 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138208 + else
138209 +#endif
138210 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138211 + if (!eq)
138212 + return -EBUSY;
138213 + /* Process ORP-specifics here */
138214 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138215 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138216 + else {
138217 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138218 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138219 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138220 + else
138221 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138222 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138223 + }
138224 + eq->seqnum = cpu_to_be16(orp_seqnum);
138225 + eq->orp = cpu_to_be32(orp->fqid);
138226 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138227 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138228 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138229 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138230 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138231 + PORTAL_IRQ_UNLOCK(p, irqflags);
138232 + put_affine_portal();
138233 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138234 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138235 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138236 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138237 + /* NB: return success even if signal occurs before
138238 + * condition is true. pvb_commit guarantees success */
138239 + wait_event_interruptible(affine_queue,
138240 + (p->eqci_owned != fq));
138241 + else
138242 + wait_event(affine_queue, (p->eqci_owned != fq));
138243 + }
138244 +#endif
138245 + return 0;
138246 +}
138247 +EXPORT_SYMBOL(qman_enqueue_orp);
138248 +
138249 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
138250 + const struct qm_fd *fd, u32 flags,
138251 + qman_cb_precommit cb, void *cb_arg)
138252 +{
138253 + struct qm_eqcr_entry *eq;
138254 + unsigned long irqflags __maybe_unused;
138255 +
138256 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138257 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138258 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138259 + else
138260 +#endif
138261 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138262 + if (!eq)
138263 + return -EBUSY;
138264 + /* invoke user supplied callback function before writing commit verb */
138265 + if (cb(cb_arg)) {
138266 + PORTAL_IRQ_UNLOCK(p, irqflags);
138267 + return -EINVAL;
138268 + }
138269 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138270 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138271 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138272 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138273 + PORTAL_IRQ_UNLOCK(p, irqflags);
138274 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138275 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138276 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138277 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138278 + /* NB: return success even if signal occurs before
138279 + * condition is true. pvb_commit guarantees success */
138280 + wait_event_interruptible(affine_queue,
138281 + (p->eqci_owned != fq));
138282 + else
138283 + wait_event(affine_queue, (p->eqci_owned != fq));
138284 + }
138285 +#endif
138286 + return 0;
138287 +}
138288 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
138289 +
138290 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
138291 + u32 flags, qman_cb_precommit cb, void *cb_arg)
138292 +{
138293 + struct qman_portal *p;
138294 + struct qm_eqcr_entry *eq;
138295 + unsigned long irqflags __maybe_unused;
138296 +
138297 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138298 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138299 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138300 + else
138301 +#endif
138302 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138303 + if (!eq)
138304 + return -EBUSY;
138305 + /* invoke user supplied callback function before writing commit verb */
138306 + if (cb(cb_arg)) {
138307 + PORTAL_IRQ_UNLOCK(p, irqflags);
138308 + put_affine_portal();
138309 + return -EINVAL;
138310 + }
138311 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138312 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138313 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138314 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138315 + PORTAL_IRQ_UNLOCK(p, irqflags);
138316 + put_affine_portal();
138317 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138318 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138319 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138320 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138321 + /* NB: return success even if signal occurs before
138322 + * condition is true. pvb_commit guarantees success */
138323 + wait_event_interruptible(affine_queue,
138324 + (p->eqci_owned != fq));
138325 + else
138326 + wait_event(affine_queue, (p->eqci_owned != fq));
138327 + }
138328 +#endif
138329 + return 0;
138330 +}
138331 +EXPORT_SYMBOL(qman_enqueue_precommit);
138332 +
138333 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
138334 + struct qm_mcc_initcgr *opts)
138335 +{
138336 + struct qm_mc_command *mcc;
138337 + struct qm_mc_result *mcr;
138338 + struct qman_portal *p = get_affine_portal();
138339 + unsigned long irqflags __maybe_unused;
138340 + u8 res;
138341 + u8 verb = QM_MCC_VERB_MODIFYCGR;
138342 +
138343 + PORTAL_IRQ_LOCK(p, irqflags);
138344 + mcc = qm_mc_start(&p->p);
138345 + if (opts)
138346 + mcc->initcgr = *opts;
138347 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
138348 + mcc->initcgr.cgr.wr_parm_g.word =
138349 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
138350 + mcc->initcgr.cgr.wr_parm_y.word =
138351 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
138352 + mcc->initcgr.cgr.wr_parm_r.word =
138353 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
138354 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
138355 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
138356 +
138357 + mcc->initcgr.cgid = cgr->cgrid;
138358 + if (flags & QMAN_CGR_FLAG_USE_INIT)
138359 + verb = QM_MCC_VERB_INITCGR;
138360 + qm_mc_commit(&p->p, verb);
138361 + while (!(mcr = qm_mc_result(&p->p)))
138362 + cpu_relax();
138363 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
138364 + res = mcr->result;
138365 + PORTAL_IRQ_UNLOCK(p, irqflags);
138366 + put_affine_portal();
138367 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
138368 +}
138369 +EXPORT_SYMBOL(qman_modify_cgr);
138370 +
138371 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
138372 + QM_CHANNEL_SWPORTAL0))
138373 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
138374 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
138375 +
138376 +static u8 qman_cgr_cpus[__CGR_NUM];
138377 +
138378 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
138379 + struct qm_mcc_initcgr *opts)
138380 +{
138381 + unsigned long irqflags __maybe_unused;
138382 + struct qm_mcr_querycgr cgr_state;
138383 + struct qm_mcc_initcgr local_opts;
138384 + int ret;
138385 + struct qman_portal *p;
138386 +
138387 + /* We have to check that the provided CGRID is within the limits of the
138388 + * data-structures, for obvious reasons. However we'll let h/w take
138389 + * care of determining whether it's within the limits of what exists on
138390 + * the SoC. */
138391 + if (cgr->cgrid >= __CGR_NUM)
138392 + return -EINVAL;
138393 +
138394 + preempt_disable();
138395 + p = get_affine_portal();
138396 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
138397 + preempt_enable();
138398 +
138399 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138400 + cgr->chan = p->config->public_cfg.channel;
138401 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138402 +
138403 + /* if no opts specified, just add it to the list */
138404 + if (!opts)
138405 + goto add_list;
138406 +
138407 + ret = qman_query_cgr(cgr, &cgr_state);
138408 + if (ret)
138409 + goto release_lock;
138410 + if (opts)
138411 + local_opts = *opts;
138412 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138413 + local_opts.cgr.cscn_targ_upd_ctrl =
138414 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
138415 + else
138416 + /* Overwrite TARG */
138417 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138418 + TARG_MASK(p);
138419 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138420 +
138421 + /* send init if flags indicate so */
138422 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138423 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
138424 + else
138425 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138426 + if (ret)
138427 + goto release_lock;
138428 +add_list:
138429 + list_add(&cgr->node, &p->cgr_cbs);
138430 +
138431 + /* Determine if newly added object requires its callback to be called */
138432 + ret = qman_query_cgr(cgr, &cgr_state);
138433 + if (ret) {
138434 + /* we can't go back, so proceed and return success, but screen
138435 + * and wail to the log file */
138436 + pr_crit("CGR HW state partially modified\n");
138437 + ret = 0;
138438 + goto release_lock;
138439 + }
138440 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
138441 + cgr->cgrid))
138442 + cgr->cb(p, cgr, 1);
138443 +release_lock:
138444 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138445 + put_affine_portal();
138446 + return ret;
138447 +}
138448 +EXPORT_SYMBOL(qman_create_cgr);
138449 +
138450 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
138451 + struct qm_mcc_initcgr *opts)
138452 +{
138453 + unsigned long irqflags __maybe_unused;
138454 + struct qm_mcc_initcgr local_opts;
138455 + struct qm_mcr_querycgr cgr_state;
138456 + int ret;
138457 +
138458 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
138459 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
138460 + return -EINVAL;
138461 + }
138462 + /* We have to check that the provided CGRID is within the limits of the
138463 + * data-structures, for obvious reasons. However we'll let h/w take
138464 + * care of determining whether it's within the limits of what exists on
138465 + * the SoC.
138466 + */
138467 + if (cgr->cgrid >= __CGR_NUM)
138468 + return -EINVAL;
138469 +
138470 + ret = qman_query_cgr(cgr, &cgr_state);
138471 + if (ret)
138472 + return ret;
138473 +
138474 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138475 + if (opts)
138476 + local_opts = *opts;
138477 +
138478 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138479 + local_opts.cgr.cscn_targ_upd_ctrl =
138480 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
138481 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
138482 + else
138483 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138484 + TARG_DCP_MASK(dcp_portal);
138485 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138486 +
138487 + /* send init if flags indicate so */
138488 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138489 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
138490 + &local_opts);
138491 + else
138492 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138493 +
138494 + return ret;
138495 +}
138496 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
138497 +
138498 +int qman_delete_cgr(struct qman_cgr *cgr)
138499 +{
138500 + unsigned long irqflags __maybe_unused;
138501 + struct qm_mcr_querycgr cgr_state;
138502 + struct qm_mcc_initcgr local_opts;
138503 + int ret = 0;
138504 + struct qman_cgr *i;
138505 + struct qman_portal *p = get_affine_portal();
138506 +
138507 + if (cgr->chan != p->config->public_cfg.channel) {
138508 + pr_crit("Attempting to delete cgr from different portal "
138509 + "than it was create: create 0x%x, delete 0x%x\n",
138510 + cgr->chan, p->config->public_cfg.channel);
138511 + ret = -EINVAL;
138512 + goto put_portal;
138513 + }
138514 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138515 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138516 + list_del(&cgr->node);
138517 + /*
138518 + * If there are no other CGR objects for this CGRID in the list, update
138519 + * CSCN_TARG accordingly
138520 + */
138521 + list_for_each_entry(i, &p->cgr_cbs, node)
138522 + if ((i->cgrid == cgr->cgrid) && i->cb)
138523 + goto release_lock;
138524 + ret = qman_query_cgr(cgr, &cgr_state);
138525 + if (ret) {
138526 + /* add back to the list */
138527 + list_add(&cgr->node, &p->cgr_cbs);
138528 + goto release_lock;
138529 + }
138530 + /* Overwrite TARG */
138531 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
138532 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138533 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
138534 + else
138535 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
138536 + ~(TARG_MASK(p));
138537 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138538 + if (ret)
138539 + /* add back to the list */
138540 + list_add(&cgr->node, &p->cgr_cbs);
138541 +release_lock:
138542 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138543 +put_portal:
138544 + put_affine_portal();
138545 + return ret;
138546 +}
138547 +EXPORT_SYMBOL(qman_delete_cgr);
138548 +
138549 +struct cgr_comp {
138550 + struct qman_cgr *cgr;
138551 + struct completion completion;
138552 +};
138553 +
138554 +static int qman_delete_cgr_thread(void *p)
138555 +{
138556 + struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
138557 + int res;
138558 +
138559 + res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
138560 + complete(&cgr_comp->completion);
138561 +
138562 + return res;
138563 +}
138564 +
138565 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
138566 +{
138567 + struct task_struct *thread;
138568 + struct cgr_comp cgr_comp;
138569 +
138570 + preempt_disable();
138571 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
138572 + init_completion(&cgr_comp.completion);
138573 + cgr_comp.cgr = cgr;
138574 + thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
138575 + "cgr_del");
138576 +
138577 + if (likely(!IS_ERR(thread))) {
138578 + kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
138579 + wake_up_process(thread);
138580 + wait_for_completion(&cgr_comp.completion);
138581 + preempt_enable();
138582 + return;
138583 + }
138584 + }
138585 + qman_delete_cgr(cgr);
138586 + preempt_enable();
138587 +}
138588 +EXPORT_SYMBOL(qman_delete_cgr_safe);
138589 +
138590 +int qm_get_clock(u64 *clock_hz)
138591 +{
138592 + if (!qman_clk) {
138593 + pr_warn("Qman clock speed is unknown\n");
138594 + return -EINVAL;
138595 + }
138596 + *clock_hz = (u64)qman_clk;
138597 + return 0;
138598 +}
138599 +EXPORT_SYMBOL(qm_get_clock);
138600 +
138601 +int qm_set_clock(u64 clock_hz)
138602 +{
138603 + if (qman_clk)
138604 + return -1;
138605 + qman_clk = (u32)clock_hz;
138606 + return 0;
138607 +}
138608 +EXPORT_SYMBOL(qm_set_clock);
138609 +
138610 +/* CEETM management command */
138611 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
138612 +{
138613 + struct qm_mc_command *mcc;
138614 + struct qm_mc_result *mcr;
138615 + struct qman_portal *p;
138616 + unsigned long irqflags __maybe_unused;
138617 + u8 res;
138618 +
138619 + p = get_affine_portal();
138620 + PORTAL_IRQ_LOCK(p, irqflags);
138621 +
138622 + mcc = qm_mc_start(&p->p);
138623 + mcc->lfqmt_config = *opts;
138624 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
138625 + while (!(mcr = qm_mc_result(&p->p)))
138626 + cpu_relax();
138627 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138628 + QM_CEETM_VERB_LFQMT_CONFIG);
138629 + PORTAL_IRQ_UNLOCK(p, irqflags);
138630 + put_affine_portal();
138631 +
138632 + res = mcr->result;
138633 + if (res != QM_MCR_RESULT_OK) {
138634 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
138635 + return -EIO;
138636 + }
138637 + return 0;
138638 +}
138639 +
138640 +int qman_ceetm_query_lfqmt(int lfqid,
138641 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
138642 +{
138643 + struct qm_mc_command *mcc;
138644 + struct qm_mc_result *mcr;
138645 + struct qman_portal *p;
138646 + unsigned long irqflags __maybe_unused;
138647 + u8 res;
138648 +
138649 + p = get_affine_portal();
138650 + PORTAL_IRQ_LOCK(p, irqflags);
138651 +
138652 + mcc = qm_mc_start(&p->p);
138653 + mcc->lfqmt_query.lfqid = lfqid;
138654 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
138655 + while (!(mcr = qm_mc_result(&p->p)))
138656 + cpu_relax();
138657 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
138658 + res = mcr->result;
138659 + if (res == QM_MCR_RESULT_OK)
138660 + *lfqmt_query = mcr->lfqmt_query;
138661 +
138662 + PORTAL_IRQ_UNLOCK(p, irqflags);
138663 + put_affine_portal();
138664 + if (res != QM_MCR_RESULT_OK) {
138665 + pr_err("CEETM: QUERY LFQMT failed\n");
138666 + return -EIO;
138667 + }
138668 + return 0;
138669 +}
138670 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
138671 +
138672 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
138673 +{
138674 + struct qm_mc_command *mcc;
138675 + struct qm_mc_result *mcr;
138676 + struct qman_portal *p;
138677 + unsigned long irqflags __maybe_unused;
138678 + u8 res;
138679 +
138680 + p = get_affine_portal();
138681 + PORTAL_IRQ_LOCK(p, irqflags);
138682 +
138683 + mcc = qm_mc_start(&p->p);
138684 + mcc->cq_config = *opts;
138685 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
138686 + while (!(mcr = qm_mc_result(&p->p)))
138687 + cpu_relax();
138688 + res = mcr->result;
138689 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
138690 +
138691 + PORTAL_IRQ_UNLOCK(p, irqflags);
138692 + put_affine_portal();
138693 +
138694 + if (res != QM_MCR_RESULT_OK) {
138695 + pr_err("CEETM: CONFIGURE CQ failed\n");
138696 + return -EIO;
138697 + }
138698 + return 0;
138699 +}
138700 +
138701 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
138702 + struct qm_mcr_ceetm_cq_query *cq_query)
138703 +{
138704 + struct qm_mc_command *mcc;
138705 + struct qm_mc_result *mcr;
138706 + struct qman_portal *p;
138707 + unsigned long irqflags __maybe_unused;
138708 + u8 res;
138709 +
138710 + p = get_affine_portal();
138711 + PORTAL_IRQ_LOCK(p, irqflags);
138712 +
138713 + mcc = qm_mc_start(&p->p);
138714 + mcc->cq_query.cqid = cpu_to_be16(cqid);
138715 + mcc->cq_query.dcpid = dcpid;
138716 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
138717 + while (!(mcr = qm_mc_result(&p->p)))
138718 + cpu_relax();
138719 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
138720 + res = mcr->result;
138721 + if (res == QM_MCR_RESULT_OK) {
138722 + *cq_query = mcr->cq_query;
138723 + hw_cq_query_to_cpu(cq_query);
138724 + }
138725 +
138726 + PORTAL_IRQ_UNLOCK(p, irqflags);
138727 + put_affine_portal();
138728 +
138729 + if (res != QM_MCR_RESULT_OK) {
138730 + pr_err("CEETM: QUERY CQ failed\n");
138731 + return -EIO;
138732 + }
138733 +
138734 + return 0;
138735 +}
138736 +EXPORT_SYMBOL(qman_ceetm_query_cq);
138737 +
138738 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
138739 +{
138740 + struct qm_mc_command *mcc;
138741 + struct qm_mc_result *mcr;
138742 + struct qman_portal *p;
138743 + unsigned long irqflags __maybe_unused;
138744 + u8 res;
138745 +
138746 + p = get_affine_portal();
138747 + PORTAL_IRQ_LOCK(p, irqflags);
138748 +
138749 + mcc = qm_mc_start(&p->p);
138750 + mcc->dct_config = *opts;
138751 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
138752 + while (!(mcr = qm_mc_result(&p->p)))
138753 + cpu_relax();
138754 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
138755 + res = mcr->result;
138756 +
138757 + PORTAL_IRQ_UNLOCK(p, irqflags);
138758 + put_affine_portal();
138759 +
138760 + if (res != QM_MCR_RESULT_OK) {
138761 + pr_err("CEETM: CONFIGURE DCT failed\n");
138762 + return -EIO;
138763 + }
138764 + return 0;
138765 +}
138766 +
138767 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
138768 + struct qm_mcr_ceetm_dct_query *dct_query)
138769 +{
138770 + struct qm_mc_command *mcc;
138771 + struct qm_mc_result *mcr;
138772 + struct qman_portal *p = get_affine_portal();
138773 + unsigned long irqflags __maybe_unused;
138774 + u8 res;
138775 +
138776 + PORTAL_IRQ_LOCK(p, irqflags);
138777 +
138778 + mcc = qm_mc_start(&p->p);
138779 + mcc->dct_query = *opts;
138780 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
138781 + while (!(mcr = qm_mc_result(&p->p)))
138782 + cpu_relax();
138783 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
138784 + res = mcr->result;
138785 +
138786 + PORTAL_IRQ_UNLOCK(p, irqflags);
138787 + put_affine_portal();
138788 +
138789 + if (res != QM_MCR_RESULT_OK) {
138790 + pr_err("CEETM: QUERY DCT failed\n");
138791 + return -EIO;
138792 + }
138793 +
138794 + *dct_query = mcr->dct_query;
138795 + return 0;
138796 +}
138797 +
138798 +static int qman_ceetm_configure_class_scheduler(
138799 + struct qm_mcc_ceetm_class_scheduler_config *opts)
138800 +{
138801 + struct qm_mc_command *mcc;
138802 + struct qm_mc_result *mcr;
138803 + struct qman_portal *p;
138804 + unsigned long irqflags __maybe_unused;
138805 + u8 res;
138806 +
138807 + p = get_affine_portal();
138808 + PORTAL_IRQ_LOCK(p, irqflags);
138809 +
138810 + mcc = qm_mc_start(&p->p);
138811 + mcc->csch_config = *opts;
138812 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
138813 + while (!(mcr = qm_mc_result(&p->p)))
138814 + cpu_relax();
138815 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138816 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
138817 + res = mcr->result;
138818 +
138819 + PORTAL_IRQ_UNLOCK(p, irqflags);
138820 + put_affine_portal();
138821 +
138822 + if (res != QM_MCR_RESULT_OK) {
138823 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
138824 + return -EIO;
138825 + }
138826 + return 0;
138827 +}
138828 +
138829 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
138830 + struct qm_mcr_ceetm_class_scheduler_query *query)
138831 +{
138832 + struct qm_mc_command *mcc;
138833 + struct qm_mc_result *mcr;
138834 + struct qman_portal *p;
138835 + unsigned long irqflags __maybe_unused;
138836 + u8 res;
138837 +
138838 + p = get_affine_portal();
138839 + PORTAL_IRQ_LOCK(p, irqflags);
138840 +
138841 + mcc = qm_mc_start(&p->p);
138842 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
138843 + mcc->csch_query.dcpid = channel->dcp_idx;
138844 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
138845 + while (!(mcr = qm_mc_result(&p->p)))
138846 + cpu_relax();
138847 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138848 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
138849 + res = mcr->result;
138850 +
138851 + PORTAL_IRQ_UNLOCK(p, irqflags);
138852 + put_affine_portal();
138853 +
138854 + if (res != QM_MCR_RESULT_OK) {
138855 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
138856 + return -EIO;
138857 + }
138858 + *query = mcr->csch_query;
138859 + return 0;
138860 +}
138861 +
138862 +static int qman_ceetm_configure_mapping_shaper_tcfc(
138863 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
138864 +{
138865 + struct qm_mc_command *mcc;
138866 + struct qm_mc_result *mcr;
138867 + struct qman_portal *p;
138868 + unsigned long irqflags __maybe_unused;
138869 + u8 res;
138870 +
138871 + p = get_affine_portal();
138872 + PORTAL_IRQ_LOCK(p, irqflags);
138873 +
138874 + mcc = qm_mc_start(&p->p);
138875 + mcc->mst_config = *opts;
138876 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
138877 + while (!(mcr = qm_mc_result(&p->p)))
138878 + cpu_relax();
138879 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138880 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
138881 + res = mcr->result;
138882 +
138883 + PORTAL_IRQ_UNLOCK(p, irqflags);
138884 + put_affine_portal();
138885 +
138886 + if (res != QM_MCR_RESULT_OK) {
138887 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
138888 + return -EIO;
138889 + }
138890 + return 0;
138891 +}
138892 +
138893 +static int qman_ceetm_query_mapping_shaper_tcfc(
138894 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
138895 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
138896 +{
138897 + struct qm_mc_command *mcc;
138898 + struct qm_mc_result *mcr;
138899 + struct qman_portal *p;
138900 + unsigned long irqflags __maybe_unused;
138901 + u8 res;
138902 +
138903 + p = get_affine_portal();
138904 + PORTAL_IRQ_LOCK(p, irqflags);
138905 +
138906 + mcc = qm_mc_start(&p->p);
138907 + mcc->mst_query = *opts;
138908 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
138909 + while (!(mcr = qm_mc_result(&p->p)))
138910 + cpu_relax();
138911 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138912 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
138913 + res = mcr->result;
138914 +
138915 + PORTAL_IRQ_UNLOCK(p, irqflags);
138916 + put_affine_portal();
138917 +
138918 + if (res != QM_MCR_RESULT_OK) {
138919 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
138920 + return -EIO;
138921 + }
138922 +
138923 + *response = mcr->mst_query;
138924 + return 0;
138925 +}
138926 +
138927 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
138928 +{
138929 + struct qm_mc_command *mcc;
138930 + struct qm_mc_result *mcr;
138931 + struct qman_portal *p;
138932 + unsigned long irqflags __maybe_unused;
138933 + u8 res;
138934 +
138935 + p = get_affine_portal();
138936 + PORTAL_IRQ_LOCK(p, irqflags);
138937 +
138938 + mcc = qm_mc_start(&p->p);
138939 + mcc->ccgr_config = *opts;
138940 +
138941 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
138942 + while (!(mcr = qm_mc_result(&p->p)))
138943 + cpu_relax();
138944 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
138945 +
138946 + PORTAL_IRQ_UNLOCK(p, irqflags);
138947 + put_affine_portal();
138948 +
138949 + res = mcr->result;
138950 + if (res != QM_MCR_RESULT_OK) {
138951 + pr_err("CEETM: CONFIGURE CCGR failed\n");
138952 + return -EIO;
138953 + }
138954 + return 0;
138955 +}
138956 +
138957 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
138958 + struct qm_mcr_ceetm_ccgr_query *response)
138959 +{
138960 + struct qm_mc_command *mcc;
138961 + struct qm_mc_result *mcr;
138962 + struct qman_portal *p;
138963 + unsigned long irqflags __maybe_unused;
138964 + u8 res;
138965 +
138966 + p = get_affine_portal();
138967 + PORTAL_IRQ_LOCK(p, irqflags);
138968 +
138969 + mcc = qm_mc_start(&p->p);
138970 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
138971 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
138972 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
138973 +
138974 + while (!(mcr = qm_mc_result(&p->p)))
138975 + cpu_relax();
138976 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
138977 + res = mcr->result;
138978 + if (res == QM_MCR_RESULT_OK) {
138979 + *response = mcr->ccgr_query;
138980 + hw_ccgr_query_to_cpu(response);
138981 + }
138982 +
138983 + PORTAL_IRQ_UNLOCK(p, irqflags);
138984 + put_affine_portal();
138985 + if (res != QM_MCR_RESULT_OK) {
138986 + pr_err("CEETM: QUERY CCGR failed\n");
138987 + return -EIO;
138988 + }
138989 + return 0;
138990 +}
138991 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
138992 +
138993 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
138994 + u8 command_type, u16 xsfdr,
138995 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
138996 +{
138997 + struct qm_mc_command *mcc;
138998 + struct qm_mc_result *mcr;
138999 + struct qman_portal *p;
139000 + unsigned long irqflags __maybe_unused;
139001 + u8 res;
139002 +
139003 + p = get_affine_portal();
139004 + PORTAL_IRQ_LOCK(p, irqflags);
139005 +
139006 + mcc = qm_mc_start(&p->p);
139007 + switch (command_type) {
139008 + case 0:
139009 + case 1:
139010 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
139011 + break;
139012 + case 2:
139013 + mcc->cq_ppxr.xsfdr = xsfdr;
139014 + break;
139015 + default:
139016 + break;
139017 + }
139018 + mcc->cq_ppxr.ct = command_type;
139019 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
139020 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139021 + while (!(mcr = qm_mc_result(&p->p)))
139022 + cpu_relax();
139023 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139024 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139025 +
139026 + PORTAL_IRQ_UNLOCK(p, irqflags);
139027 + put_affine_portal();
139028 +
139029 + res = mcr->result;
139030 + if (res != QM_MCR_RESULT_OK) {
139031 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
139032 + return -EIO;
139033 + }
139034 + *cq_ppxr = mcr->cq_ppxr;
139035 + return 0;
139036 +}
139037 +
139038 +static int qman_ceetm_query_statistics(u16 cid,
139039 + enum qm_dc_portal dcp_idx,
139040 + u16 command_type,
139041 + struct qm_mcr_ceetm_statistics_query *query_result)
139042 +{
139043 + struct qm_mc_command *mcc;
139044 + struct qm_mc_result *mcr;
139045 + struct qman_portal *p;
139046 + unsigned long irqflags __maybe_unused;
139047 + u8 res;
139048 +
139049 + p = get_affine_portal();
139050 + PORTAL_IRQ_LOCK(p, irqflags);
139051 +
139052 + mcc = qm_mc_start(&p->p);
139053 + mcc->stats_query_write.cid = cid;
139054 + mcc->stats_query_write.dcpid = dcp_idx;
139055 + mcc->stats_query_write.ct = command_type;
139056 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139057 +
139058 + while (!(mcr = qm_mc_result(&p->p)))
139059 + cpu_relax();
139060 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139061 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139062 +
139063 + PORTAL_IRQ_UNLOCK(p, irqflags);
139064 + put_affine_portal();
139065 +
139066 + res = mcr->result;
139067 + if (res != QM_MCR_RESULT_OK) {
139068 + pr_err("CEETM: STATISTICS QUERY failed\n");
139069 + return -EIO;
139070 + }
139071 + *query_result = mcr->stats_query;
139072 + return 0;
139073 +}
139074 +
139075 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
139076 + u16 command_type, u64 frame_count,
139077 + u64 byte_count)
139078 +{
139079 + struct qm_mc_command *mcc;
139080 + struct qm_mc_result *mcr;
139081 + struct qman_portal *p;
139082 + unsigned long irqflags __maybe_unused;
139083 + u8 res;
139084 +
139085 + p = get_affine_portal();
139086 + PORTAL_IRQ_LOCK(p, irqflags);
139087 +
139088 + mcc = qm_mc_start(&p->p);
139089 + mcc->stats_query_write.cid = cid;
139090 + mcc->stats_query_write.dcpid = dcp_idx;
139091 + mcc->stats_query_write.ct = command_type;
139092 + mcc->stats_query_write.frm_cnt = frame_count;
139093 + mcc->stats_query_write.byte_cnt = byte_count;
139094 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139095 +
139096 + while (!(mcr = qm_mc_result(&p->p)))
139097 + cpu_relax();
139098 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139099 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139100 +
139101 + PORTAL_IRQ_UNLOCK(p, irqflags);
139102 + put_affine_portal();
139103 +
139104 + res = mcr->result;
139105 + if (res != QM_MCR_RESULT_OK) {
139106 + pr_err("CEETM: STATISTICS WRITE failed\n");
139107 + return -EIO;
139108 + }
139109 + return 0;
139110 +}
139111 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
139112 +
139113 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
139114 + int rounding)
139115 +{
139116 + u16 pres;
139117 + u64 temp;
139118 + u64 qman_freq;
139119 + int ret;
139120 +
139121 + /* Read PRES from CEET_CFG_PRES register */
139122 + ret = qman_ceetm_get_prescaler(&pres);
139123 + if (ret)
139124 + return -EINVAL;
139125 +
139126 + ret = qm_get_clock(&qman_freq);
139127 + if (ret)
139128 + return -EINVAL;
139129 +
139130 + /* token-rate = bytes-per-second * update-reference-period
139131 + *
139132 + * Where token-rate is N/8192 for a integer N, and
139133 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
139134 + * is the prescalar value and QHz is the QMan clock frequency.
139135 + * So:
139136 + *
139137 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
139138 + *
139139 + * Converting to bits-per-second gives;
139140 + *
139141 + * token-rate = (bps*2^19) / (PRES*QHZ)
139142 + * N = (bps*2^32) / (PRES*QHz)
139143 + *
139144 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
139145 + * (yet minimise rounding error if 'bps' is small), we reorganise
139146 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
139147 + * N = (((bps*2^16)/PRES)*2^16)/QHz
139148 + */
139149 + temp = ROUNDING((bps << 16), pres, rounding);
139150 + temp = ROUNDING((temp << 16), qman_freq, rounding);
139151 + token_rate->whole = temp >> 13;
139152 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
139153 + return 0;
139154 +}
139155 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
139156 +
139157 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
139158 + int rounding)
139159 +{
139160 + u16 pres;
139161 + u64 temp;
139162 + u64 qman_freq;
139163 + int ret;
139164 +
139165 + /* Read PRES from CEET_CFG_PRES register */
139166 + ret = qman_ceetm_get_prescaler(&pres);
139167 + if (ret)
139168 + return -EINVAL;
139169 +
139170 + ret = qm_get_clock(&qman_freq);
139171 + if (ret)
139172 + return -EINVAL;
139173 +
139174 + /* bytes-per-second = token-rate / update-reference-period
139175 + *
139176 + * where "token-rate" is N/8192 for an integer N, and
139177 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
139178 + * the prescalar value and QHz is the QMan clock frequency. So;
139179 + *
139180 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
139181 + * = N*PRES*QHz / (4194304*8192)
139182 + * = N*PRES*QHz / (2^35)
139183 + *
139184 + * Converting to bits-per-second gives;
139185 + *
139186 + * bps = N*PRES*QHZ / (2^32)
139187 + *
139188 + * Note, the numerator has a maximum width of 72 bits! So to
139189 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
139190 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
139191 + * multiplying by N (goes to maximum of 63 bits).
139192 + *
139193 + * temp = PRES*QHZ / (2^16)
139194 + * kbps = temp*N / (2^16)
139195 + */
139196 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
139197 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
139198 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
139199 + return 0;
139200 +}
139201 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
139202 +
139203 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
139204 + unsigned int sp_idx)
139205 +{
139206 + struct qm_ceetm_sp *p;
139207 +
139208 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
139209 + (dcp_idx == qm_dc_portal_fman1));
139210 +
139211 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
139212 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
139213 + qman_ceetms[dcp_idx].sp_range[1]))) {
139214 + pr_err("Sub-portal index doesn't exist\n");
139215 + return -EINVAL;
139216 + }
139217 +
139218 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
139219 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
139220 + p->is_claimed = 1;
139221 + *sp = p;
139222 + return 0;
139223 + }
139224 + }
139225 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
139226 + return -ENODEV;
139227 +}
139228 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
139229 +
139230 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
139231 +{
139232 + struct qm_ceetm_sp *p;
139233 +
139234 + if (sp->lni && sp->lni->is_claimed == 1) {
139235 + pr_err("The dependency of sub-portal has not been released!\n");
139236 + return -EBUSY;
139237 + }
139238 +
139239 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
139240 + if (p->idx == sp->idx) {
139241 + p->is_claimed = 0;
139242 + p->lni = NULL;
139243 + }
139244 + }
139245 + /* Disable CEETM mode of this sub-portal */
139246 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
139247 +
139248 + return 0;
139249 +}
139250 +EXPORT_SYMBOL(qman_ceetm_sp_release);
139251 +
139252 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
139253 + unsigned int lni_idx)
139254 +{
139255 + struct qm_ceetm_lni *p;
139256 +
139257 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
139258 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
139259 + qman_ceetms[dcp_idx].lni_range[1]))) {
139260 + pr_err("The lni index is out of range\n");
139261 + return -EINVAL;
139262 + }
139263 +
139264 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
139265 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
139266 + *lni = p;
139267 + p->is_claimed = 1;
139268 + return 0;
139269 + }
139270 + }
139271 +
139272 + pr_err("The LNI#%d is not available!\n", lni_idx);
139273 + return -EINVAL;
139274 +}
139275 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
139276 +
139277 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
139278 +{
139279 + struct qm_ceetm_lni *p;
139280 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139281 +
139282 + if (!list_empty(&lni->channels)) {
139283 + pr_err("The LNI dependencies are not released!\n");
139284 + return -EBUSY;
139285 + }
139286 +
139287 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
139288 + if (p->idx == lni->idx) {
139289 + p->shaper_enable = 0;
139290 + p->shaper_couple = 0;
139291 + p->cr_token_rate.whole = 0;
139292 + p->cr_token_rate.fraction = 0;
139293 + p->er_token_rate.whole = 0;
139294 + p->er_token_rate.fraction = 0;
139295 + p->cr_token_bucket_limit = 0;
139296 + p->er_token_bucket_limit = 0;
139297 + p->is_claimed = 0;
139298 + }
139299 + }
139300 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139301 + config_opts.dcpid = lni->dcp_idx;
139302 + memset(&config_opts.shaper_config, 0,
139303 + sizeof(config_opts.shaper_config));
139304 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139305 +}
139306 +EXPORT_SYMBOL(qman_ceetm_lni_release);
139307 +
139308 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
139309 +{
139310 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139311 +
139312 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139313 + config_opts.dcpid = sp->dcp_idx;
139314 + config_opts.sp_mapping.map_lni_id = lni->idx;
139315 + sp->lni = lni;
139316 +
139317 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
139318 + return -EINVAL;
139319 +
139320 + /* Enable CEETM mode for this sub-portal */
139321 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
139322 +}
139323 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
139324 +
139325 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
139326 +{
139327 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139328 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139329 +
139330 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139331 + query_opts.dcpid = sp->dcp_idx;
139332 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139333 + pr_err("Can't get SP <-> LNI mapping\n");
139334 + return -EINVAL;
139335 + }
139336 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
139337 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
139338 + return 0;
139339 +}
139340 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
139341 +
139342 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
139343 + int oal)
139344 +{
139345 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139346 +
139347 + if (lni->shaper_enable) {
139348 + pr_err("The shaper has already been enabled\n");
139349 + return -EINVAL;
139350 + }
139351 + lni->shaper_enable = 1;
139352 + lni->shaper_couple = coupled;
139353 + lni->oal = oal;
139354 +
139355 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139356 + config_opts.dcpid = lni->dcp_idx;
139357 + config_opts.shaper_config.cpl = coupled;
139358 + config_opts.shaper_config.oal = oal;
139359 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
139360 + << 13) | lni->cr_token_rate.fraction);
139361 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
139362 + << 13) | lni->er_token_rate.fraction);
139363 + config_opts.shaper_config.crtbl =
139364 + cpu_to_be16(lni->cr_token_bucket_limit);
139365 + config_opts.shaper_config.ertbl =
139366 + cpu_to_be16(lni->er_token_bucket_limit);
139367 + config_opts.shaper_config.mps = 60;
139368 +
139369 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139370 +}
139371 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
139372 +
139373 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
139374 +{
139375 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139376 +
139377 + if (!lni->shaper_enable) {
139378 + pr_err("The shaper has been disabled\n");
139379 + return -EINVAL;
139380 + }
139381 +
139382 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139383 + config_opts.dcpid = lni->dcp_idx;
139384 + config_opts.shaper_config.cpl = lni->shaper_couple;
139385 + config_opts.shaper_config.oal = lni->oal;
139386 + config_opts.shaper_config.crtbl =
139387 + cpu_to_be16(lni->cr_token_bucket_limit);
139388 + config_opts.shaper_config.ertbl =
139389 + cpu_to_be16(lni->er_token_bucket_limit);
139390 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
139391 + * disable the shaping.
139392 + */
139393 + config_opts.shaper_config.crtcr = 0xFFFFFF;
139394 + config_opts.shaper_config.ertcr = 0xFFFFFF;
139395 + config_opts.shaper_config.mps = 60;
139396 + lni->shaper_enable = 0;
139397 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139398 +}
139399 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
139400 +
139401 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
139402 +{
139403 + return lni->shaper_enable;
139404 +}
139405 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
139406 +
139407 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
139408 + const struct qm_ceetm_rate *token_rate,
139409 + u16 token_limit)
139410 +{
139411 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139412 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139413 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139414 + int ret;
139415 +
139416 + lni->cr_token_rate.whole = token_rate->whole;
139417 + lni->cr_token_rate.fraction = token_rate->fraction;
139418 + lni->cr_token_bucket_limit = token_limit;
139419 + if (!lni->shaper_enable)
139420 + return 0;
139421 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139422 + query_opts.dcpid = lni->dcp_idx;
139423 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139424 + &query_result);
139425 + if (ret) {
139426 + pr_err("Fail to get current LNI shaper setting\n");
139427 + return -EINVAL;
139428 + }
139429 +
139430 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139431 + config_opts.dcpid = lni->dcp_idx;
139432 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
139433 + | (token_rate->fraction));
139434 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
139435 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139436 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139437 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
139438 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
139439 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139440 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139441 +}
139442 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
139443 +
139444 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
139445 + u64 bps,
139446 + u16 token_limit)
139447 +{
139448 + struct qm_ceetm_rate token_rate;
139449 + int ret;
139450 +
139451 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139452 + if (ret) {
139453 + pr_err("Can not convert bps to token rate\n");
139454 + return -EINVAL;
139455 + }
139456 +
139457 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
139458 +}
139459 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
139460 +
139461 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
139462 + struct qm_ceetm_rate *token_rate,
139463 + u16 *token_limit)
139464 +{
139465 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139466 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139467 + int ret;
139468 +
139469 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139470 + query_opts.dcpid = lni->dcp_idx;
139471 +
139472 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139473 + if (ret) {
139474 + pr_err("The LNI CR rate or limit is not set\n");
139475 + return -EINVAL;
139476 + }
139477 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
139478 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
139479 + 0x1FFF;
139480 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
139481 + return 0;
139482 +}
139483 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
139484 +
139485 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
139486 + u64 *bps, u16 *token_limit)
139487 +{
139488 + struct qm_ceetm_rate token_rate;
139489 + int ret;
139490 +
139491 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
139492 + if (ret) {
139493 + pr_err("The LNI CR rate or limit is not available\n");
139494 + return -EINVAL;
139495 + }
139496 +
139497 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139498 +}
139499 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
139500 +
139501 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
139502 + const struct qm_ceetm_rate *token_rate,
139503 + u16 token_limit)
139504 +{
139505 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139506 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139507 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139508 + int ret;
139509 +
139510 + lni->er_token_rate.whole = token_rate->whole;
139511 + lni->er_token_rate.fraction = token_rate->fraction;
139512 + lni->er_token_bucket_limit = token_limit;
139513 + if (!lni->shaper_enable)
139514 + return 0;
139515 +
139516 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139517 + query_opts.dcpid = lni->dcp_idx;
139518 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139519 + &query_result);
139520 + if (ret) {
139521 + pr_err("Fail to get current LNI shaper setting\n");
139522 + return -EINVAL;
139523 + }
139524 +
139525 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139526 + config_opts.dcpid = lni->dcp_idx;
139527 + config_opts.shaper_config.ertcr = cpu_to_be24(
139528 + (token_rate->whole << 13) | (token_rate->fraction));
139529 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
139530 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139531 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139532 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
139533 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
139534 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139535 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139536 +}
139537 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
139538 +
139539 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
139540 + u64 bps,
139541 + u16 token_limit)
139542 +{
139543 + struct qm_ceetm_rate token_rate;
139544 + int ret;
139545 +
139546 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139547 + if (ret) {
139548 + pr_err("Can not convert bps to token rate\n");
139549 + return -EINVAL;
139550 + }
139551 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
139552 +}
139553 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
139554 +
139555 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
139556 + struct qm_ceetm_rate *token_rate,
139557 + u16 *token_limit)
139558 +{
139559 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139560 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139561 + int ret;
139562 +
139563 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139564 + query_opts.dcpid = lni->dcp_idx;
139565 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139566 + if (ret) {
139567 + pr_err("The LNI ER rate or limit is not set\n");
139568 + return -EINVAL;
139569 + }
139570 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
139571 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
139572 + 0x1FFF;
139573 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
139574 + return 0;
139575 +}
139576 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
139577 +
139578 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
139579 + u64 *bps, u16 *token_limit)
139580 +{
139581 + struct qm_ceetm_rate token_rate;
139582 + int ret;
139583 +
139584 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
139585 + if (ret) {
139586 + pr_err("The LNI ER rate or limit is not available\n");
139587 + return -EINVAL;
139588 + }
139589 +
139590 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139591 +}
139592 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
139593 +
139594 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
139595 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
139596 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
139597 + unsigned int cq_level,
139598 + int traffic_class)
139599 +{
139600 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139601 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139602 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139603 + u64 lnitcfcc;
139604 +
139605 + if ((cq_level > 15) | (traffic_class > 7)) {
139606 + pr_err("The CQ or traffic class id is out of range\n");
139607 + return -EINVAL;
139608 + }
139609 +
139610 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139611 + query_opts.dcpid = lni->dcp_idx;
139612 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139613 + pr_err("Fail to query tcfcc\n");
139614 + return -EINVAL;
139615 + }
139616 +
139617 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
139618 + if (traffic_class == -1) {
139619 + /* disable tcfc for this CQ */
139620 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
139621 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139622 + } else {
139623 + lnitcfcc &= ~((u64)0xF <<
139624 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139625 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
139626 + traffic_class)) <<
139627 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
139628 + }
139629 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
139630 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139631 + config_opts.dcpid = lni->dcp_idx;
139632 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139633 +}
139634 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
139635 +
139636 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
139637 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
139638 + int *traffic_class)
139639 +{
139640 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139641 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139642 + int ret;
139643 + u8 lnitcfcc;
139644 +
139645 + if (cq_level > 15) {
139646 + pr_err("the CQ level is out of range\n");
139647 + return -EINVAL;
139648 + }
139649 +
139650 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
139651 + query_opts.dcpid = lni->dcp_idx;
139652 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139653 + if (ret)
139654 + return ret;
139655 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
139656 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
139657 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
139658 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
139659 + else
139660 + *traffic_class = -1;
139661 + return 0;
139662 +}
139663 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
139664 +
139665 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
139666 + struct qm_ceetm_lni *lni)
139667 +{
139668 + struct qm_ceetm_channel *p;
139669 + u32 channel_idx;
139670 + int ret = 0;
139671 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139672 +
139673 + if (lni->dcp_idx == qm_dc_portal_fman0) {
139674 + ret = qman_alloc_ceetm0_channel(&channel_idx);
139675 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
139676 + ret = qman_alloc_ceetm1_channel(&channel_idx);
139677 + } else {
139678 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139679 + lni->dcp_idx);
139680 + return -EINVAL;
139681 + }
139682 +
139683 + if (ret) {
139684 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
139685 + return -ENODEV;
139686 + }
139687 +
139688 + p = kzalloc(sizeof(*p), GFP_KERNEL);
139689 + if (!p)
139690 + return -ENOMEM;
139691 + p->idx = channel_idx;
139692 + p->dcp_idx = lni->dcp_idx;
139693 + p->lni_idx = lni->idx;
139694 + list_add_tail(&p->node, &lni->channels);
139695 + INIT_LIST_HEAD(&p->class_queues);
139696 + INIT_LIST_HEAD(&p->ccgs);
139697 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139698 + channel_idx);
139699 + config_opts.dcpid = lni->dcp_idx;
139700 + config_opts.channel_mapping.map_lni_id = lni->idx;
139701 + config_opts.channel_mapping.map_shaped = 0;
139702 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139703 + pr_err("Can't map channel#%d for LNI#%d\n",
139704 + channel_idx, lni->idx);
139705 + return -EINVAL;
139706 + }
139707 + *channel = p;
139708 + return 0;
139709 +}
139710 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
139711 +
139712 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
139713 +{
139714 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139715 + if (!list_empty(&channel->class_queues)) {
139716 + pr_err("CEETM channel#%d has class queue unreleased!\n",
139717 + channel->idx);
139718 + return -EBUSY;
139719 + }
139720 + if (!list_empty(&channel->ccgs)) {
139721 + pr_err("CEETM channel#%d has ccg unreleased!\n",
139722 + channel->idx);
139723 + return -EBUSY;
139724 + }
139725 +
139726 + /* channel->dcp_idx corresponds to known fman validation */
139727 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
139728 + (channel->dcp_idx != qm_dc_portal_fman1)) {
139729 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139730 + channel->dcp_idx);
139731 + return -EINVAL;
139732 + }
139733 +
139734 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139735 + channel->idx);
139736 + config_opts.dcpid = channel->dcp_idx;
139737 + memset(&config_opts.shaper_config, 0,
139738 + sizeof(config_opts.shaper_config));
139739 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139740 + pr_err("Can't reset channel shapping parameters\n");
139741 + return -EINVAL;
139742 + }
139743 +
139744 + if (channel->dcp_idx == qm_dc_portal_fman0) {
139745 + qman_release_ceetm0_channelid(channel->idx);
139746 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
139747 + qman_release_ceetm1_channelid(channel->idx);
139748 + } else {
139749 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
139750 + channel->dcp_idx);
139751 + return -EINVAL;
139752 + }
139753 + list_del(&channel->node);
139754 + kfree(channel);
139755 +
139756 + return 0;
139757 +}
139758 +EXPORT_SYMBOL(qman_ceetm_channel_release);
139759 +
139760 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
139761 + int coupled)
139762 +{
139763 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139764 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139765 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139766 +
139767 + if (channel->shaper_enable == 1) {
139768 + pr_err("This channel shaper has been enabled!\n");
139769 + return -EINVAL;
139770 + }
139771 +
139772 + channel->shaper_enable = 1;
139773 + channel->shaper_couple = coupled;
139774 +
139775 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139776 + channel->idx);
139777 + query_opts.dcpid = channel->dcp_idx;
139778 +
139779 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139780 + pr_err("Can't query channel mapping\n");
139781 + return -EINVAL;
139782 + }
139783 +
139784 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139785 + channel->idx);
139786 + config_opts.dcpid = channel->dcp_idx;
139787 + config_opts.channel_mapping.map_lni_id =
139788 + query_result.channel_mapping_query.map_lni_id;
139789 + config_opts.channel_mapping.map_shaped = 1;
139790 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
139791 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
139792 + return -EINVAL;
139793 + }
139794 +
139795 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139796 + channel->idx);
139797 + config_opts.shaper_config.cpl = coupled;
139798 + config_opts.shaper_config.crtcr =
139799 + cpu_to_be24((channel->cr_token_rate.whole
139800 + << 13) |
139801 + channel->cr_token_rate.fraction);
139802 + config_opts.shaper_config.ertcr =
139803 + cpu_to_be24(channel->er_token_rate.whole
139804 + << 13 |
139805 + channel->er_token_rate.fraction);
139806 + config_opts.shaper_config.crtbl =
139807 + cpu_to_be16(channel->cr_token_bucket_limit);
139808 + config_opts.shaper_config.ertbl =
139809 + cpu_to_be16(channel->er_token_bucket_limit);
139810 +
139811 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139812 +}
139813 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
139814 +
139815 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
139816 +{
139817 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139818 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139819 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139820 +
139821 +
139822 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139823 + channel->idx);
139824 + query_opts.dcpid = channel->dcp_idx;
139825 +
139826 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139827 + pr_err("Can't query channel mapping\n");
139828 + return -EINVAL;
139829 + }
139830 +
139831 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139832 + channel->idx);
139833 + config_opts.dcpid = channel->dcp_idx;
139834 + config_opts.channel_mapping.map_shaped = 0;
139835 + config_opts.channel_mapping.map_lni_id =
139836 + query_result.channel_mapping_query.map_lni_id;
139837 +
139838 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139839 +}
139840 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
139841 +
139842 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
139843 +{
139844 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139845 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139846 +
139847 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
139848 + channel->idx);
139849 + query_opts.dcpid = channel->dcp_idx;
139850 +
139851 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139852 + pr_err("Can't query channel mapping\n");
139853 + return -EINVAL;
139854 + }
139855 +
139856 + return query_result.channel_mapping_query.map_shaped;
139857 +}
139858 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
139859 +
139860 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
139861 + const struct qm_ceetm_rate *token_rate,
139862 + u16 token_limit)
139863 +{
139864 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139865 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139866 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139867 + int ret;
139868 +
139869 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139870 + channel->idx);
139871 + query_opts.dcpid = channel->dcp_idx;
139872 +
139873 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139874 + if (ret) {
139875 + pr_err("Fail to get the current channel shaper setting\n");
139876 + return -EINVAL;
139877 + }
139878 +
139879 + channel->cr_token_rate.whole = token_rate->whole;
139880 + channel->cr_token_rate.fraction = token_rate->fraction;
139881 + channel->cr_token_bucket_limit = token_limit;
139882 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139883 + channel->idx);
139884 + config_opts.dcpid = channel->dcp_idx;
139885 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
139886 + << 13) | (token_rate->fraction));
139887 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
139888 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139889 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
139890 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
139891 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139892 +}
139893 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
139894 +
139895 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
139896 + u64 bps, u16 token_limit)
139897 +{
139898 + struct qm_ceetm_rate token_rate;
139899 + int ret;
139900 +
139901 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139902 + if (ret) {
139903 + pr_err("Can not convert bps to token rate\n");
139904 + return -EINVAL;
139905 + }
139906 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
139907 + token_limit);
139908 +}
139909 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
139910 +
139911 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
139912 + struct qm_ceetm_rate *token_rate,
139913 + u16 *token_limit)
139914 +{
139915 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139916 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139917 + int ret;
139918 +
139919 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139920 + channel->idx);
139921 + query_opts.dcpid = channel->dcp_idx;
139922 +
139923 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139924 + if (ret | !query_result.shaper_query.crtcr |
139925 + !query_result.shaper_query.crtbl) {
139926 + pr_err("The channel commit rate or limit is not set\n");
139927 + return -EINVAL;
139928 + }
139929 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
139930 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
139931 + 0x1FFF;
139932 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
139933 + return 0;
139934 +}
139935 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
139936 +
139937 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
139938 + u64 *bps, u16 *token_limit)
139939 +{
139940 + struct qm_ceetm_rate token_rate;
139941 + int ret;
139942 +
139943 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
139944 + token_limit);
139945 + if (ret) {
139946 + pr_err("The channel CR rate or limit is not available\n");
139947 + return -EINVAL;
139948 + }
139949 +
139950 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139951 +}
139952 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
139953 +
139954 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
139955 + const struct qm_ceetm_rate *token_rate,
139956 + u16 token_limit)
139957 +{
139958 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139959 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139960 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139961 + int ret;
139962 +
139963 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139964 + channel->idx);
139965 + query_opts.dcpid = channel->dcp_idx;
139966 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139967 + if (ret) {
139968 + pr_err("Fail to get the current channel shaper setting\n");
139969 + return -EINVAL;
139970 + }
139971 +
139972 + channel->er_token_rate.whole = token_rate->whole;
139973 + channel->er_token_rate.fraction = token_rate->fraction;
139974 + channel->er_token_bucket_limit = token_limit;
139975 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
139976 + channel->idx);
139977 + config_opts.dcpid = channel->dcp_idx;
139978 + config_opts.shaper_config.ertcr = cpu_to_be24(
139979 + (token_rate->whole << 13) | (token_rate->fraction));
139980 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
139981 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139982 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
139983 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
139984 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139985 +}
139986 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
139987 +
139988 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
139989 + u64 bps, u16 token_limit)
139990 +{
139991 + struct qm_ceetm_rate token_rate;
139992 + int ret;
139993 +
139994 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139995 + if (ret) {
139996 + pr_err("Can not convert bps to token rate\n");
139997 + return -EINVAL;
139998 + }
139999 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
140000 + token_limit);
140001 +}
140002 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
140003 +
140004 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
140005 + struct qm_ceetm_rate *token_rate,
140006 + u16 *token_limit)
140007 +{
140008 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140009 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140010 + int ret;
140011 +
140012 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140013 + channel->idx);
140014 + query_opts.dcpid = channel->dcp_idx;
140015 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140016 + if (ret | !query_result.shaper_query.ertcr |
140017 + !query_result.shaper_query.ertbl) {
140018 + pr_err("The channel excess rate or limit is not set\n");
140019 + return -EINVAL;
140020 + }
140021 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140022 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140023 + 0x1FFF;
140024 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140025 + return 0;
140026 +}
140027 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
140028 +
140029 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
140030 + u64 *bps, u16 *token_limit)
140031 +{
140032 + struct qm_ceetm_rate token_rate;
140033 + int ret;
140034 +
140035 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
140036 + token_limit);
140037 + if (ret) {
140038 + pr_err("The channel ER rate or limit is not available\n");
140039 + return -EINVAL;
140040 + }
140041 +
140042 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140043 +}
140044 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
140045 +
140046 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
140047 + u16 token_limit)
140048 +{
140049 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140050 +
140051 + if (channel->shaper_enable) {
140052 + pr_err("This channel is a shaped one\n");
140053 + return -EINVAL;
140054 + }
140055 +
140056 + channel->cr_token_bucket_limit = token_limit;
140057 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140058 + channel->idx);
140059 + config_opts.dcpid = channel->dcp_idx;
140060 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140061 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140062 +}
140063 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
140064 +
140065 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
140066 + u16 *token_limit)
140067 +{
140068 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140069 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140070 + int ret;
140071 +
140072 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140073 + channel->idx);
140074 + query_opts.dcpid = channel->dcp_idx;
140075 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140076 + if (ret | !query_result.shaper_query.crtbl) {
140077 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
140078 + return -EINVAL;
140079 + }
140080 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140081 + return 0;
140082 +}
140083 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
140084 +
140085 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
140086 + unsigned int prio_a, unsigned int prio_b)
140087 +{
140088 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140089 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140090 + int i;
140091 +
140092 + if (prio_a > 7) {
140093 + pr_err("The priority of group A is out of range\n");
140094 + return -EINVAL;
140095 + }
140096 + if (group_b && (prio_b > 7)) {
140097 + pr_err("The priority of group B is out of range\n");
140098 + return -EINVAL;
140099 + }
140100 +
140101 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140102 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140103 + return -EINVAL;
140104 + }
140105 +
140106 + config_opts.cqcid = cpu_to_be16(channel->idx);
140107 + config_opts.dcpid = channel->dcp_idx;
140108 + config_opts.gpc_combine_flag = !group_b;
140109 + config_opts.gpc_prio_a = prio_a;
140110 + config_opts.gpc_prio_b = prio_b;
140111 +
140112 + for (i = 0; i < 8; i++)
140113 + config_opts.w[i] = query_result.w[i];
140114 + config_opts.crem = query_result.crem;
140115 + config_opts.erem = query_result.erem;
140116 +
140117 + return qman_ceetm_configure_class_scheduler(&config_opts);
140118 +}
140119 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
140120 +
140121 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
140122 + unsigned int *prio_a, unsigned int *prio_b)
140123 +{
140124 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140125 +
140126 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140127 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140128 + return -EINVAL;
140129 + }
140130 + *group_b = !query_result.gpc_combine_flag;
140131 + *prio_a = query_result.gpc_prio_a;
140132 + *prio_b = query_result.gpc_prio_b;
140133 +
140134 + return 0;
140135 +}
140136 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
140137 +
140138 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
140139 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
140140 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
140141 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
140142 + *channel, int group_b, int cre)
140143 +{
140144 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140145 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140146 + int i;
140147 +
140148 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140149 + pr_err("Cannot get the channel %d scheduler setting.\n",
140150 + channel->idx);
140151 + return -EINVAL;
140152 + }
140153 + csch_config.cqcid = cpu_to_be16(channel->idx);
140154 + csch_config.dcpid = channel->dcp_idx;
140155 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140156 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140157 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140158 +
140159 + for (i = 0; i < 8; i++)
140160 + csch_config.w[i] = csch_query.w[i];
140161 + csch_config.erem = csch_query.erem;
140162 + if (group_b)
140163 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140164 + & ~GROUP_B_ELIGIBILITY_SET)
140165 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
140166 + else
140167 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140168 + & ~GROUP_A_ELIGIBILITY_SET)
140169 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
140170 +
140171 + csch_config.crem = cpu_to_be16(csch_config.crem);
140172 +
140173 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140174 + pr_err("Cannot config channel %d's scheduler with "
140175 + "group_%c's cr eligibility\n", channel->idx,
140176 + group_b ? 'b' : 'a');
140177 + return -EINVAL;
140178 + }
140179 +
140180 + return 0;
140181 +}
140182 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
140183 +
140184 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
140185 + *channel, int group_b, int ere)
140186 +{
140187 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140188 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140189 + int i;
140190 +
140191 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140192 + pr_err("Cannot get the channel %d scheduler setting.\n",
140193 + channel->idx);
140194 + return -EINVAL;
140195 + }
140196 + csch_config.cqcid = cpu_to_be16(channel->idx);
140197 + csch_config.dcpid = channel->dcp_idx;
140198 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140199 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140200 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140201 +
140202 + for (i = 0; i < 8; i++)
140203 + csch_config.w[i] = csch_query.w[i];
140204 + csch_config.crem = csch_query.crem;
140205 + if (group_b)
140206 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140207 + & ~GROUP_B_ELIGIBILITY_SET)
140208 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
140209 + else
140210 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140211 + & ~GROUP_A_ELIGIBILITY_SET)
140212 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
140213 +
140214 + csch_config.erem = cpu_to_be16(csch_config.erem);
140215 +
140216 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140217 + pr_err("Cannot config channel %d's scheduler with "
140218 + "group_%c's er eligibility\n", channel->idx,
140219 + group_b ? 'b' : 'a');
140220 + return -EINVAL;
140221 + }
140222 +
140223 + return 0;
140224 +}
140225 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
140226 +
140227 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
140228 + unsigned int idx, int cre)
140229 +{
140230 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140231 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140232 + int i;
140233 +
140234 + if (idx > 7) {
140235 + pr_err("CQ index is out of range\n");
140236 + return -EINVAL;
140237 + }
140238 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140239 + pr_err("Cannot get the channel %d scheduler setting.\n",
140240 + channel->idx);
140241 + return -EINVAL;
140242 + }
140243 + csch_config.cqcid = cpu_to_be16(channel->idx);
140244 + csch_config.dcpid = channel->dcp_idx;
140245 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140246 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140247 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140248 + for (i = 0; i < 8; i++)
140249 + csch_config.w[i] = csch_query.w[i];
140250 + csch_config.erem = csch_query.erem;
140251 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140252 + & ~CQ_ELIGIBILITY_SET(idx)) |
140253 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
140254 + csch_config.crem = cpu_to_be16(csch_config.crem);
140255 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140256 + pr_err("Cannot config channel scheduler to set "
140257 + "cr eligibility mask for CQ#%d\n", idx);
140258 + return -EINVAL;
140259 + }
140260 +
140261 + return 0;
140262 +}
140263 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
140264 +
140265 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
140266 + unsigned int idx, int ere)
140267 +{
140268 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140269 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140270 + int i;
140271 +
140272 + if (idx > 7) {
140273 + pr_err("CQ index is out of range\n");
140274 + return -EINVAL;
140275 + }
140276 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140277 + pr_err("Cannot get the channel %d scheduler setting.\n",
140278 + channel->idx);
140279 + return -EINVAL;
140280 + }
140281 + csch_config.cqcid = cpu_to_be16(channel->idx);
140282 + csch_config.dcpid = channel->dcp_idx;
140283 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140284 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140285 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140286 + for (i = 0; i < 8; i++)
140287 + csch_config.w[i] = csch_query.w[i];
140288 + csch_config.crem = csch_query.crem;
140289 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140290 + & ~CQ_ELIGIBILITY_SET(idx)) |
140291 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
140292 + csch_config.erem = cpu_to_be16(csch_config.erem);
140293 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140294 + pr_err("Cannot config channel scheduler to set "
140295 + "er eligibility mask for CQ#%d\n", idx);
140296 + return -EINVAL;
140297 + }
140298 + return 0;
140299 +}
140300 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
140301 +
140302 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
140303 + struct qm_ceetm_channel *channel, unsigned int idx,
140304 + struct qm_ceetm_ccg *ccg)
140305 +{
140306 + struct qm_ceetm_cq *p;
140307 + struct qm_mcc_ceetm_cq_config cq_config;
140308 +
140309 + if (idx > 7) {
140310 + pr_err("The independent class queue id is out of range\n");
140311 + return -EINVAL;
140312 + }
140313 +
140314 + list_for_each_entry(p, &channel->class_queues, node) {
140315 + if (p->idx == idx) {
140316 + pr_err("The CQ#%d has been claimed!\n", idx);
140317 + return -EINVAL;
140318 + }
140319 + }
140320 +
140321 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140322 + if (!p) {
140323 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140324 + return -ENOMEM;
140325 + }
140326 +
140327 + list_add_tail(&p->node, &channel->class_queues);
140328 + p->idx = idx;
140329 + p->is_claimed = 1;
140330 + p->parent = channel;
140331 + INIT_LIST_HEAD(&p->bound_lfqids);
140332 +
140333 + if (ccg) {
140334 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140335 + cq_config.dcpid = channel->dcp_idx;
140336 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140337 + if (qman_ceetm_configure_cq(&cq_config)) {
140338 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140339 + idx, ccg->idx);
140340 + list_del(&p->node);
140341 + kfree(p);
140342 + return -EINVAL;
140343 + }
140344 + }
140345 +
140346 + *cq = p;
140347 + return 0;
140348 +}
140349 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
140350 +
140351 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
140352 + struct qm_ceetm_channel *channel, unsigned int idx,
140353 + struct qm_ceetm_ccg *ccg)
140354 +{
140355 + struct qm_ceetm_cq *p;
140356 + struct qm_mcc_ceetm_cq_config cq_config;
140357 +
140358 + if ((idx < 8) || (idx > 15)) {
140359 + pr_err("This grouped class queue id is out of range\n");
140360 + return -EINVAL;
140361 + }
140362 +
140363 + list_for_each_entry(p, &channel->class_queues, node) {
140364 + if (p->idx == idx) {
140365 + pr_err("The CQ#%d has been claimed!\n", idx);
140366 + return -EINVAL;
140367 + }
140368 + }
140369 +
140370 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140371 + if (!p) {
140372 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140373 + return -ENOMEM;
140374 + }
140375 +
140376 + list_add_tail(&p->node, &channel->class_queues);
140377 + p->idx = idx;
140378 + p->is_claimed = 1;
140379 + p->parent = channel;
140380 + INIT_LIST_HEAD(&p->bound_lfqids);
140381 +
140382 + if (ccg) {
140383 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140384 + cq_config.dcpid = channel->dcp_idx;
140385 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140386 + if (qman_ceetm_configure_cq(&cq_config)) {
140387 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140388 + idx, ccg->idx);
140389 + list_del(&p->node);
140390 + kfree(p);
140391 + return -EINVAL;
140392 + }
140393 + }
140394 + *cq = p;
140395 + return 0;
140396 +}
140397 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
140398 +
140399 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
140400 + struct qm_ceetm_channel *channel, unsigned int idx,
140401 + struct qm_ceetm_ccg *ccg)
140402 +{
140403 + struct qm_ceetm_cq *p;
140404 + struct qm_mcc_ceetm_cq_config cq_config;
140405 +
140406 + if ((idx < 12) || (idx > 15)) {
140407 + pr_err("This grouped class queue id is out of range\n");
140408 + return -EINVAL;
140409 + }
140410 +
140411 + list_for_each_entry(p, &channel->class_queues, node) {
140412 + if (p->idx == idx) {
140413 + pr_err("The CQ#%d has been claimed!\n", idx);
140414 + return -EINVAL;
140415 + }
140416 + }
140417 +
140418 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140419 + if (!p) {
140420 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140421 + return -ENOMEM;
140422 + }
140423 +
140424 + list_add_tail(&p->node, &channel->class_queues);
140425 + p->idx = idx;
140426 + p->is_claimed = 1;
140427 + p->parent = channel;
140428 + INIT_LIST_HEAD(&p->bound_lfqids);
140429 +
140430 + if (ccg) {
140431 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140432 + cq_config.dcpid = channel->dcp_idx;
140433 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140434 + if (qman_ceetm_configure_cq(&cq_config)) {
140435 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140436 + idx, ccg->idx);
140437 + list_del(&p->node);
140438 + kfree(p);
140439 + return -EINVAL;
140440 + }
140441 + }
140442 + *cq = p;
140443 + return 0;
140444 +}
140445 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
140446 +
140447 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
140448 +{
140449 + if (!list_empty(&cq->bound_lfqids)) {
140450 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
140451 + return -EBUSY;
140452 + }
140453 + list_del(&cq->node);
140454 + qman_ceetm_drain_cq(cq);
140455 + kfree(cq);
140456 + return 0;
140457 +}
140458 +EXPORT_SYMBOL(qman_ceetm_cq_release);
140459 +
140460 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
140461 + struct qm_ceetm_weight_code *weight_code)
140462 +{
140463 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140464 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140465 + int i;
140466 +
140467 + if (cq->idx < 8) {
140468 + pr_err("Can not set weight for ungrouped class queue\n");
140469 + return -EINVAL;
140470 + }
140471 +
140472 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
140473 + pr_err("Can't query channel#%d's scheduler!\n",
140474 + cq->parent->idx);
140475 + return -EINVAL;
140476 + }
140477 +
140478 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
140479 + config_opts.dcpid = cq->parent->dcp_idx;
140480 + config_opts.crem = query_result.crem;
140481 + config_opts.erem = query_result.erem;
140482 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
140483 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
140484 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
140485 +
140486 + for (i = 0; i < 8; i++)
140487 + config_opts.w[i] = query_result.w[i];
140488 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
140489 + (weight_code->x & 0x7));
140490 + return qman_ceetm_configure_class_scheduler(&config_opts);
140491 +}
140492 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
140493 +
140494 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
140495 + struct qm_ceetm_weight_code *weight_code)
140496 +{
140497 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140498 +
140499 + if (cq->idx < 8) {
140500 + pr_err("Can not get weight for ungrouped class queue\n");
140501 + return -EINVAL;
140502 + }
140503 +
140504 + if (qman_ceetm_query_class_scheduler(cq->parent,
140505 + &query_result)) {
140506 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
140507 + return -EINVAL;
140508 + }
140509 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
140510 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
140511 +
140512 + return 0;
140513 +}
140514 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
140515 +
140516 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
140517 + * effective weight = 2^x / (1 - (y/64))
140518 + * = 2^(x+6) / (64 - y)
140519 + */
140520 +static void reduce_fraction(u32 *n, u32 *d)
140521 +{
140522 + u32 factor = 2;
140523 + u32 lesser = (*n < *d) ? *n : *d;
140524 + /* If factor exceeds the square-root of the lesser of *n and *d,
140525 + * then there's no point continuing. Proof: if there was a factor
140526 + * bigger than the square root, that would imply there exists
140527 + * another factor smaller than the square-root with which it
140528 + * multiplies to give 'lesser' - but that's a contradiction
140529 + * because the other factor would have already been found and
140530 + * divided out.
140531 + */
140532 + while ((factor * factor) <= lesser) {
140533 + /* If 'factor' is a factor of *n and *d, divide them both
140534 + * by 'factor' as many times as possible.
140535 + */
140536 + while (!(*n % factor) && !(*d % factor)) {
140537 + *n /= factor;
140538 + *d /= factor;
140539 + lesser /= factor;
140540 + }
140541 + if (factor == 2)
140542 + factor = 3;
140543 + else
140544 + factor += 2;
140545 + }
140546 +}
140547 +
140548 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
140549 + u32 *numerator,
140550 + u32 *denominator)
140551 +{
140552 + *numerator = (u32) 1 << (weight_code->x + 6);
140553 + *denominator = 64 - weight_code->y;
140554 + reduce_fraction(numerator, denominator);
140555 + return 0;
140556 +}
140557 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
140558 +
140559 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
140560 + * So find 'x' by range, and then estimate 'y' using:
140561 + * 64 - y = 2^(x + 6) / weight
140562 + * = 2^(x + 6) / (n/d)
140563 + * = d * 2^(x+6) / n
140564 + * y = 64 - (d * 2^(x+6) / n)
140565 + */
140566 +int qman_ceetm_ratio2wbfs(u32 numerator,
140567 + u32 denominator,
140568 + struct qm_ceetm_weight_code *weight_code,
140569 + int rounding)
140570 +{
140571 + unsigned int y, x = 0;
140572 + /* search incrementing 'x' until:
140573 + * weight < 2^(x+1)
140574 + * n/d < 2^(x+1)
140575 + * n < d * 2^(x+1)
140576 + */
140577 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
140578 + x++;
140579 + if (x >= 8)
140580 + return -ERANGE;
140581 + /* because of the subtraction, use '-rounding' */
140582 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
140583 + if (y >= 32)
140584 + return -ERANGE;
140585 + weight_code->x = x;
140586 + weight_code->y = y;
140587 + return 0;
140588 +}
140589 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
140590 +
140591 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
140592 +{
140593 + struct qm_ceetm_weight_code weight_code;
140594 +
140595 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
140596 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
140597 + return -EINVAL;
140598 + }
140599 + return qman_ceetm_set_queue_weight(cq, &weight_code);
140600 +}
140601 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
140602 +
140603 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
140604 +{
140605 + struct qm_ceetm_weight_code weight_code;
140606 + u32 n, d;
140607 +
140608 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
140609 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
140610 + return -EINVAL;
140611 + }
140612 +
140613 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
140614 + pr_err("Cannot get the ratio with wbfs code\n");
140615 + return -EINVAL;
140616 + }
140617 +
140618 + *ratio = (n * 100) / d;
140619 + return 0;
140620 +}
140621 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
140622 +
140623 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
140624 + u64 *frame_count, u64 *byte_count)
140625 +{
140626 + struct qm_mcr_ceetm_statistics_query result;
140627 + u16 cid, command_type;
140628 + enum qm_dc_portal dcp_idx;
140629 + int ret;
140630 +
140631 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
140632 + dcp_idx = cq->parent->dcp_idx;
140633 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
140634 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
140635 + else
140636 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
140637 +
140638 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
140639 + if (ret) {
140640 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
140641 + return -EINVAL;
140642 + }
140643 +
140644 + *frame_count = be40_to_cpu(result.frm_cnt);
140645 + *byte_count = be48_to_cpu(result.byte_cnt);
140646 + return 0;
140647 +}
140648 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
140649 +
140650 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
140651 +{
140652 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
140653 + int ret;
140654 +
140655 + do {
140656 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
140657 + if (ret) {
140658 + pr_err("Failed to pop frame from CQ\n");
140659 + return -EINVAL;
140660 + }
140661 + } while (!(ppxr.stat & 0x2));
140662 +
140663 + return 0;
140664 +}
140665 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
140666 +
140667 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
140668 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
140669 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
140670 + struct qm_ceetm_cq *cq)
140671 +{
140672 + struct qm_ceetm_lfq *p;
140673 + u32 lfqid;
140674 + int ret = 0;
140675 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
140676 +
140677 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
140678 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
140679 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
140680 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
140681 + } else {
140682 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140683 + cq->parent->dcp_idx);
140684 + return -EINVAL;
140685 + }
140686 +
140687 + if (ret) {
140688 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
140689 + return -ENODEV;
140690 + }
140691 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140692 + if (!p)
140693 + return -ENOMEM;
140694 + p->idx = lfqid;
140695 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
140696 + p->parent = cq->parent;
140697 + list_add_tail(&p->node, &cq->bound_lfqids);
140698 +
140699 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
140700 + (cq->parent->dcp_idx << 16) |
140701 + (lfqid & CEETM_LFQMT_LFQID_LSB));
140702 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
140703 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
140704 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
140705 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
140706 + lfqid, cq->idx);
140707 + list_del(&p->node);
140708 + kfree(p);
140709 + return -EINVAL;
140710 + }
140711 + *lfq = p;
140712 + return 0;
140713 +}
140714 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
140715 +
140716 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
140717 +{
140718 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
140719 + qman_release_ceetm0_lfqid(lfq->idx);
140720 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
140721 + qman_release_ceetm1_lfqid(lfq->idx);
140722 + } else {
140723 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140724 + lfq->parent->dcp_idx);
140725 + return -EINVAL;
140726 + }
140727 + list_del(&lfq->node);
140728 + kfree(lfq);
140729 + return 0;
140730 +}
140731 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
140732 +
140733 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
140734 + u32 context_b)
140735 +{
140736 + struct qm_mcc_ceetm_dct_config dct_config;
140737 + lfq->context_a = context_a;
140738 + lfq->context_b = context_b;
140739 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
140740 + dct_config.dcpid = lfq->parent->dcp_idx;
140741 + dct_config.context_b = cpu_to_be32(context_b);
140742 + dct_config.context_a = cpu_to_be64(context_a);
140743 +
140744 + return qman_ceetm_configure_dct(&dct_config);
140745 +}
140746 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
140747 +
140748 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
140749 + u32 *context_b)
140750 +{
140751 + struct qm_mcc_ceetm_dct_query dct_query;
140752 + struct qm_mcr_ceetm_dct_query query_result;
140753 +
140754 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
140755 + dct_query.dcpid = lfq->parent->dcp_idx;
140756 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
140757 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
140758 + return -EINVAL;
140759 + }
140760 + *context_a = be64_to_cpu(query_result.context_a);
140761 + *context_b = be32_to_cpu(query_result.context_b);
140762 + return 0;
140763 +}
140764 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
140765 +
140766 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
140767 +{
140768 + spin_lock_init(&fq->fqlock);
140769 + fq->fqid = lfq->idx;
140770 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
140771 + if (lfq->ern)
140772 + fq->cb.ern = lfq->ern;
140773 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
140774 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
140775 + return -ENOMEM;
140776 +#endif
140777 + return 0;
140778 +}
140779 +EXPORT_SYMBOL(qman_ceetm_create_fq);
140780 +
140781 +#define MAX_CCG_IDX 0x000F
140782 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
140783 + struct qm_ceetm_channel *channel,
140784 + unsigned int idx,
140785 + void (*cscn)(struct qm_ceetm_ccg *,
140786 + void *cb_ctx,
140787 + int congested),
140788 + void *cb_ctx)
140789 +{
140790 + struct qm_ceetm_ccg *p;
140791 +
140792 + if (idx > MAX_CCG_IDX) {
140793 + pr_err("The given ccg index is out of range\n");
140794 + return -EINVAL;
140795 + }
140796 +
140797 + list_for_each_entry(p, &channel->ccgs, node) {
140798 + if (p->idx == idx) {
140799 + pr_err("The CCG#%d has been claimed\n", idx);
140800 + return -EINVAL;
140801 + }
140802 + }
140803 +
140804 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140805 + if (!p) {
140806 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
140807 + return -ENOMEM;
140808 + }
140809 +
140810 + list_add_tail(&p->node, &channel->ccgs);
140811 +
140812 + p->idx = idx;
140813 + p->parent = channel;
140814 + p->cb = cscn;
140815 + p->cb_ctx = cb_ctx;
140816 + INIT_LIST_HEAD(&p->cb_node);
140817 +
140818 + *ccg = p;
140819 + return 0;
140820 +}
140821 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
140822 +
140823 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
140824 +{
140825 + unsigned long irqflags __maybe_unused;
140826 + struct qm_mcc_ceetm_ccgr_config config_opts;
140827 + int ret = 0;
140828 + struct qman_portal *p = get_affine_portal();
140829 +
140830 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
140831 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
140832 + if (!list_empty(&ccg->cb_node))
140833 + list_del(&ccg->cb_node);
140834 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
140835 + (ccg->parent->idx << 4) | ccg->idx);
140836 + config_opts.dcpid = ccg->parent->dcp_idx;
140837 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
140838 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
140839 + ret = qman_ceetm_configure_ccgr(&config_opts);
140840 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
140841 + put_affine_portal();
140842 +
140843 + list_del(&ccg->node);
140844 + kfree(ccg);
140845 + return ret;
140846 +}
140847 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
140848 +
140849 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
140850 + const struct qm_ceetm_ccg_params *params)
140851 +{
140852 + struct qm_mcc_ceetm_ccgr_config config_opts;
140853 + unsigned long irqflags __maybe_unused;
140854 + int ret;
140855 + struct qman_portal *p;
140856 +
140857 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
140858 + return -EINVAL;
140859 +
140860 + p = get_affine_portal();
140861 +
140862 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
140863 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
140864 +
140865 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
140866 + (ccg->parent->idx << 4) | ccg->idx);
140867 + config_opts.dcpid = ccg->parent->dcp_idx;
140868 + config_opts.we_mask = we_mask;
140869 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
140870 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
140871 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
140872 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
140873 + }
140874 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
140875 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
140876 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
140877 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
140878 + config_opts.cm_config.ctl_td_en = params->td_en;
140879 + config_opts.cm_config.ctl_td_mode = params->td_mode;
140880 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
140881 + config_opts.cm_config.ctl_mode = params->mode;
140882 + config_opts.cm_config.oal = params->oal;
140883 + config_opts.cm_config.cs_thres.hword =
140884 + cpu_to_be16(params->cs_thres_in.hword);
140885 + config_opts.cm_config.cs_thres_x.hword =
140886 + cpu_to_be16(params->cs_thres_out.hword);
140887 + config_opts.cm_config.td_thres.hword =
140888 + cpu_to_be16(params->td_thres.hword);
140889 + config_opts.cm_config.wr_parm_g.word =
140890 + cpu_to_be32(params->wr_parm_g.word);
140891 + config_opts.cm_config.wr_parm_y.word =
140892 + cpu_to_be32(params->wr_parm_y.word);
140893 + config_opts.cm_config.wr_parm_r.word =
140894 + cpu_to_be32(params->wr_parm_r.word);
140895 + ret = qman_ceetm_configure_ccgr(&config_opts);
140896 + if (ret) {
140897 + pr_err("Configure CCGR CM failed!\n");
140898 + goto release_lock;
140899 + }
140900 +
140901 + if (we_mask & QM_CCGR_WE_CSCN_EN)
140902 + if (list_empty(&ccg->cb_node))
140903 + list_add(&ccg->cb_node,
140904 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
140905 +release_lock:
140906 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
140907 + put_affine_portal();
140908 + return ret;
140909 +}
140910 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
140911 +
140912 +#define CEETM_CCGR_CTL_MASK 0x01
140913 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
140914 + struct qm_ceetm_ccg_params *params)
140915 +{
140916 + struct qm_mcc_ceetm_ccgr_query query_opts;
140917 + struct qm_mcr_ceetm_ccgr_query query_result;
140918 +
140919 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
140920 + (ccg->parent->idx << 4) | ccg->idx);
140921 + query_opts.dcpid = ccg->parent->dcp_idx;
140922 +
140923 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
140924 + pr_err("Can't query CCGR#%d\n", ccg->idx);
140925 + return -EINVAL;
140926 + }
140927 +
140928 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
140929 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
140930 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
140931 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
140932 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
140933 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
140934 + params->oal = query_result.cm_query.oal;
140935 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
140936 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
140937 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
140938 + params->td_en = query_result.cm_query.ctl_td_en;
140939 + params->td_mode = query_result.cm_query.ctl_td_mode;
140940 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
140941 + params->mode = query_result.cm_query.ctl_mode;
140942 +
140943 + return 0;
140944 +}
140945 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
140946 +
140947 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
140948 + u64 *frame_count, u64 *byte_count)
140949 +{
140950 + struct qm_mcr_ceetm_statistics_query result;
140951 + u16 cid, command_type;
140952 + enum qm_dc_portal dcp_idx;
140953 + int ret;
140954 +
140955 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
140956 + dcp_idx = ccg->parent->dcp_idx;
140957 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
140958 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
140959 + else
140960 + command_type = CEETM_QUERY_REJECT_STATISTICS;
140961 +
140962 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
140963 + if (ret) {
140964 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
140965 + return -EINVAL;
140966 + }
140967 +
140968 + *frame_count = be40_to_cpu(result.frm_cnt);
140969 + *byte_count = be48_to_cpu(result.byte_cnt);
140970 + return 0;
140971 +}
140972 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
140973 +
140974 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
140975 + u16 swp_idx,
140976 + unsigned int *cscn_enabled)
140977 +{
140978 + struct qm_mcc_ceetm_ccgr_query query_opts;
140979 + struct qm_mcr_ceetm_ccgr_query query_result;
140980 + int i;
140981 +
140982 + DPA_ASSERT(swp_idx < 127);
140983 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
140984 + (ccg->parent->idx << 4) | ccg->idx);
140985 + query_opts.dcpid = ccg->parent->dcp_idx;
140986 +
140987 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
140988 + pr_err("Can't query CCGR#%d\n", ccg->idx);
140989 + return -EINVAL;
140990 + }
140991 +
140992 + i = swp_idx / 32;
140993 + i = 3 - i;
140994 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
140995 + (31 - swp_idx % 32);
140996 +
140997 + return 0;
140998 +}
140999 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
141000 +
141001 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
141002 + u16 dcp_idx,
141003 + u8 vcgid,
141004 + unsigned int cscn_enabled,
141005 + u16 we_mask,
141006 + const struct qm_ceetm_ccg_params *params)
141007 +{
141008 + struct qm_mcc_ceetm_ccgr_config config_opts;
141009 + int ret;
141010 +
141011 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141012 + (ccg->parent->idx << 4) | ccg->idx);
141013 + config_opts.dcpid = ccg->parent->dcp_idx;
141014 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
141015 + QM_CCGR_WE_CDV);
141016 + config_opts.cm_config.cdv = vcgid;
141017 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
141018 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
141019 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141020 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141021 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141022 + config_opts.cm_config.ctl_td_en = params->td_en;
141023 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141024 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141025 + config_opts.cm_config.ctl_mode = params->mode;
141026 + config_opts.cm_config.cs_thres.hword =
141027 + cpu_to_be16(params->cs_thres_in.hword);
141028 + config_opts.cm_config.cs_thres_x.hword =
141029 + cpu_to_be16(params->cs_thres_out.hword);
141030 + config_opts.cm_config.td_thres.hword =
141031 + cpu_to_be16(params->td_thres.hword);
141032 + config_opts.cm_config.wr_parm_g.word =
141033 + cpu_to_be32(params->wr_parm_g.word);
141034 + config_opts.cm_config.wr_parm_y.word =
141035 + cpu_to_be32(params->wr_parm_y.word);
141036 + config_opts.cm_config.wr_parm_r.word =
141037 + cpu_to_be32(params->wr_parm_r.word);
141038 +
141039 + ret = qman_ceetm_configure_ccgr(&config_opts);
141040 + if (ret) {
141041 + pr_err("Configure CSCN_TARG_DCP failed!\n");
141042 + return -EINVAL;
141043 + }
141044 + return 0;
141045 +}
141046 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
141047 +
141048 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
141049 + u16 dcp_idx,
141050 + u8 *vcgid,
141051 + unsigned int *cscn_enabled)
141052 +{
141053 + struct qm_mcc_ceetm_ccgr_query query_opts;
141054 + struct qm_mcr_ceetm_ccgr_query query_result;
141055 +
141056 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141057 + (ccg->parent->idx << 4) | ccg->idx);
141058 + query_opts.dcpid = ccg->parent->dcp_idx;
141059 +
141060 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141061 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141062 + return -EINVAL;
141063 + }
141064 +
141065 + *vcgid = query_result.cm_query.cdv;
141066 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
141067 + return 0;
141068 +}
141069 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
141070 +
141071 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
141072 + unsigned int dcp_idx)
141073 +{
141074 + struct qm_mc_command *mcc;
141075 + struct qm_mc_result *mcr;
141076 + struct qman_portal *p;
141077 + unsigned long irqflags __maybe_unused;
141078 + u8 res;
141079 + int i, j;
141080 +
141081 + p = get_affine_portal();
141082 + PORTAL_IRQ_LOCK(p, irqflags);
141083 +
141084 + mcc = qm_mc_start(&p->p);
141085 + for (i = 0; i < 2; i++) {
141086 + mcc->ccgr_query.ccgrid =
141087 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
141088 + mcc->ccgr_query.dcpid = dcp_idx;
141089 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
141090 +
141091 + while (!(mcr = qm_mc_result(&p->p)))
141092 + cpu_relax();
141093 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141094 + QM_CEETM_VERB_CCGR_QUERY);
141095 + res = mcr->result;
141096 + if (res == QM_MCR_RESULT_OK) {
141097 + for (j = 0; j < 8; j++)
141098 + mcr->ccgr_query.congestion_state.state.
141099 + __state[j] = be32_to_cpu(mcr->ccgr_query.
141100 + congestion_state.state.__state[j]);
141101 + *(ccg_state + i) =
141102 + mcr->ccgr_query.congestion_state.state;
141103 + } else {
141104 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
141105 + PORTAL_IRQ_UNLOCK(p, irqflags);
141106 + return -EIO;
141107 + }
141108 + }
141109 + PORTAL_IRQ_UNLOCK(p, irqflags);
141110 + put_affine_portal();
141111 + return 0;
141112 +}
141113 +
141114 +int qman_set_wpm(int wpm_enable)
141115 +{
141116 + return qm_set_wpm(wpm_enable);
141117 +}
141118 +EXPORT_SYMBOL(qman_set_wpm);
141119 +
141120 +int qman_get_wpm(int *wpm_enable)
141121 +{
141122 + return qm_get_wpm(wpm_enable);
141123 +}
141124 +EXPORT_SYMBOL(qman_get_wpm);
141125 +
141126 +int qman_shutdown_fq(u32 fqid)
141127 +{
141128 + struct qman_portal *p;
141129 + unsigned long irqflags __maybe_unused;
141130 + int ret;
141131 + struct qm_portal *low_p;
141132 + p = get_affine_portal();
141133 + PORTAL_IRQ_LOCK(p, irqflags);
141134 + low_p = &p->p;
141135 + ret = qm_shutdown_fq(&low_p, 1, fqid);
141136 + PORTAL_IRQ_UNLOCK(p, irqflags);
141137 + put_affine_portal();
141138 + return ret;
141139 +}
141140 +
141141 +const struct qm_portal_config *qman_get_qm_portal_config(
141142 + struct qman_portal *portal)
141143 +{
141144 + return portal->sharing_redirect ? NULL : portal->config;
141145 +}
141146 --- /dev/null
141147 +++ b/drivers/staging/fsl_qbman/qman_low.h
141148 @@ -0,0 +1,1427 @@
141149 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
141150 + *
141151 + * Redistribution and use in source and binary forms, with or without
141152 + * modification, are permitted provided that the following conditions are met:
141153 + * * Redistributions of source code must retain the above copyright
141154 + * notice, this list of conditions and the following disclaimer.
141155 + * * Redistributions in binary form must reproduce the above copyright
141156 + * notice, this list of conditions and the following disclaimer in the
141157 + * documentation and/or other materials provided with the distribution.
141158 + * * Neither the name of Freescale Semiconductor nor the
141159 + * names of its contributors may be used to endorse or promote products
141160 + * derived from this software without specific prior written permission.
141161 + *
141162 + *
141163 + * ALTERNATIVELY, this software may be distributed under the terms of the
141164 + * GNU General Public License ("GPL") as published by the Free Software
141165 + * Foundation, either version 2 of that License or (at your option) any
141166 + * later version.
141167 + *
141168 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
141169 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
141170 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
141171 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
141172 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
141173 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
141174 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
141175 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
141176 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
141177 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141178 + */
141179 +
141180 +#include "qman_private.h"
141181 +
141182 +/***************************/
141183 +/* Portal register assists */
141184 +/***************************/
141185 +
141186 +/* Cache-inhibited register offsets */
141187 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141188 +
141189 +#define QM_REG_EQCR_PI_CINH 0x0000
141190 +#define QM_REG_EQCR_CI_CINH 0x0004
141191 +#define QM_REG_EQCR_ITR 0x0008
141192 +#define QM_REG_DQRR_PI_CINH 0x0040
141193 +#define QM_REG_DQRR_CI_CINH 0x0044
141194 +#define QM_REG_DQRR_ITR 0x0048
141195 +#define QM_REG_DQRR_DCAP 0x0050
141196 +#define QM_REG_DQRR_SDQCR 0x0054
141197 +#define QM_REG_DQRR_VDQCR 0x0058
141198 +#define QM_REG_DQRR_PDQCR 0x005c
141199 +#define QM_REG_MR_PI_CINH 0x0080
141200 +#define QM_REG_MR_CI_CINH 0x0084
141201 +#define QM_REG_MR_ITR 0x0088
141202 +#define QM_REG_CFG 0x0100
141203 +#define QM_REG_ISR 0x0e00
141204 +#define QM_REG_IIR 0x0e0c
141205 +#define QM_REG_ITPR 0x0e14
141206 +
141207 +/* Cache-enabled register offsets */
141208 +#define QM_CL_EQCR 0x0000
141209 +#define QM_CL_DQRR 0x1000
141210 +#define QM_CL_MR 0x2000
141211 +#define QM_CL_EQCR_PI_CENA 0x3000
141212 +#define QM_CL_EQCR_CI_CENA 0x3100
141213 +#define QM_CL_DQRR_PI_CENA 0x3200
141214 +#define QM_CL_DQRR_CI_CENA 0x3300
141215 +#define QM_CL_MR_PI_CENA 0x3400
141216 +#define QM_CL_MR_CI_CENA 0x3500
141217 +#define QM_CL_CR 0x3800
141218 +#define QM_CL_RR0 0x3900
141219 +#define QM_CL_RR1 0x3940
141220 +
141221 +#endif
141222 +
141223 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
141224 +
141225 +#define QM_REG_EQCR_PI_CINH 0x3000
141226 +#define QM_REG_EQCR_CI_CINH 0x3040
141227 +#define QM_REG_EQCR_ITR 0x3080
141228 +#define QM_REG_DQRR_PI_CINH 0x3100
141229 +#define QM_REG_DQRR_CI_CINH 0x3140
141230 +#define QM_REG_DQRR_ITR 0x3180
141231 +#define QM_REG_DQRR_DCAP 0x31C0
141232 +#define QM_REG_DQRR_SDQCR 0x3200
141233 +#define QM_REG_DQRR_VDQCR 0x3240
141234 +#define QM_REG_DQRR_PDQCR 0x3280
141235 +#define QM_REG_MR_PI_CINH 0x3300
141236 +#define QM_REG_MR_CI_CINH 0x3340
141237 +#define QM_REG_MR_ITR 0x3380
141238 +#define QM_REG_CFG 0x3500
141239 +#define QM_REG_ISR 0x3600
141240 +#define QM_REG_IIR 0x36C0
141241 +#define QM_REG_ITPR 0x3740
141242 +
141243 +/* Cache-enabled register offsets */
141244 +#define QM_CL_EQCR 0x0000
141245 +#define QM_CL_DQRR 0x1000
141246 +#define QM_CL_MR 0x2000
141247 +#define QM_CL_EQCR_PI_CENA 0x3000
141248 +#define QM_CL_EQCR_CI_CENA 0x3040
141249 +#define QM_CL_DQRR_PI_CENA 0x3100
141250 +#define QM_CL_DQRR_CI_CENA 0x3140
141251 +#define QM_CL_MR_PI_CENA 0x3300
141252 +#define QM_CL_MR_CI_CENA 0x3340
141253 +#define QM_CL_CR 0x3800
141254 +#define QM_CL_RR0 0x3900
141255 +#define QM_CL_RR1 0x3940
141256 +
141257 +#endif
141258 +
141259 +
141260 +/* BTW, the drivers (and h/w programming model) already obtain the required
141261 + * synchronisation for portal accesses via lwsync(), hwsync(), and
141262 + * data-dependencies. Use of barrier()s or other order-preserving primitives
141263 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
141264 + * simply ensure that the compiler treats the portal registers as volatile (ie.
141265 + * non-coherent). */
141266 +
141267 +/* Cache-inhibited register access. */
141268 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
141269 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
141270 + (qm)->addr_ci + (o));
141271 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
141272 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
141273 +
141274 +/* Cache-enabled (index) register access */
141275 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
141276 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
141277 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
141278 +#define __qm_cl_out(qm, o, val) \
141279 + do { \
141280 + u32 *__tmpclout = (qm)->addr_ce + (o); \
141281 + __raw_writel(cpu_to_be32(val), __tmpclout); \
141282 + dcbf(__tmpclout); \
141283 + } while (0)
141284 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
141285 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
141286 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
141287 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
141288 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
141289 +#define qm_cl_invalidate(reg)\
141290 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
141291 +
141292 +/* Cache-enabled ring access */
141293 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
141294 +
141295 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
141296 + * analysis, look at using the "extra" bit in the ring index registers to avoid
141297 + * cyclic issues. */
141298 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
141299 +{
141300 + /* 'first' is included, 'last' is excluded */
141301 + if (first <= last)
141302 + return last - first;
141303 + return ringsize + last - first;
141304 +}
141305 +
141306 +/* Portal modes.
141307 + * Enum types;
141308 + * pmode == production mode
141309 + * cmode == consumption mode,
141310 + * dmode == h/w dequeue mode.
141311 + * Enum values use 3 letter codes. First letter matches the portal mode,
141312 + * remaining two letters indicate;
141313 + * ci == cache-inhibited portal register
141314 + * ce == cache-enabled portal register
141315 + * vb == in-band valid-bit (cache-enabled)
141316 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
141317 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
141318 + */
141319 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
141320 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
141321 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
141322 + qm_eqcr_pvb = 2 /* valid-bit */
141323 +};
141324 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
141325 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
141326 + qm_dqrr_dpull = 1 /* PDQCR */
141327 +};
141328 +enum qm_dqrr_pmode { /* s/w-only */
141329 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
141330 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
141331 + qm_dqrr_pvb /* reads valid-bit */
141332 +};
141333 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
141334 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
141335 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
141336 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
141337 +};
141338 +enum qm_mr_pmode { /* s/w-only */
141339 + qm_mr_pci, /* reads MR_PI_CINH */
141340 + qm_mr_pce, /* reads MR_PI_CENA */
141341 + qm_mr_pvb /* reads valid-bit */
141342 +};
141343 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
141344 + qm_mr_cci = 0, /* CI index, cache-inhibited */
141345 + qm_mr_cce = 1 /* CI index, cache-enabled */
141346 +};
141347 +
141348 +
141349 +/* ------------------------- */
141350 +/* --- Portal structures --- */
141351 +
141352 +#define QM_EQCR_SIZE 8
141353 +#define QM_DQRR_SIZE 16
141354 +#define QM_MR_SIZE 8
141355 +
141356 +struct qm_eqcr {
141357 + struct qm_eqcr_entry *ring, *cursor;
141358 + u8 ci, available, ithresh, vbit;
141359 +#ifdef CONFIG_FSL_DPA_CHECKING
141360 + u32 busy;
141361 + enum qm_eqcr_pmode pmode;
141362 +#endif
141363 +};
141364 +
141365 +struct qm_dqrr {
141366 + const struct qm_dqrr_entry *ring, *cursor;
141367 + u8 pi, ci, fill, ithresh, vbit;
141368 +#ifdef CONFIG_FSL_DPA_CHECKING
141369 + enum qm_dqrr_dmode dmode;
141370 + enum qm_dqrr_pmode pmode;
141371 + enum qm_dqrr_cmode cmode;
141372 +#endif
141373 +};
141374 +
141375 +struct qm_mr {
141376 + const struct qm_mr_entry *ring, *cursor;
141377 + u8 pi, ci, fill, ithresh, vbit;
141378 +#ifdef CONFIG_FSL_DPA_CHECKING
141379 + enum qm_mr_pmode pmode;
141380 + enum qm_mr_cmode cmode;
141381 +#endif
141382 +};
141383 +
141384 +struct qm_mc {
141385 + struct qm_mc_command *cr;
141386 + struct qm_mc_result *rr;
141387 + u8 rridx, vbit;
141388 +#ifdef CONFIG_FSL_DPA_CHECKING
141389 + enum {
141390 + /* Can be _mc_start()ed */
141391 + qman_mc_idle,
141392 + /* Can be _mc_commit()ed or _mc_abort()ed */
141393 + qman_mc_user,
141394 + /* Can only be _mc_retry()ed */
141395 + qman_mc_hw
141396 + } state;
141397 +#endif
141398 +};
141399 +
141400 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
141401 +
141402 +struct qm_addr {
141403 + void __iomem *addr_ce; /* cache-enabled */
141404 + void __iomem *addr_ci; /* cache-inhibited */
141405 +};
141406 +
141407 +struct qm_portal {
141408 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
141409 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
141410 + * is setup-only, so isn't a cause for a concern. In other words, don't
141411 + * rearrange this structure on a whim, there be dragons ... */
141412 + struct qm_addr addr;
141413 + struct qm_eqcr eqcr;
141414 + struct qm_dqrr dqrr;
141415 + struct qm_mr mr;
141416 + struct qm_mc mc;
141417 +} QM_PORTAL_ALIGNMENT;
141418 +
141419 +
141420 +/* ---------------- */
141421 +/* --- EQCR API --- */
141422 +
141423 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
141424 +#define EQCR_CARRYCLEAR(p) \
141425 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
141426 +
141427 +/* Bit-wise logic to convert a ring pointer to a ring index */
141428 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
141429 +{
141430 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
141431 +}
141432 +
141433 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
141434 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
141435 +{
141436 + /* NB: this is odd-looking, but experiments show that it generates fast
141437 + * code with essentially no branching overheads. We increment to the
141438 + * next EQCR pointer and handle overflow and 'vbit'. */
141439 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
141440 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
141441 + if (partial != eqcr->cursor)
141442 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
141443 +}
141444 +
141445 +static inline int qm_eqcr_init(struct qm_portal *portal,
141446 + enum qm_eqcr_pmode pmode,
141447 + unsigned int eq_stash_thresh,
141448 + int eq_stash_prio)
141449 +{
141450 + /* This use of 'register', as well as all other occurrences, is because
141451 + * it has been observed to generate much faster code with gcc than is
141452 + * otherwise the case. */
141453 + register struct qm_eqcr *eqcr = &portal->eqcr;
141454 + u32 cfg;
141455 + u8 pi;
141456 +
141457 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
141458 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141459 + qm_cl_invalidate(EQCR_CI);
141460 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141461 + eqcr->cursor = eqcr->ring + pi;
141462 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
141463 + QM_EQCR_VERB_VBIT : 0;
141464 + eqcr->available = QM_EQCR_SIZE - 1 -
141465 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
141466 + eqcr->ithresh = qm_in(EQCR_ITR);
141467 +#ifdef CONFIG_FSL_DPA_CHECKING
141468 + eqcr->busy = 0;
141469 + eqcr->pmode = pmode;
141470 +#endif
141471 + cfg = (qm_in(CFG) & 0x00ffffff) |
141472 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
141473 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
141474 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
141475 + qm_out(CFG, cfg);
141476 + return 0;
141477 +}
141478 +
141479 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
141480 +{
141481 + return (qm_in(CFG) >> 28) & 0x7;
141482 +}
141483 +
141484 +static inline void qm_eqcr_finish(struct qm_portal *portal)
141485 +{
141486 + register struct qm_eqcr *eqcr = &portal->eqcr;
141487 + u8 pi, ci;
141488 + u32 cfg;
141489 +
141490 + /*
141491 + * Disable EQCI stashing because the QMan only
141492 + * presents the value it previously stashed to
141493 + * maintain coherency. Setting the stash threshold
141494 + * to 1 then 0 ensures that QMan has resyncronized
141495 + * its internal copy so that the portal is clean
141496 + * when it is reinitialized in the future
141497 + */
141498 + cfg = (qm_in(CFG) & 0x0fffffff) |
141499 + (1 << 28); /* QCSP_CFG: EST */
141500 + qm_out(CFG, cfg);
141501 + cfg &= 0x0fffffff; /* stash threshold = 0 */
141502 + qm_out(CFG, cfg);
141503 +
141504 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141505 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141506 +
141507 + /* Refresh EQCR CI cache value */
141508 + qm_cl_invalidate(EQCR_CI);
141509 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141510 +
141511 + DPA_ASSERT(!eqcr->busy);
141512 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
141513 + pr_crit("losing uncommited EQCR entries\n");
141514 + if (ci != eqcr->ci)
141515 + pr_crit("missing existing EQCR completions\n");
141516 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
141517 + pr_crit("EQCR destroyed unquiesced\n");
141518 +}
141519 +
141520 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
141521 + *portal)
141522 +{
141523 + register struct qm_eqcr *eqcr = &portal->eqcr;
141524 + DPA_ASSERT(!eqcr->busy);
141525 + if (!eqcr->available)
141526 + return NULL;
141527 +
141528 +
141529 +#ifdef CONFIG_FSL_DPA_CHECKING
141530 + eqcr->busy = 1;
141531 +#endif
141532 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141533 + dcbz_64(eqcr->cursor);
141534 +#endif
141535 + return eqcr->cursor;
141536 +}
141537 +
141538 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
141539 + *portal)
141540 +{
141541 + register struct qm_eqcr *eqcr = &portal->eqcr;
141542 + u8 diff, old_ci;
141543 +
141544 + DPA_ASSERT(!eqcr->busy);
141545 + if (!eqcr->available) {
141546 + old_ci = eqcr->ci;
141547 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141548 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141549 + eqcr->available += diff;
141550 + if (!diff)
141551 + return NULL;
141552 + }
141553 +#ifdef CONFIG_FSL_DPA_CHECKING
141554 + eqcr->busy = 1;
141555 +#endif
141556 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141557 + dcbz_64(eqcr->cursor);
141558 +#endif
141559 + return eqcr->cursor;
141560 +}
141561 +
141562 +static inline void qm_eqcr_abort(struct qm_portal *portal)
141563 +{
141564 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141565 + DPA_ASSERT(eqcr->busy);
141566 +#ifdef CONFIG_FSL_DPA_CHECKING
141567 + eqcr->busy = 0;
141568 +#endif
141569 +}
141570 +
141571 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
141572 + struct qm_portal *portal, u8 myverb)
141573 +{
141574 + register struct qm_eqcr *eqcr = &portal->eqcr;
141575 + DPA_ASSERT(eqcr->busy);
141576 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
141577 + if (eqcr->available == 1)
141578 + return NULL;
141579 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141580 + dcbf(eqcr->cursor);
141581 + EQCR_INC(eqcr);
141582 + eqcr->available--;
141583 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141584 + dcbz_64(eqcr->cursor);
141585 +#endif
141586 + return eqcr->cursor;
141587 +}
141588 +
141589 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
141590 +#define EQCR_COMMIT_CHECKS(eqcr) \
141591 +do { \
141592 + DPA_ASSERT(eqcr->busy); \
141593 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
141594 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
141595 +} while (0)
141596 +#else
141597 +#define EQCR_COMMIT_CHECKS(eqcr) \
141598 +do { \
141599 + DPA_ASSERT(eqcr->busy); \
141600 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
141601 + cpu_to_be32(0x00ffffff))); \
141602 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
141603 + cpu_to_be32(0x00ffffff))); \
141604 +} while (0)
141605 +#endif
141606 +
141607 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
141608 +{
141609 + register struct qm_eqcr *eqcr = &portal->eqcr;
141610 + EQCR_COMMIT_CHECKS(eqcr);
141611 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
141612 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141613 + EQCR_INC(eqcr);
141614 + eqcr->available--;
141615 + dcbf(eqcr->cursor);
141616 + hwsync();
141617 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
141618 +#ifdef CONFIG_FSL_DPA_CHECKING
141619 + eqcr->busy = 0;
141620 +#endif
141621 +}
141622 +
141623 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
141624 +{
141625 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141626 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
141627 + qm_cl_invalidate(EQCR_PI);
141628 + qm_cl_touch_rw(EQCR_PI);
141629 +}
141630 +
141631 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
141632 +{
141633 + register struct qm_eqcr *eqcr = &portal->eqcr;
141634 + EQCR_COMMIT_CHECKS(eqcr);
141635 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
141636 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141637 + EQCR_INC(eqcr);
141638 + eqcr->available--;
141639 + dcbf(eqcr->cursor);
141640 + lwsync();
141641 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
141642 +#ifdef CONFIG_FSL_DPA_CHECKING
141643 + eqcr->busy = 0;
141644 +#endif
141645 +}
141646 +
141647 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
141648 +{
141649 + register struct qm_eqcr *eqcr = &portal->eqcr;
141650 + struct qm_eqcr_entry *eqcursor;
141651 + EQCR_COMMIT_CHECKS(eqcr);
141652 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
141653 + lwsync();
141654 + eqcursor = eqcr->cursor;
141655 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
141656 + dcbf(eqcursor);
141657 + EQCR_INC(eqcr);
141658 + eqcr->available--;
141659 +#ifdef CONFIG_FSL_DPA_CHECKING
141660 + eqcr->busy = 0;
141661 +#endif
141662 +}
141663 +
141664 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
141665 +{
141666 + register struct qm_eqcr *eqcr = &portal->eqcr;
141667 + u8 diff, old_ci = eqcr->ci;
141668 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141669 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141670 + eqcr->available += diff;
141671 + return diff;
141672 +}
141673 +
141674 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
141675 +{
141676 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
141677 + qm_cl_touch_ro(EQCR_CI);
141678 +}
141679 +
141680 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
141681 +{
141682 + register struct qm_eqcr *eqcr = &portal->eqcr;
141683 + u8 diff, old_ci = eqcr->ci;
141684 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141685 + qm_cl_invalidate(EQCR_CI);
141686 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
141687 + eqcr->available += diff;
141688 + return diff;
141689 +}
141690 +
141691 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
141692 +{
141693 + register struct qm_eqcr *eqcr = &portal->eqcr;
141694 + return eqcr->ithresh;
141695 +}
141696 +
141697 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
141698 +{
141699 + register struct qm_eqcr *eqcr = &portal->eqcr;
141700 + eqcr->ithresh = ithresh;
141701 + qm_out(EQCR_ITR, ithresh);
141702 +}
141703 +
141704 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
141705 +{
141706 + register struct qm_eqcr *eqcr = &portal->eqcr;
141707 + return eqcr->available;
141708 +}
141709 +
141710 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
141711 +{
141712 + register struct qm_eqcr *eqcr = &portal->eqcr;
141713 + return QM_EQCR_SIZE - 1 - eqcr->available;
141714 +}
141715 +
141716 +
141717 +/* ---------------- */
141718 +/* --- DQRR API --- */
141719 +
141720 +/* FIXME: many possible improvements;
141721 + * - look at changing the API to use pointer rather than index parameters now
141722 + * that 'cursor' is a pointer,
141723 + * - consider moving other parameters to pointer if it could help (ci)
141724 + */
141725 +
141726 +#define DQRR_CARRYCLEAR(p) \
141727 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
141728 +
141729 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
141730 +{
141731 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
141732 +}
141733 +
141734 +static inline const struct qm_dqrr_entry *DQRR_INC(
141735 + const struct qm_dqrr_entry *e)
141736 +{
141737 + return DQRR_CARRYCLEAR(e + 1);
141738 +}
141739 +
141740 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
141741 +{
141742 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
141743 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
141744 +}
141745 +
141746 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
141747 +{
141748 + register struct qm_dqrr *dqrr = &portal->dqrr;
141749 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
141750 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
141751 + qm_out(DQRR_CI_CINH, dqrr->ci);
141752 +}
141753 +
141754 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
141755 +{
141756 + register struct qm_dqrr *dqrr = &portal->dqrr;
141757 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
141758 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
141759 + qm_cl_out(DQRR_CI, dqrr->ci);
141760 +}
141761 +
141762 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
141763 +{
141764 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141765 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141766 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
141767 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
141768 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
141769 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
141770 +}
141771 +
141772 +static inline int qm_dqrr_init(struct qm_portal *portal,
141773 + const struct qm_portal_config *config,
141774 + enum qm_dqrr_dmode dmode,
141775 + __maybe_unused enum qm_dqrr_pmode pmode,
141776 + enum qm_dqrr_cmode cmode, u8 max_fill)
141777 +{
141778 + register struct qm_dqrr *dqrr = &portal->dqrr;
141779 + u32 cfg;
141780 +
141781 + /* Make sure the DQRR will be idle when we enable */
141782 + qm_out(DQRR_SDQCR, 0);
141783 + qm_out(DQRR_VDQCR, 0);
141784 + qm_out(DQRR_PDQCR, 0);
141785 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
141786 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
141787 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
141788 + dqrr->cursor = dqrr->ring + dqrr->ci;
141789 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
141790 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
141791 + QM_DQRR_VERB_VBIT : 0;
141792 + dqrr->ithresh = qm_in(DQRR_ITR);
141793 +
141794 + /* Free up pending DQRR entries if any as per current DCM */
141795 + if (dqrr->fill) {
141796 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
141797 +
141798 +#ifdef CONFIG_FSL_DPA_CHECKING
141799 + dqrr->cmode = dcm;
141800 +#endif
141801 + switch (dcm) {
141802 + case qm_dqrr_cci:
141803 + qm_dqrr_cci_consume(portal, dqrr->fill);
141804 + break;
141805 + case qm_dqrr_cce:
141806 + qm_dqrr_cce_consume(portal, dqrr->fill);
141807 + break;
141808 + case qm_dqrr_cdc:
141809 + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1));
141810 + break;
141811 + default:
141812 + DPA_ASSERT(0);
141813 + }
141814 + }
141815 +
141816 +#ifdef CONFIG_FSL_DPA_CHECKING
141817 + dqrr->dmode = dmode;
141818 + dqrr->pmode = pmode;
141819 + dqrr->cmode = cmode;
141820 +#endif
141821 + /* Invalidate every ring entry before beginning */
141822 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
141823 + dcbi(qm_cl(dqrr->ring, cfg));
141824 + cfg = (qm_in(CFG) & 0xff000f00) |
141825 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
141826 + ((dmode & 1) << 18) | /* DP */
141827 + ((cmode & 3) << 16) | /* DCM */
141828 + 0xa0 | /* RE+SE */
141829 + (0 ? 0x40 : 0) | /* Ignore RP */
141830 + (0 ? 0x10 : 0); /* Ignore SP */
141831 + qm_out(CFG, cfg);
141832 + qm_dqrr_set_maxfill(portal, max_fill);
141833 + return 0;
141834 +}
141835 +
141836 +static inline void qm_dqrr_finish(struct qm_portal *portal)
141837 +{
141838 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141839 +#ifdef CONFIG_FSL_DPA_CHECKING
141840 + if ((dqrr->cmode != qm_dqrr_cdc) &&
141841 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
141842 + pr_crit("Ignoring completed DQRR entries\n");
141843 +#endif
141844 +}
141845 +
141846 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
141847 + struct qm_portal *portal)
141848 +{
141849 + register struct qm_dqrr *dqrr = &portal->dqrr;
141850 + if (!dqrr->fill)
141851 + return NULL;
141852 + return dqrr->cursor;
141853 +}
141854 +
141855 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
141856 +{
141857 + register struct qm_dqrr *dqrr = &portal->dqrr;
141858 + return DQRR_PTR2IDX(dqrr->cursor);
141859 +}
141860 +
141861 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
141862 +{
141863 + register struct qm_dqrr *dqrr = &portal->dqrr;
141864 + DPA_ASSERT(dqrr->fill);
141865 + dqrr->cursor = DQRR_INC(dqrr->cursor);
141866 + return --dqrr->fill;
141867 +}
141868 +
141869 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
141870 +{
141871 + register struct qm_dqrr *dqrr = &portal->dqrr;
141872 + u8 diff, old_pi = dqrr->pi;
141873 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
141874 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
141875 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
141876 + dqrr->fill += diff;
141877 + return diff;
141878 +}
141879 +
141880 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
141881 +{
141882 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141883 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
141884 + qm_cl_invalidate(DQRR_PI);
141885 + qm_cl_touch_ro(DQRR_PI);
141886 +}
141887 +
141888 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
141889 +{
141890 + register struct qm_dqrr *dqrr = &portal->dqrr;
141891 + u8 diff, old_pi = dqrr->pi;
141892 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
141893 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
141894 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
141895 + dqrr->fill += diff;
141896 + return diff;
141897 +}
141898 +
141899 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
141900 +{
141901 + register struct qm_dqrr *dqrr = &portal->dqrr;
141902 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
141903 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
141904 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
141905 + /*
141906 + * On PowerPC platforms if PAMU is not available we need to
141907 + * manually invalidate the cache. When PAMU is available the
141908 + * cache is updated by stashing operations generated by QMan
141909 + */
141910 + dcbi(res);
141911 + dcbt_ro(res);
141912 +#endif
141913 +
141914 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
141915 + * inlining doesn't try to optimise out "excess reads". */
141916 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
141917 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
141918 + if (!dqrr->pi)
141919 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
141920 + dqrr->fill++;
141921 + }
141922 +}
141923 +
141924 +
141925 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
141926 +{
141927 + register struct qm_dqrr *dqrr = &portal->dqrr;
141928 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
141929 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
141930 + qm_out(DQRR_CI_CINH, dqrr->ci);
141931 +}
141932 +
141933 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
141934 +{
141935 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141936 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
141937 + qm_cl_invalidate(DQRR_CI);
141938 + qm_cl_touch_rw(DQRR_CI);
141939 +}
141940 +
141941 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
141942 +{
141943 + register struct qm_dqrr *dqrr = &portal->dqrr;
141944 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
141945 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
141946 + qm_cl_out(DQRR_CI, dqrr->ci);
141947 +}
141948 +
141949 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
141950 + int park)
141951 +{
141952 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141953 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141954 + DPA_ASSERT(idx < QM_DQRR_SIZE);
141955 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
141956 + ((park ? 1 : 0) << 6) | /* PK */
141957 + idx); /* DCAP_CI */
141958 +}
141959 +
141960 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
141961 + const struct qm_dqrr_entry *dq,
141962 + int park)
141963 +{
141964 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141965 + u8 idx = DQRR_PTR2IDX(dq);
141966 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141967 + DPA_ASSERT((dqrr->ring + idx) == dq);
141968 + DPA_ASSERT(idx < QM_DQRR_SIZE);
141969 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
141970 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
141971 + idx); /* DQRR_DCAP::DCAP_CI */
141972 +}
141973 +
141974 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
141975 +{
141976 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141977 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141978 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
141979 +}
141980 +
141981 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
141982 +{
141983 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141984 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141985 + qm_cl_invalidate(DQRR_CI);
141986 + qm_cl_touch_ro(DQRR_CI);
141987 +}
141988 +
141989 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
141990 +{
141991 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
141992 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
141993 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
141994 +}
141995 +
141996 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
141997 +{
141998 + register struct qm_dqrr *dqrr = &portal->dqrr;
141999 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142000 + return dqrr->ci;
142001 +}
142002 +
142003 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
142004 +{
142005 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142006 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142007 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142008 + (1 << 6) | /* PK */
142009 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
142010 +}
142011 +
142012 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
142013 +{
142014 + register struct qm_dqrr *dqrr = &portal->dqrr;
142015 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142016 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142017 + (1 << 6) | /* PK */
142018 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
142019 +}
142020 +
142021 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
142022 +{
142023 + qm_out(DQRR_SDQCR, sdqcr);
142024 +}
142025 +
142026 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
142027 +{
142028 + return qm_in(DQRR_SDQCR);
142029 +}
142030 +
142031 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
142032 +{
142033 + qm_out(DQRR_VDQCR, vdqcr);
142034 +}
142035 +
142036 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
142037 +{
142038 + return qm_in(DQRR_VDQCR);
142039 +}
142040 +
142041 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
142042 +{
142043 + qm_out(DQRR_PDQCR, pdqcr);
142044 +}
142045 +
142046 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
142047 +{
142048 + return qm_in(DQRR_PDQCR);
142049 +}
142050 +
142051 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
142052 +{
142053 + register struct qm_dqrr *dqrr = &portal->dqrr;
142054 + return dqrr->ithresh;
142055 +}
142056 +
142057 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142058 +{
142059 + qm_out(DQRR_ITR, ithresh);
142060 +}
142061 +
142062 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
142063 +{
142064 + return (qm_in(CFG) & 0x00f00000) >> 20;
142065 +}
142066 +
142067 +
142068 +/* -------------- */
142069 +/* --- MR API --- */
142070 +
142071 +#define MR_CARRYCLEAR(p) \
142072 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
142073 +
142074 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
142075 +{
142076 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
142077 +}
142078 +
142079 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
142080 +{
142081 + return MR_CARRYCLEAR(e + 1);
142082 +}
142083 +
142084 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
142085 + enum qm_mr_cmode cmode)
142086 +{
142087 + register struct qm_mr *mr = &portal->mr;
142088 + u32 cfg;
142089 +
142090 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
142091 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
142092 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
142093 + mr->cursor = mr->ring + mr->ci;
142094 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
142095 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
142096 + mr->ithresh = qm_in(MR_ITR);
142097 +#ifdef CONFIG_FSL_DPA_CHECKING
142098 + mr->pmode = pmode;
142099 + mr->cmode = cmode;
142100 +#endif
142101 + cfg = (qm_in(CFG) & 0xfffff0ff) |
142102 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
142103 + qm_out(CFG, cfg);
142104 + return 0;
142105 +}
142106 +
142107 +static inline void qm_mr_finish(struct qm_portal *portal)
142108 +{
142109 + register struct qm_mr *mr = &portal->mr;
142110 + if (mr->ci != MR_PTR2IDX(mr->cursor))
142111 + pr_crit("Ignoring completed MR entries\n");
142112 +}
142113 +
142114 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
142115 +{
142116 + register struct qm_mr *mr = &portal->mr;
142117 + if (!mr->fill)
142118 + return NULL;
142119 + return mr->cursor;
142120 +}
142121 +
142122 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
142123 +{
142124 + register struct qm_mr *mr = &portal->mr;
142125 + return MR_PTR2IDX(mr->cursor);
142126 +}
142127 +
142128 +static inline u8 qm_mr_next(struct qm_portal *portal)
142129 +{
142130 + register struct qm_mr *mr = &portal->mr;
142131 + DPA_ASSERT(mr->fill);
142132 + mr->cursor = MR_INC(mr->cursor);
142133 + return --mr->fill;
142134 +}
142135 +
142136 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
142137 +{
142138 + register struct qm_mr *mr = &portal->mr;
142139 + u8 diff, old_pi = mr->pi;
142140 + DPA_ASSERT(mr->pmode == qm_mr_pci);
142141 + mr->pi = qm_in(MR_PI_CINH);
142142 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142143 + mr->fill += diff;
142144 + return diff;
142145 +}
142146 +
142147 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
142148 +{
142149 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142150 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142151 + qm_cl_invalidate(MR_PI);
142152 + qm_cl_touch_ro(MR_PI);
142153 +}
142154 +
142155 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
142156 +{
142157 + register struct qm_mr *mr = &portal->mr;
142158 + u8 diff, old_pi = mr->pi;
142159 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142160 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
142161 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142162 + mr->fill += diff;
142163 + return diff;
142164 +}
142165 +
142166 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
142167 +{
142168 + register struct qm_mr *mr = &portal->mr;
142169 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
142170 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
142171 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142172 + * inlining doesn't try to optimise out "excess reads". */
142173 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
142174 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
142175 + if (!mr->pi)
142176 + mr->vbit ^= QM_MR_VERB_VBIT;
142177 + mr->fill++;
142178 + res = MR_INC(res);
142179 + }
142180 + dcbit_ro(res);
142181 +}
142182 +
142183 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
142184 +{
142185 + register struct qm_mr *mr = &portal->mr;
142186 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142187 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142188 + qm_out(MR_CI_CINH, mr->ci);
142189 +}
142190 +
142191 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
142192 +{
142193 + register struct qm_mr *mr = &portal->mr;
142194 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142195 + mr->ci = MR_PTR2IDX(mr->cursor);
142196 + qm_out(MR_CI_CINH, mr->ci);
142197 +}
142198 +
142199 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
142200 +{
142201 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142202 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142203 + qm_cl_invalidate(MR_CI);
142204 + qm_cl_touch_rw(MR_CI);
142205 +}
142206 +
142207 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
142208 +{
142209 + register struct qm_mr *mr = &portal->mr;
142210 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142211 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142212 + qm_cl_out(MR_CI, mr->ci);
142213 +}
142214 +
142215 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
142216 +{
142217 + register struct qm_mr *mr = &portal->mr;
142218 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142219 + mr->ci = MR_PTR2IDX(mr->cursor);
142220 + qm_cl_out(MR_CI, mr->ci);
142221 +}
142222 +
142223 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
142224 +{
142225 + register struct qm_mr *mr = &portal->mr;
142226 + return mr->ci;
142227 +}
142228 +
142229 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
142230 +{
142231 + register struct qm_mr *mr = &portal->mr;
142232 + return mr->ithresh;
142233 +}
142234 +
142235 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142236 +{
142237 + qm_out(MR_ITR, ithresh);
142238 +}
142239 +
142240 +
142241 +/* ------------------------------ */
142242 +/* --- Management command API --- */
142243 +
142244 +static inline int qm_mc_init(struct qm_portal *portal)
142245 +{
142246 + register struct qm_mc *mc = &portal->mc;
142247 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
142248 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
142249 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
142250 + QM_MCC_VERB_VBIT) ? 0 : 1;
142251 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
142252 +#ifdef CONFIG_FSL_DPA_CHECKING
142253 + mc->state = qman_mc_idle;
142254 +#endif
142255 + return 0;
142256 +}
142257 +
142258 +static inline void qm_mc_finish(struct qm_portal *portal)
142259 +{
142260 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142261 + DPA_ASSERT(mc->state == qman_mc_idle);
142262 +#ifdef CONFIG_FSL_DPA_CHECKING
142263 + if (mc->state != qman_mc_idle)
142264 + pr_crit("Losing incomplete MC command\n");
142265 +#endif
142266 +}
142267 +
142268 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
142269 +{
142270 + register struct qm_mc *mc = &portal->mc;
142271 + DPA_ASSERT(mc->state == qman_mc_idle);
142272 +#ifdef CONFIG_FSL_DPA_CHECKING
142273 + mc->state = qman_mc_user;
142274 +#endif
142275 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142276 + dcbz_64(mc->cr);
142277 +#endif
142278 + return mc->cr;
142279 +}
142280 +
142281 +static inline void qm_mc_abort(struct qm_portal *portal)
142282 +{
142283 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142284 + DPA_ASSERT(mc->state == qman_mc_user);
142285 +#ifdef CONFIG_FSL_DPA_CHECKING
142286 + mc->state = qman_mc_idle;
142287 +#endif
142288 +}
142289 +
142290 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
142291 +{
142292 + register struct qm_mc *mc = &portal->mc;
142293 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142294 + DPA_ASSERT(mc->state == qman_mc_user);
142295 + lwsync();
142296 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
142297 + dcbf(mc->cr);
142298 + dcbit_ro(rr);
142299 +#ifdef CONFIG_FSL_DPA_CHECKING
142300 + mc->state = qman_mc_hw;
142301 +#endif
142302 +}
142303 +
142304 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
142305 +{
142306 + register struct qm_mc *mc = &portal->mc;
142307 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142308 + DPA_ASSERT(mc->state == qman_mc_hw);
142309 + /* The inactive response register's verb byte always returns zero until
142310 + * its command is submitted and completed. This includes the valid-bit,
142311 + * in case you were wondering... */
142312 + if (!__raw_readb(&rr->verb)) {
142313 + dcbit_ro(rr);
142314 + return NULL;
142315 + }
142316 + mc->rridx ^= 1;
142317 + mc->vbit ^= QM_MCC_VERB_VBIT;
142318 +#ifdef CONFIG_FSL_DPA_CHECKING
142319 + mc->state = qman_mc_idle;
142320 +#endif
142321 + return rr;
142322 +}
142323 +
142324 +
142325 +/* ------------------------------------- */
142326 +/* --- Portal interrupt register API --- */
142327 +
142328 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
142329 +{
142330 + return 0;
142331 +}
142332 +
142333 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
142334 +{
142335 +}
142336 +
142337 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
142338 +{
142339 + qm_out(ITPR, iperiod);
142340 +}
142341 +
142342 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
142343 +{
142344 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142345 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
142346 +#else
142347 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
142348 +#endif
142349 +}
142350 +
142351 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
142352 + u32 val)
142353 +{
142354 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142355 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
142356 +#else
142357 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
142358 +#endif
142359 +}
142360 +
142361 +/* Cleanup FQs */
142362 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
142363 + u32 fqid)
142364 +{
142365 +
142366 + struct qm_mc_command *mcc;
142367 + struct qm_mc_result *mcr;
142368 + u8 state;
142369 + int orl_empty, fq_empty, i, drain = 0;
142370 + u32 result;
142371 + u32 channel, wq;
142372 + u16 dest_wq;
142373 +
142374 + /* Determine the state of the FQID */
142375 + mcc = qm_mc_start(portal[0]);
142376 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
142377 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
142378 + while (!(mcr = qm_mc_result(portal[0])))
142379 + cpu_relax();
142380 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
142381 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
142382 + if (state == QM_MCR_NP_STATE_OOS)
142383 + return 0; /* Already OOS, no need to do anymore checks */
142384 +
142385 + /* Query which channel the FQ is using */
142386 + mcc = qm_mc_start(portal[0]);
142387 + mcc->queryfq.fqid = cpu_to_be32(fqid);
142388 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
142389 + while (!(mcr = qm_mc_result(portal[0])))
142390 + cpu_relax();
142391 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
142392 +
142393 + /* Need to store these since the MCR gets reused */
142394 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
142395 + wq = dest_wq & 0x7;
142396 + channel = dest_wq>>3;
142397 +
142398 + switch (state) {
142399 + case QM_MCR_NP_STATE_TEN_SCHED:
142400 + case QM_MCR_NP_STATE_TRU_SCHED:
142401 + case QM_MCR_NP_STATE_ACTIVE:
142402 + case QM_MCR_NP_STATE_PARKED:
142403 + orl_empty = 0;
142404 + mcc = qm_mc_start(portal[0]);
142405 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142406 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
142407 + while (!(mcr = qm_mc_result(portal[0])))
142408 + cpu_relax();
142409 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142410 + QM_MCR_VERB_ALTER_RETIRE);
142411 + result = mcr->result; /* Make a copy as we reuse MCR below */
142412 +
142413 + if (result == QM_MCR_RESULT_PENDING) {
142414 + /* Need to wait for the FQRN in the message ring, which
142415 + will only occur once the FQ has been drained. In
142416 + order for the FQ to drain the portal needs to be set
142417 + to dequeue from the channel the FQ is scheduled on */
142418 + const struct qm_mr_entry *msg;
142419 + const struct qm_dqrr_entry *dqrr = NULL;
142420 + int found_fqrn = 0;
142421 + u16 dequeue_wq = 0;
142422 +
142423 + /* Flag that we need to drain FQ */
142424 + drain = 1;
142425 +
142426 + if (channel >= qm_channel_pool1 &&
142427 + channel < (qm_channel_pool1 + 15)) {
142428 + /* Pool channel, enable the bit in the portal */
142429 + dequeue_wq = (channel -
142430 + qm_channel_pool1 + 1)<<4 | wq;
142431 + } else if (channel < qm_channel_pool1) {
142432 + /* Dedicated channel */
142433 + dequeue_wq = wq;
142434 + } else {
142435 + pr_info("Cannot recover FQ 0x%x, it is "
142436 + "scheduled on channel 0x%x",
142437 + fqid, channel);
142438 + return -EBUSY;
142439 + }
142440 + /* Set the sdqcr to drain this channel */
142441 + if (channel < qm_channel_pool1)
142442 + for (i = 0; i < portal_count; i++)
142443 + qm_dqrr_sdqcr_set(portal[i],
142444 + QM_SDQCR_TYPE_ACTIVE |
142445 + QM_SDQCR_CHANNELS_DEDICATED);
142446 + else
142447 + for (i = 0; i < portal_count; i++)
142448 + qm_dqrr_sdqcr_set(
142449 + portal[i],
142450 + QM_SDQCR_TYPE_ACTIVE |
142451 + QM_SDQCR_CHANNELS_POOL_CONV
142452 + (channel));
142453 + while (!found_fqrn) {
142454 + /* Keep draining DQRR while checking the MR*/
142455 + for (i = 0; i < portal_count; i++) {
142456 + qm_dqrr_pvb_update(portal[i]);
142457 + dqrr = qm_dqrr_current(portal[i]);
142458 + while (dqrr) {
142459 + qm_dqrr_cdc_consume_1ptr(
142460 + portal[i], dqrr, 0);
142461 + qm_dqrr_pvb_update(portal[i]);
142462 + qm_dqrr_next(portal[i]);
142463 + dqrr = qm_dqrr_current(
142464 + portal[i]);
142465 + }
142466 + /* Process message ring too */
142467 + qm_mr_pvb_update(portal[i]);
142468 + msg = qm_mr_current(portal[i]);
142469 + while (msg) {
142470 + if ((msg->verb &
142471 + QM_MR_VERB_TYPE_MASK)
142472 + == QM_MR_VERB_FQRN)
142473 + found_fqrn = 1;
142474 + qm_mr_next(portal[i]);
142475 + qm_mr_cci_consume_to_current(
142476 + portal[i]);
142477 + qm_mr_pvb_update(portal[i]);
142478 + msg = qm_mr_current(portal[i]);
142479 + }
142480 + cpu_relax();
142481 + }
142482 + }
142483 + }
142484 + if (result != QM_MCR_RESULT_OK &&
142485 + result != QM_MCR_RESULT_PENDING) {
142486 + /* error */
142487 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
142488 + fqid, result);
142489 + return -1;
142490 + }
142491 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
142492 + /* ORL had no entries, no need to wait until the
142493 + ERNs come in */
142494 + orl_empty = 1;
142495 + }
142496 + /* Retirement succeeded, check to see if FQ needs
142497 + to be drained */
142498 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
142499 + /* FQ is Not Empty, drain using volatile DQ commands */
142500 + fq_empty = 0;
142501 + do {
142502 + const struct qm_dqrr_entry *dqrr = NULL;
142503 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
142504 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
142505 +
142506 + /* Wait for a dequeue to occur */
142507 + while (dqrr == NULL) {
142508 + qm_dqrr_pvb_update(portal[0]);
142509 + dqrr = qm_dqrr_current(portal[0]);
142510 + if (!dqrr)
142511 + cpu_relax();
142512 + }
142513 + /* Process the dequeues, making sure to
142514 + empty the ring completely */
142515 + while (dqrr) {
142516 + if (be32_to_cpu(dqrr->fqid) == fqid &&
142517 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
142518 + fq_empty = 1;
142519 + qm_dqrr_cdc_consume_1ptr(portal[0],
142520 + dqrr, 0);
142521 + qm_dqrr_pvb_update(portal[0]);
142522 + qm_dqrr_next(portal[0]);
142523 + dqrr = qm_dqrr_current(portal[0]);
142524 + }
142525 + } while (fq_empty == 0);
142526 + }
142527 + for (i = 0; i < portal_count; i++)
142528 + qm_dqrr_sdqcr_set(portal[i], 0);
142529 +
142530 + /* Wait for the ORL to have been completely drained */
142531 + while (orl_empty == 0) {
142532 + const struct qm_mr_entry *msg;
142533 + qm_mr_pvb_update(portal[0]);
142534 + msg = qm_mr_current(portal[0]);
142535 + while (msg) {
142536 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
142537 + QM_MR_VERB_FQRL)
142538 + orl_empty = 1;
142539 + qm_mr_next(portal[0]);
142540 + qm_mr_cci_consume_to_current(portal[0]);
142541 + qm_mr_pvb_update(portal[0]);
142542 + msg = qm_mr_current(portal[0]);
142543 + }
142544 + cpu_relax();
142545 + }
142546 + mcc = qm_mc_start(portal[0]);
142547 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142548 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
142549 + while (!(mcr = qm_mc_result(portal[0])))
142550 + cpu_relax();
142551 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142552 + QM_MCR_VERB_ALTER_OOS);
142553 + if (mcr->result != QM_MCR_RESULT_OK) {
142554 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
142555 + fqid, mcr->result);
142556 + return -1;
142557 + }
142558 + return 0;
142559 + case QM_MCR_NP_STATE_RETIRED:
142560 + /* Send OOS Command */
142561 + mcc = qm_mc_start(portal[0]);
142562 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142563 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
142564 + while (!(mcr = qm_mc_result(portal[0])))
142565 + cpu_relax();
142566 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142567 + QM_MCR_VERB_ALTER_OOS);
142568 + if (mcr->result) {
142569 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
142570 + return -1;
142571 + }
142572 + return 0;
142573 + }
142574 + return -1;
142575 +}
142576 --- /dev/null
142577 +++ b/drivers/staging/fsl_qbman/qman_private.h
142578 @@ -0,0 +1,398 @@
142579 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
142580 + *
142581 + * Redistribution and use in source and binary forms, with or without
142582 + * modification, are permitted provided that the following conditions are met:
142583 + * * Redistributions of source code must retain the above copyright
142584 + * notice, this list of conditions and the following disclaimer.
142585 + * * Redistributions in binary form must reproduce the above copyright
142586 + * notice, this list of conditions and the following disclaimer in the
142587 + * documentation and/or other materials provided with the distribution.
142588 + * * Neither the name of Freescale Semiconductor nor the
142589 + * names of its contributors may be used to endorse or promote products
142590 + * derived from this software without specific prior written permission.
142591 + *
142592 + *
142593 + * ALTERNATIVELY, this software may be distributed under the terms of the
142594 + * GNU General Public License ("GPL") as published by the Free Software
142595 + * Foundation, either version 2 of that License or (at your option) any
142596 + * later version.
142597 + *
142598 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
142599 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
142600 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
142601 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
142602 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
142603 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
142604 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
142605 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
142606 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
142607 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142608 + */
142609 +
142610 +#include "dpa_sys.h"
142611 +#include <linux/fsl_qman.h>
142612 +#include <linux/iommu.h>
142613 +
142614 +#if defined(CONFIG_FSL_PAMU)
142615 +#include <asm/fsl_pamu_stash.h>
142616 +#endif
142617 +
142618 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
142619 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
142620 +#endif
142621 +
142622 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
142623 + /* ----------------- */
142624 + /* Congestion Groups */
142625 + /* ----------------- */
142626 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
142627 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
142628 + * those that don't concern us. We harness the structure and accessor details
142629 + * already used in the management command to query congestion groups. */
142630 +struct qman_cgrs {
142631 + struct __qm_mcr_querycongestion q;
142632 +};
142633 +static inline void qman_cgrs_init(struct qman_cgrs *c)
142634 +{
142635 + memset(c, 0, sizeof(*c));
142636 +}
142637 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
142638 +{
142639 + memset(c, 0xff, sizeof(*c));
142640 +}
142641 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
142642 +{
142643 + return QM_MCR_QUERYCONGESTION(&c->q, num);
142644 +}
142645 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
142646 +{
142647 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
142648 +}
142649 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
142650 +{
142651 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
142652 +}
142653 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
142654 +{
142655 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
142656 + ;
142657 + return num;
142658 +}
142659 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
142660 + const struct qman_cgrs *src)
142661 +{
142662 + *dest = *src;
142663 +}
142664 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
142665 + const struct qman_cgrs *a, const struct qman_cgrs *b)
142666 +{
142667 + int ret;
142668 + u32 *_d = dest->q.__state;
142669 + const u32 *_a = a->q.__state;
142670 + const u32 *_b = b->q.__state;
142671 + for (ret = 0; ret < 8; ret++)
142672 + *(_d++) = *(_a++) & *(_b++);
142673 +}
142674 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
142675 + const struct qman_cgrs *a, const struct qman_cgrs *b)
142676 +{
142677 + int ret;
142678 + u32 *_d = dest->q.__state;
142679 + const u32 *_a = a->q.__state;
142680 + const u32 *_b = b->q.__state;
142681 + for (ret = 0; ret < 8; ret++)
142682 + *(_d++) = *(_a++) ^ *(_b++);
142683 +}
142684 +
142685 + /* ----------------------- */
142686 + /* CEETM Congestion Groups */
142687 + /* ----------------------- */
142688 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
142689 + * congestion groups.
142690 + */
142691 +struct qman_ccgrs {
142692 + struct __qm_mcr_querycongestion q[2];
142693 +};
142694 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
142695 +{
142696 + memset(c, 0, sizeof(*c));
142697 +}
142698 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
142699 +{
142700 + memset(c, 0xff, sizeof(*c));
142701 +}
142702 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
142703 +{
142704 + if (num < __CGR_NUM)
142705 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
142706 + else
142707 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
142708 +}
142709 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
142710 +{
142711 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
142712 + ;
142713 + return num;
142714 +}
142715 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
142716 + const struct qman_ccgrs *src)
142717 +{
142718 + *dest = *src;
142719 +}
142720 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
142721 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
142722 +{
142723 + int ret, i;
142724 + u32 *_d;
142725 + const u32 *_a, *_b;
142726 + for (i = 0; i < 2; i++) {
142727 + _d = dest->q[i].__state;
142728 + _a = a->q[i].__state;
142729 + _b = b->q[i].__state;
142730 + for (ret = 0; ret < 8; ret++)
142731 + *(_d++) = *(_a++) & *(_b++);
142732 + }
142733 +}
142734 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
142735 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
142736 +{
142737 + int ret, i;
142738 + u32 *_d;
142739 + const u32 *_a, *_b;
142740 + for (i = 0; i < 2; i++) {
142741 + _d = dest->q[i].__state;
142742 + _a = a->q[i].__state;
142743 + _b = b->q[i].__state;
142744 + for (ret = 0; ret < 8; ret++)
142745 + *(_d++) = *(_a++) ^ *(_b++);
142746 + }
142747 +}
142748 +
142749 +/* used by CCSR and portal interrupt code */
142750 +enum qm_isr_reg {
142751 + qm_isr_status = 0,
142752 + qm_isr_enable = 1,
142753 + qm_isr_disable = 2,
142754 + qm_isr_inhibit = 3
142755 +};
142756 +
142757 +struct qm_portal_config {
142758 + /* Corenet portal addresses;
142759 + * [0]==cache-enabled, [1]==cache-inhibited. */
142760 + __iomem void *addr_virt[2];
142761 + struct resource addr_phys[2];
142762 + struct device dev;
142763 + struct iommu_domain *iommu_domain;
142764 + /* Allow these to be joined in lists */
142765 + struct list_head list;
142766 + /* User-visible portal configuration settings */
142767 + struct qman_portal_config public_cfg;
142768 + /* power management saved data */
142769 + u32 saved_isdr;
142770 +};
142771 +
142772 +/* Revision info (for errata and feature handling) */
142773 +#define QMAN_REV11 0x0101
142774 +#define QMAN_REV12 0x0102
142775 +#define QMAN_REV20 0x0200
142776 +#define QMAN_REV30 0x0300
142777 +#define QMAN_REV31 0x0301
142778 +#define QMAN_REV32 0x0302
142779 +
142780 +/* QMan REV_2 register contains the Cfg option */
142781 +#define QMAN_REV_CFG_0 0x0
142782 +#define QMAN_REV_CFG_1 0x1
142783 +#define QMAN_REV_CFG_2 0x2
142784 +#define QMAN_REV_CFG_3 0x3
142785 +
142786 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
142787 +extern u8 qman_ip_cfg;
142788 +extern u32 qman_clk;
142789 +extern u16 qman_portal_max;
142790 +
142791 +#ifdef CONFIG_FSL_QMAN_CONFIG
142792 +/* Hooks from qman_driver.c to qman_config.c */
142793 +int qman_init_ccsr(struct device_node *node);
142794 +void qman_liodn_fixup(u16 channel);
142795 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
142796 +size_t get_qman_fqd_size(void);
142797 +#else
142798 +static inline size_t get_qman_fqd_size(void)
142799 +{
142800 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
142801 +}
142802 +#endif
142803 +
142804 +int qm_set_wpm(int wpm);
142805 +int qm_get_wpm(int *wpm);
142806 +
142807 +/* Hooks from qman_driver.c in to qman_high.c */
142808 +struct qman_portal *qman_create_portal(
142809 + struct qman_portal *portal,
142810 + const struct qm_portal_config *config,
142811 + const struct qman_cgrs *cgrs);
142812 +
142813 +struct qman_portal *qman_create_affine_portal(
142814 + const struct qm_portal_config *config,
142815 + const struct qman_cgrs *cgrs);
142816 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
142817 + int cpu);
142818 +const struct qm_portal_config *qman_destroy_affine_portal(void);
142819 +void qman_destroy_portal(struct qman_portal *qm);
142820 +
142821 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
142822 +struct qm_portal_config *qm_get_unused_portal(void);
142823 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
142824 +
142825 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
142826 +void qm_set_liodns(struct qm_portal_config *pcfg);
142827 +
142828 +/* This CGR feature is supported by h/w and required by unit-tests and the
142829 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
142830 + * corruption of h/w fields by s/w that are usually incorruptible (because the
142831 + * counters are usually maintained entirely within h/w). As such, we declare
142832 + * this API internally. */
142833 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
142834 + struct qm_mcr_cgrtestwrite *result);
142835 +
142836 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
142837 +/* If the fq object pointer is greater than the size of context_b field,
142838 + * than a lookup table is required. */
142839 +int qman_setup_fq_lookup_table(size_t num_entries);
142840 +#endif
142841 +
142842 +
142843 +/*************************************************/
142844 +/* QMan s/w corenet portal, low-level i/face */
142845 +/*************************************************/
142846 +
142847 +/* Note: most functions are only used by the high-level interface, so are
142848 + * inlined from qman_low.h. The stuff below is for use by other parts of the
142849 + * driver. */
142850 +
142851 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
142852 + * dequeue TYPE. Choose TOKEN (8-bit).
142853 + * If SOURCE == CHANNELS,
142854 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
142855 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
142856 + * priority.
142857 + * If SOURCE == SPECIFICWQ,
142858 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
142859 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
142860 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
142861 + * same value.
142862 + */
142863 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
142864 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
142865 +#define QM_SDQCR_COUNT_EXACT1 0x0
142866 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
142867 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
142868 +#define QM_SDQCR_TYPE_MASK 0x03000000
142869 +#define QM_SDQCR_TYPE_NULL 0x0
142870 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
142871 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
142872 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
142873 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
142874 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
142875 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
142876 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
142877 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
142878 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
142879 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
142880 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
142881 +
142882 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
142883 +#define QM_VDQCR_FQID_MASK 0x00ffffff
142884 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
142885 +
142886 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
142887 + * If MODE==SCHEDULED
142888 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
142889 + * If CHANNELS,
142890 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
142891 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
142892 + * priority.
142893 + * If SPECIFICWQ,
142894 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
142895 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
142896 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
142897 + * same value.
142898 + * If MODE==UNSCHEDULED
142899 + * Choose FQID().
142900 + */
142901 +#define QM_PDQCR_MODE_SCHEDULED 0x0
142902 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
142903 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
142904 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
142905 +#define QM_PDQCR_COUNT_EXACT1 0x0
142906 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
142907 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
142908 +#define QM_PDQCR_TYPE_MASK 0x03000000
142909 +#define QM_PDQCR_TYPE_NULL 0x0
142910 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
142911 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
142912 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
142913 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
142914 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
142915 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
142916 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
142917 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
142918 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
142919 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
142920 +
142921 +/* Used by all portal interrupt registers except 'inhibit'
142922 + * Channels with frame availability
142923 + */
142924 +#define QM_PIRQ_DQAVAIL 0x0000ffff
142925 +
142926 +/* The DQAVAIL interrupt fields break down into these bits; */
142927 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
142928 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
142929 +#define QM_DQAVAIL_MASK 0xffff
142930 +/* This mask contains all the "irqsource" bits visible to API users */
142931 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
142932 +
142933 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
142934 + * the disable register" rather than "disable the ability to write". */
142935 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
142936 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
142937 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
142938 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
142939 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
142940 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
142941 +/* TODO: unfortunate name-clash here, reword? */
142942 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
142943 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
142944 +
142945 +#ifdef CONFIG_FSL_QMAN_CONFIG
142946 +int qman_have_ccsr(void);
142947 +#else
142948 +#define qman_have_ccsr 0
142949 +#endif
142950 +
142951 +__init int qman_init(void);
142952 +__init int qman_resource_init(void);
142953 +
142954 +/* CEETM related */
142955 +#define QMAN_CEETM_MAX 2
142956 +extern u8 num_ceetms;
142957 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
142958 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
142959 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
142960 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
142961 +int qman_ceetm_get_prescaler(u16 *pres);
142962 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
142963 + struct qm_mcr_ceetm_cq_query *cq_query);
142964 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
142965 + struct qm_mcr_ceetm_ccgr_query *response);
142966 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
142967 +
142968 +extern void *affine_portals[NR_CPUS];
142969 +const struct qm_portal_config *qman_get_qm_portal_config(
142970 + struct qman_portal *portal);
142971 +
142972 +/* power management */
142973 +#ifdef CONFIG_SUSPEND
142974 +void suspend_unused_qportal(void);
142975 +void resume_unused_qportal(void);
142976 +#endif
142977 --- /dev/null
142978 +++ b/drivers/staging/fsl_qbman/qman_test.c
142979 @@ -0,0 +1,57 @@
142980 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
142981 + *
142982 + * Redistribution and use in source and binary forms, with or without
142983 + * modification, are permitted provided that the following conditions are met:
142984 + * * Redistributions of source code must retain the above copyright
142985 + * notice, this list of conditions and the following disclaimer.
142986 + * * Redistributions in binary form must reproduce the above copyright
142987 + * notice, this list of conditions and the following disclaimer in the
142988 + * documentation and/or other materials provided with the distribution.
142989 + * * Neither the name of Freescale Semiconductor nor the
142990 + * names of its contributors may be used to endorse or promote products
142991 + * derived from this software without specific prior written permission.
142992 + *
142993 + *
142994 + * ALTERNATIVELY, this software may be distributed under the terms of the
142995 + * GNU General Public License ("GPL") as published by the Free Software
142996 + * Foundation, either version 2 of that License or (at your option) any
142997 + * later version.
142998 + *
142999 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143000 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143001 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143002 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143003 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143004 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143005 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143006 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143007 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143008 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143009 + */
143010 +
143011 +#include "qman_test.h"
143012 +
143013 +MODULE_AUTHOR("Geoff Thorpe");
143014 +MODULE_LICENSE("Dual BSD/GPL");
143015 +MODULE_DESCRIPTION("Qman testing");
143016 +
143017 +static int test_init(void)
143018 +{
143019 + int loop = 1;
143020 + while (loop--) {
143021 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
143022 + qman_test_hotpotato();
143023 +#endif
143024 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
143025 + qman_test_high();
143026 +#endif
143027 + }
143028 + return 0;
143029 +}
143030 +
143031 +static void test_exit(void)
143032 +{
143033 +}
143034 +
143035 +module_init(test_init);
143036 +module_exit(test_exit);
143037 --- /dev/null
143038 +++ b/drivers/staging/fsl_qbman/qman_test.h
143039 @@ -0,0 +1,45 @@
143040 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143041 + *
143042 + * Redistribution and use in source and binary forms, with or without
143043 + * modification, are permitted provided that the following conditions are met:
143044 + * * Redistributions of source code must retain the above copyright
143045 + * notice, this list of conditions and the following disclaimer.
143046 + * * Redistributions in binary form must reproduce the above copyright
143047 + * notice, this list of conditions and the following disclaimer in the
143048 + * documentation and/or other materials provided with the distribution.
143049 + * * Neither the name of Freescale Semiconductor nor the
143050 + * names of its contributors may be used to endorse or promote products
143051 + * derived from this software without specific prior written permission.
143052 + *
143053 + *
143054 + * ALTERNATIVELY, this software may be distributed under the terms of the
143055 + * GNU General Public License ("GPL") as published by the Free Software
143056 + * Foundation, either version 2 of that License or (at your option) any
143057 + * later version.
143058 + *
143059 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143060 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143061 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143062 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143063 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143064 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143065 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143066 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143067 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143068 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143069 + */
143070 +
143071 +#include <linux/kernel.h>
143072 +#include <linux/errno.h>
143073 +#include <linux/io.h>
143074 +#include <linux/slab.h>
143075 +#include <linux/module.h>
143076 +#include <linux/interrupt.h>
143077 +#include <linux/delay.h>
143078 +#include <linux/sched.h>
143079 +
143080 +#include <linux/fsl_qman.h>
143081 +
143082 +void qman_test_hotpotato(void);
143083 +void qman_test_high(void);
143084 +
143085 --- /dev/null
143086 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
143087 @@ -0,0 +1,216 @@
143088 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143089 + *
143090 + * Redistribution and use in source and binary forms, with or without
143091 + * modification, are permitted provided that the following conditions are met:
143092 + * * Redistributions of source code must retain the above copyright
143093 + * notice, this list of conditions and the following disclaimer.
143094 + * * Redistributions in binary form must reproduce the above copyright
143095 + * notice, this list of conditions and the following disclaimer in the
143096 + * documentation and/or other materials provided with the distribution.
143097 + * * Neither the name of Freescale Semiconductor nor the
143098 + * names of its contributors may be used to endorse or promote products
143099 + * derived from this software without specific prior written permission.
143100 + *
143101 + *
143102 + * ALTERNATIVELY, this software may be distributed under the terms of the
143103 + * GNU General Public License ("GPL") as published by the Free Software
143104 + * Foundation, either version 2 of that License or (at your option) any
143105 + * later version.
143106 + *
143107 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143108 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143109 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143110 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143111 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143112 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143113 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143114 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143115 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143116 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143117 + */
143118 +
143119 +#include "qman_test.h"
143120 +
143121 +/*************/
143122 +/* constants */
143123 +/*************/
143124 +
143125 +#define CGR_ID 27
143126 +#define POOL_ID 2
143127 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
143128 +#define NUM_ENQUEUES 10
143129 +#define NUM_PARTIAL 4
143130 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
143131 + QM_SDQCR_TYPE_PRIO_QOS | \
143132 + QM_SDQCR_TOKEN_SET(0x98) | \
143133 + QM_SDQCR_CHANNELS_DEDICATED | \
143134 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
143135 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
143136 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
143137 +
143138 +/*************************************/
143139 +/* Predeclarations (eg. for fq_base) */
143140 +/*************************************/
143141 +
143142 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
143143 + struct qman_fq *,
143144 + const struct qm_dqrr_entry *);
143145 +static void cb_ern(struct qman_portal *, struct qman_fq *,
143146 + const struct qm_mr_entry *);
143147 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
143148 + const struct qm_mr_entry *);
143149 +
143150 +/***************/
143151 +/* global vars */
143152 +/***************/
143153 +
143154 +static struct qm_fd fd, fd_dq;
143155 +static struct qman_fq fq_base = {
143156 + .cb.dqrr = cb_dqrr,
143157 + .cb.ern = cb_ern,
143158 + .cb.fqs = cb_fqs
143159 +};
143160 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
143161 +static int retire_complete, sdqcr_complete;
143162 +
143163 +/**********************/
143164 +/* internal functions */
143165 +/**********************/
143166 +
143167 +/* Helpers for initialising and "incrementing" a frame descriptor */
143168 +static void fd_init(struct qm_fd *__fd)
143169 +{
143170 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
143171 + __fd->format = qm_fd_contig_big;
143172 + __fd->length29 = 0x0000ffff;
143173 + __fd->cmd = 0xfeedf00d;
143174 +}
143175 +
143176 +static void fd_inc(struct qm_fd *__fd)
143177 +{
143178 + u64 t = qm_fd_addr_get64(__fd);
143179 + int z = t >> 40;
143180 + t <<= 1;
143181 + if (z)
143182 + t |= 1;
143183 + qm_fd_addr_set64(__fd, t);
143184 + __fd->length29--;
143185 + __fd->cmd++;
143186 +}
143187 +
143188 +/* The only part of the 'fd' we can't memcmp() is the ppid */
143189 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
143190 +{
143191 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
143192 + if (!r)
143193 + r = a->format - b->format;
143194 + if (!r)
143195 + r = a->opaque - b->opaque;
143196 + if (!r)
143197 + r = a->cmd - b->cmd;
143198 + return r;
143199 +}
143200 +
143201 +/********/
143202 +/* test */
143203 +/********/
143204 +
143205 +static void do_enqueues(struct qman_fq *fq)
143206 +{
143207 + unsigned int loop;
143208 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
143209 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
143210 + (((loop + 1) == NUM_ENQUEUES) ?
143211 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
143212 + panic("qman_enqueue() failed\n");
143213 + fd_inc(&fd);
143214 + }
143215 +}
143216 +
143217 +void qman_test_high(void)
143218 +{
143219 + unsigned int flags;
143220 + int res;
143221 + struct qman_fq *fq = &fq_base;
143222 +
143223 + pr_info("qman_test_high starting\n");
143224 + fd_init(&fd);
143225 + fd_init(&fd_dq);
143226 +
143227 + /* Initialise (parked) FQ */
143228 + if (qman_create_fq(0, FQ_FLAGS, fq))
143229 + panic("qman_create_fq() failed\n");
143230 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
143231 + panic("qman_init_fq() failed\n");
143232 +
143233 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
143234 + do_enqueues(fq);
143235 + pr_info("VDQCR (till-empty);\n");
143236 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143237 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
143238 + panic("qman_volatile_dequeue() failed\n");
143239 + do_enqueues(fq);
143240 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
143241 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143242 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
143243 + panic("qman_volatile_dequeue() failed\n");
143244 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
143245 + NUM_ENQUEUES);
143246 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143247 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
143248 + panic("qman_volatile_dequeue() failed\n");
143249 +
143250 + do_enqueues(fq);
143251 + pr_info("scheduled dequeue (till-empty)\n");
143252 + if (qman_schedule_fq(fq))
143253 + panic("qman_schedule_fq() failed\n");
143254 + wait_event(waitqueue, sdqcr_complete);
143255 +
143256 + /* Retire and OOS the FQ */
143257 + res = qman_retire_fq(fq, &flags);
143258 + if (res < 0)
143259 + panic("qman_retire_fq() failed\n");
143260 + wait_event(waitqueue, retire_complete);
143261 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
143262 + panic("leaking frames\n");
143263 + if (qman_oos_fq(fq))
143264 + panic("qman_oos_fq() failed\n");
143265 + qman_destroy_fq(fq, 0);
143266 + pr_info("qman_test_high finished\n");
143267 +}
143268 +
143269 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
143270 + struct qman_fq *fq,
143271 + const struct qm_dqrr_entry *dq)
143272 +{
143273 + if (fd_cmp(&fd_dq, &dq->fd)) {
143274 + pr_err("BADNESS: dequeued frame doesn't match;\n");
143275 + pr_err("Expected 0x%llx, got 0x%llx\n",
143276 + (unsigned long long)fd_dq.length29,
143277 + (unsigned long long)dq->fd.length29);
143278 + BUG();
143279 + }
143280 + fd_inc(&fd_dq);
143281 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
143282 + sdqcr_complete = 1;
143283 + wake_up(&waitqueue);
143284 + }
143285 + return qman_cb_dqrr_consume;
143286 +}
143287 +
143288 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
143289 + const struct qm_mr_entry *msg)
143290 +{
143291 + panic("cb_ern() unimplemented");
143292 +}
143293 +
143294 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
143295 + const struct qm_mr_entry *msg)
143296 +{
143297 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
143298 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
143299 + panic("unexpected FQS message");
143300 + pr_info("Retirement message received\n");
143301 + retire_complete = 1;
143302 + wake_up(&waitqueue);
143303 +}
143304 --- /dev/null
143305 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
143306 @@ -0,0 +1,502 @@
143307 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
143308 + *
143309 + * Redistribution and use in source and binary forms, with or without
143310 + * modification, are permitted provided that the following conditions are met:
143311 + * * Redistributions of source code must retain the above copyright
143312 + * notice, this list of conditions and the following disclaimer.
143313 + * * Redistributions in binary form must reproduce the above copyright
143314 + * notice, this list of conditions and the following disclaimer in the
143315 + * documentation and/or other materials provided with the distribution.
143316 + * * Neither the name of Freescale Semiconductor nor the
143317 + * names of its contributors may be used to endorse or promote products
143318 + * derived from this software without specific prior written permission.
143319 + *
143320 + *
143321 + * ALTERNATIVELY, this software may be distributed under the terms of the
143322 + * GNU General Public License ("GPL") as published by the Free Software
143323 + * Foundation, either version 2 of that License or (at your option) any
143324 + * later version.
143325 + *
143326 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143327 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143328 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143329 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143330 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143331 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143332 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143333 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143334 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143335 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143336 + */
143337 +
143338 +#include <linux/kthread.h>
143339 +#include <linux/platform_device.h>
143340 +#include <linux/dma-mapping.h>
143341 +#include "qman_test.h"
143342 +
143343 +/* Algorithm:
143344 + *
143345 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
143346 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
143347 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
143348 + * shuttle a "hot potato" frame around them such that every forwarding action
143349 + * moves it from one cpu to another. (The use of more than one handler per cpu
143350 + * is to allow enough handlers/FQs to truly test the significance of caching -
143351 + * ie. when cache-expiries are occurring.)
143352 + *
143353 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
143354 + * first and last words of the frame data will undergo a transformation step on
143355 + * each forwarding action. To achieve this, each handler will be assigned a
143356 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
143357 + * received by a handler, the mixer of the expected sender is XOR'd into all
143358 + * words of the entire frame, which is then validated against the original
143359 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
143360 + * the current handler. Apart from validating that the frame is taking the
143361 + * expected path, this also provides some quasi-realistic overheads to each
143362 + * forwarding action - dereferencing *all* the frame data, computation, and
143363 + * conditional branching. There is a "special" handler designated to act as the
143364 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
143365 + * to determine when the test has completed by counting HP_LOOPS iterations.
143366 + *
143367 + * Init phases:
143368 + *
143369 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
143370 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
143371 + * handlers and link-list them (but do no other handler setup).
143372 + *
143373 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143374 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143375 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
143376 + * and advance the iterator for the next loop. This includes a final fixup,
143377 + * which connects the last handler to the first (and which is why phase 2
143378 + * and 3 are separate).
143379 + *
143380 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143381 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143382 + * initialise FQ objects and advance the iterator for the next loop.
143383 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
143384 + * initialisation targets the correct cpu.
143385 + */
143386 +
143387 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
143388 + * the fn from irq context, which is too restrictive). */
143389 +struct bstrap {
143390 + void (*fn)(void);
143391 + atomic_t started;
143392 +};
143393 +static int bstrap_fn(void *__bstrap)
143394 +{
143395 + struct bstrap *bstrap = __bstrap;
143396 + atomic_inc(&bstrap->started);
143397 + bstrap->fn();
143398 + while (!kthread_should_stop())
143399 + msleep(1);
143400 + return 0;
143401 +}
143402 +static int on_all_cpus(void (*fn)(void))
143403 +{
143404 + int cpu;
143405 + for_each_cpu(cpu, cpu_online_mask) {
143406 + struct bstrap bstrap = {
143407 + .fn = fn,
143408 + .started = ATOMIC_INIT(0)
143409 + };
143410 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
143411 + "hotpotato%d", cpu);
143412 + int ret;
143413 + if (IS_ERR(k))
143414 + return -ENOMEM;
143415 + kthread_bind(k, cpu);
143416 + wake_up_process(k);
143417 + /* If we call kthread_stop() before the "wake up" has had an
143418 + * effect, then the thread may exit with -EINTR without ever
143419 + * running the function. So poll until it's started before
143420 + * requesting it to stop. */
143421 + while (!atomic_read(&bstrap.started))
143422 + msleep(10);
143423 + ret = kthread_stop(k);
143424 + if (ret)
143425 + return ret;
143426 + }
143427 + return 0;
143428 +}
143429 +
143430 +struct hp_handler {
143431 +
143432 + /* The following data is stashed when 'rx' is dequeued; */
143433 + /* -------------- */
143434 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
143435 + struct qman_fq rx;
143436 + /* The Tx FQ we should forward to */
143437 + struct qman_fq tx;
143438 + /* The value we XOR post-dequeue, prior to validating */
143439 + u32 rx_mixer;
143440 + /* The value we XOR pre-enqueue, after validating */
143441 + u32 tx_mixer;
143442 + /* what the hotpotato address should be on dequeue */
143443 + dma_addr_t addr;
143444 + u32 *frame_ptr;
143445 +
143446 + /* The following data isn't (necessarily) stashed on dequeue; */
143447 + /* -------------- */
143448 + u32 fqid_rx, fqid_tx;
143449 + /* list node for linking us into 'hp_cpu' */
143450 + struct list_head node;
143451 + /* Just to check ... */
143452 + unsigned int processor_id;
143453 +} ____cacheline_aligned;
143454 +
143455 +struct hp_cpu {
143456 + /* identify the cpu we run on; */
143457 + unsigned int processor_id;
143458 + /* root node for the per-cpu list of handlers */
143459 + struct list_head handlers;
143460 + /* list node for linking us into 'hp_cpu_list' */
143461 + struct list_head node;
143462 + /* when repeatedly scanning 'hp_list', each time linking the n'th
143463 + * handlers together, this is used as per-cpu iterator state */
143464 + struct hp_handler *iterator;
143465 +};
143466 +
143467 +/* Each cpu has one of these */
143468 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
143469 +
143470 +/* links together the hp_cpu structs, in first-come first-serve order. */
143471 +static LIST_HEAD(hp_cpu_list);
143472 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
143473 +
143474 +static unsigned int hp_cpu_list_length;
143475 +
143476 +/* the "special" handler, that starts and terminates the test. */
143477 +static struct hp_handler *special_handler;
143478 +static int loop_counter;
143479 +
143480 +/* handlers are allocated out of this, so they're properly aligned. */
143481 +static struct kmem_cache *hp_handler_slab;
143482 +
143483 +/* this is the frame data */
143484 +static void *__frame_ptr;
143485 +static u32 *frame_ptr;
143486 +static dma_addr_t frame_dma;
143487 +
143488 +/* the main function waits on this */
143489 +static DECLARE_WAIT_QUEUE_HEAD(queue);
143490 +
143491 +#define HP_PER_CPU 2
143492 +#define HP_LOOPS 8
143493 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
143494 +#define HP_NUM_WORDS 80
143495 +/* First word of the LFSR-based frame data */
143496 +#define HP_FIRST_WORD 0xabbaf00d
143497 +
143498 +static inline u32 do_lfsr(u32 prev)
143499 +{
143500 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
143501 +}
143502 +
143503 +static void allocate_frame_data(void)
143504 +{
143505 + u32 lfsr = HP_FIRST_WORD;
143506 + int loop;
143507 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
143508 + if (!pdev)
143509 + panic("platform_device_alloc() failed");
143510 + if (platform_device_add(pdev))
143511 + panic("platform_device_add() failed");
143512 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
143513 + if (!__frame_ptr)
143514 + panic("kmalloc() failed");
143515 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
143516 + ~(unsigned long)63);
143517 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
143518 + frame_ptr[loop] = lfsr;
143519 + lfsr = do_lfsr(lfsr);
143520 + }
143521 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
143522 + DMA_BIDIRECTIONAL);
143523 + platform_device_del(pdev);
143524 + platform_device_put(pdev);
143525 +}
143526 +
143527 +static void deallocate_frame_data(void)
143528 +{
143529 + kfree(__frame_ptr);
143530 +}
143531 +
143532 +static inline void process_frame_data(struct hp_handler *handler,
143533 + const struct qm_fd *fd)
143534 +{
143535 + u32 *p = handler->frame_ptr;
143536 + u32 lfsr = HP_FIRST_WORD;
143537 + int loop;
143538 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
143539 + pr_err("Got 0x%llx expected 0x%llx\n",
143540 + qm_fd_addr_get64(fd), handler->addr);
143541 + panic("bad frame address");
143542 + }
143543 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
143544 + *p ^= handler->rx_mixer;
143545 + if (*p != lfsr)
143546 + panic("corrupt frame data");
143547 + *p ^= handler->tx_mixer;
143548 + lfsr = do_lfsr(lfsr);
143549 + }
143550 +}
143551 +
143552 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
143553 + struct qman_fq *fq,
143554 + const struct qm_dqrr_entry *dqrr)
143555 +{
143556 + struct hp_handler *handler = (struct hp_handler *)fq;
143557 +
143558 + process_frame_data(handler, &dqrr->fd);
143559 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
143560 + panic("qman_enqueue() failed");
143561 + return qman_cb_dqrr_consume;
143562 +}
143563 +
143564 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
143565 + struct qman_fq *fq,
143566 + const struct qm_dqrr_entry *dqrr)
143567 +{
143568 + struct hp_handler *handler = (struct hp_handler *)fq;
143569 +
143570 + process_frame_data(handler, &dqrr->fd);
143571 + if (++loop_counter < HP_LOOPS) {
143572 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
143573 + panic("qman_enqueue() failed");
143574 + } else {
143575 + pr_info("Received final (%dth) frame\n", loop_counter);
143576 + wake_up(&queue);
143577 + }
143578 + return qman_cb_dqrr_consume;
143579 +}
143580 +
143581 +static void create_per_cpu_handlers(void)
143582 +{
143583 + struct hp_handler *handler;
143584 + int loop;
143585 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
143586 +
143587 + hp_cpu->processor_id = smp_processor_id();
143588 + spin_lock(&hp_lock);
143589 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
143590 + hp_cpu_list_length++;
143591 + spin_unlock(&hp_lock);
143592 + INIT_LIST_HEAD(&hp_cpu->handlers);
143593 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143594 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
143595 + if (!handler)
143596 + panic("kmem_cache_alloc() failed");
143597 + handler->processor_id = hp_cpu->processor_id;
143598 + handler->addr = frame_dma;
143599 + handler->frame_ptr = frame_ptr;
143600 + list_add_tail(&handler->node, &hp_cpu->handlers);
143601 + }
143602 + put_cpu_var(hp_cpus);
143603 +}
143604 +
143605 +static void destroy_per_cpu_handlers(void)
143606 +{
143607 + struct list_head *loop, *tmp;
143608 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
143609 +
143610 + spin_lock(&hp_lock);
143611 + list_del(&hp_cpu->node);
143612 + spin_unlock(&hp_lock);
143613 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
143614 + u32 flags;
143615 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
143616 + node);
143617 + if (qman_retire_fq(&handler->rx, &flags))
143618 + panic("qman_retire_fq(rx) failed");
143619 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
143620 + if (qman_oos_fq(&handler->rx))
143621 + panic("qman_oos_fq(rx) failed");
143622 + qman_destroy_fq(&handler->rx, 0);
143623 + qman_destroy_fq(&handler->tx, 0);
143624 + qman_release_fqid(handler->fqid_rx);
143625 + list_del(&handler->node);
143626 + kmem_cache_free(hp_handler_slab, handler);
143627 + }
143628 + put_cpu_var(hp_cpus);
143629 +}
143630 +
143631 +static inline u8 num_cachelines(u32 offset)
143632 +{
143633 + u8 res = (offset + (L1_CACHE_BYTES - 1))
143634 + / (L1_CACHE_BYTES);
143635 + if (res > 3)
143636 + return 3;
143637 + return res;
143638 +}
143639 +#define STASH_DATA_CL \
143640 + num_cachelines(HP_NUM_WORDS * 4)
143641 +#define STASH_CTX_CL \
143642 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
143643 +
143644 +static void init_handler(void *__handler)
143645 +{
143646 + struct qm_mcc_initfq opts;
143647 + struct hp_handler *handler = __handler;
143648 + BUG_ON(handler->processor_id != smp_processor_id());
143649 + /* Set up rx */
143650 + memset(&handler->rx, 0, sizeof(handler->rx));
143651 + if (handler == special_handler)
143652 + handler->rx.cb.dqrr = special_dqrr;
143653 + else
143654 + handler->rx.cb.dqrr = normal_dqrr;
143655 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
143656 + panic("qman_create_fq(rx) failed");
143657 + memset(&opts, 0, sizeof(opts));
143658 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
143659 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
143660 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
143661 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
143662 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
143663 + QMAN_INITFQ_FLAG_LOCAL, &opts))
143664 + panic("qman_init_fq(rx) failed");
143665 + /* Set up tx */
143666 + memset(&handler->tx, 0, sizeof(handler->tx));
143667 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
143668 + &handler->tx))
143669 + panic("qman_create_fq(tx) failed");
143670 +}
143671 +
143672 +static void init_phase2(void)
143673 +{
143674 + int loop;
143675 + u32 fqid = 0;
143676 + u32 lfsr = 0xdeadbeef;
143677 + struct hp_cpu *hp_cpu;
143678 + struct hp_handler *handler;
143679 +
143680 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143681 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
143682 + int ret;
143683 + if (!loop)
143684 + hp_cpu->iterator = list_first_entry(
143685 + &hp_cpu->handlers,
143686 + struct hp_handler, node);
143687 + else
143688 + hp_cpu->iterator = list_entry(
143689 + hp_cpu->iterator->node.next,
143690 + struct hp_handler, node);
143691 + /* Rx FQID is the previous handler's Tx FQID */
143692 + hp_cpu->iterator->fqid_rx = fqid;
143693 + /* Allocate new FQID for Tx */
143694 + ret = qman_alloc_fqid(&fqid);
143695 + if (ret)
143696 + panic("qman_alloc_fqid() failed");
143697 + hp_cpu->iterator->fqid_tx = fqid;
143698 + /* Rx mixer is the previous handler's Tx mixer */
143699 + hp_cpu->iterator->rx_mixer = lfsr;
143700 + /* Get new mixer for Tx */
143701 + lfsr = do_lfsr(lfsr);
143702 + hp_cpu->iterator->tx_mixer = lfsr;
143703 + }
143704 + }
143705 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
143706 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
143707 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
143708 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
143709 + handler->fqid_rx = fqid;
143710 + handler->rx_mixer = lfsr;
143711 + /* and tag it as our "special" handler */
143712 + special_handler = handler;
143713 +}
143714 +
143715 +static void init_phase3(void)
143716 +{
143717 + int loop;
143718 + struct hp_cpu *hp_cpu;
143719 +
143720 + for (loop = 0; loop < HP_PER_CPU; loop++) {
143721 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
143722 + if (!loop)
143723 + hp_cpu->iterator = list_first_entry(
143724 + &hp_cpu->handlers,
143725 + struct hp_handler, node);
143726 + else
143727 + hp_cpu->iterator = list_entry(
143728 + hp_cpu->iterator->node.next,
143729 + struct hp_handler, node);
143730 + preempt_disable();
143731 + if (hp_cpu->processor_id == smp_processor_id())
143732 + init_handler(hp_cpu->iterator);
143733 + else
143734 + smp_call_function_single(hp_cpu->processor_id,
143735 + init_handler, hp_cpu->iterator, 1);
143736 + preempt_enable();
143737 + }
143738 + }
143739 +}
143740 +
143741 +static void send_first_frame(void *ignore)
143742 +{
143743 + u32 *p = special_handler->frame_ptr;
143744 + u32 lfsr = HP_FIRST_WORD;
143745 + int loop;
143746 + struct qm_fd fd;
143747 +
143748 + BUG_ON(special_handler->processor_id != smp_processor_id());
143749 + memset(&fd, 0, sizeof(fd));
143750 + qm_fd_addr_set64(&fd, special_handler->addr);
143751 + fd.format = qm_fd_contig_big;
143752 + fd.length29 = HP_NUM_WORDS * 4;
143753 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
143754 + if (*p != lfsr)
143755 + panic("corrupt frame data");
143756 + *p ^= special_handler->tx_mixer;
143757 + lfsr = do_lfsr(lfsr);
143758 + }
143759 + pr_info("Sending first frame\n");
143760 + if (qman_enqueue(&special_handler->tx, &fd, 0))
143761 + panic("qman_enqueue() failed");
143762 +}
143763 +
143764 +void qman_test_hotpotato(void)
143765 +{
143766 + if (cpumask_weight(cpu_online_mask) < 2) {
143767 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
143768 + return;
143769 + }
143770 +
143771 + pr_info("qman_test_hotpotato starting\n");
143772 +
143773 + hp_cpu_list_length = 0;
143774 + loop_counter = 0;
143775 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
143776 + sizeof(struct hp_handler), L1_CACHE_BYTES,
143777 + SLAB_HWCACHE_ALIGN, NULL);
143778 + if (!hp_handler_slab)
143779 + panic("kmem_cache_create() failed");
143780 +
143781 + allocate_frame_data();
143782 +
143783 + /* Init phase 1 */
143784 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
143785 + if (on_all_cpus(create_per_cpu_handlers))
143786 + panic("on_each_cpu() failed");
143787 + pr_info("Number of cpus: %d, total of %d handlers\n",
143788 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
143789 +
143790 + init_phase2();
143791 +
143792 + init_phase3();
143793 +
143794 + preempt_disable();
143795 + if (special_handler->processor_id == smp_processor_id())
143796 + send_first_frame(NULL);
143797 + else
143798 + smp_call_function_single(special_handler->processor_id,
143799 + send_first_frame, NULL, 1);
143800 + preempt_enable();
143801 +
143802 + wait_event(queue, loop_counter == HP_LOOPS);
143803 + deallocate_frame_data();
143804 + if (on_all_cpus(destroy_per_cpu_handlers))
143805 + panic("on_each_cpu() failed");
143806 + kmem_cache_destroy(hp_handler_slab);
143807 + pr_info("qman_test_hotpotato finished\n");
143808 +}
143809 --- /dev/null
143810 +++ b/drivers/staging/fsl_qbman/qman_utility.c
143811 @@ -0,0 +1,129 @@
143812 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143813 + *
143814 + * Redistribution and use in source and binary forms, with or without
143815 + * modification, are permitted provided that the following conditions are met:
143816 + * * Redistributions of source code must retain the above copyright
143817 + * notice, this list of conditions and the following disclaimer.
143818 + * * Redistributions in binary form must reproduce the above copyright
143819 + * notice, this list of conditions and the following disclaimer in the
143820 + * documentation and/or other materials provided with the distribution.
143821 + * * Neither the name of Freescale Semiconductor nor the
143822 + * names of its contributors may be used to endorse or promote products
143823 + * derived from this software without specific prior written permission.
143824 + *
143825 + *
143826 + * ALTERNATIVELY, this software may be distributed under the terms of the
143827 + * GNU General Public License ("GPL") as published by the Free Software
143828 + * Foundation, either version 2 of that License or (at your option) any
143829 + * later version.
143830 + *
143831 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143832 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143833 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143834 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143835 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143836 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143837 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143838 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143839 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143840 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143841 + */
143842 +
143843 +#include "qman_private.h"
143844 +
143845 +/* ----------------- */
143846 +/* --- FQID Pool --- */
143847 +
143848 +struct qman_fqid_pool {
143849 + /* Base and size of the FQID range */
143850 + u32 fqid_base;
143851 + u32 total;
143852 + /* Number of FQIDs currently "allocated" */
143853 + u32 used;
143854 + /* Allocation optimisation. When 'used<total', it is the index of an
143855 + * available FQID. Otherwise there are no available FQIDs, and this
143856 + * will be set when the next deallocation occurs. */
143857 + u32 next;
143858 + /* A bit-field representation of the FQID range. */
143859 + unsigned long *bits;
143860 +};
143861 +
143862 +#define QLONG_BYTES sizeof(unsigned long)
143863 +#define QLONG_BITS (QLONG_BYTES * 8)
143864 +/* Number of 'longs' required for the given number of bits */
143865 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
143866 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
143867 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
143868 +/* And in bits */
143869 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
143870 +
143871 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
143872 +{
143873 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
143874 + unsigned int i;
143875 +
143876 + BUG_ON(!num);
143877 + if (!pool)
143878 + return NULL;
143879 + pool->fqid_base = fqid_start;
143880 + pool->total = num;
143881 + pool->used = 0;
143882 + pool->next = 0;
143883 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
143884 + if (!pool->bits) {
143885 + kfree(pool);
143886 + return NULL;
143887 + }
143888 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
143889 + * byte-oriented searching) then we fill the trailing bits with 1, to
143890 + * make them look allocated (permanently). */
143891 + for (i = num + 1; i < QNUM_BITS(num); i++)
143892 + set_bit(i, pool->bits);
143893 + return pool;
143894 +}
143895 +EXPORT_SYMBOL(qman_fqid_pool_create);
143896 +
143897 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
143898 +{
143899 + int ret = pool->used;
143900 + kfree(pool->bits);
143901 + kfree(pool);
143902 + return ret;
143903 +}
143904 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
143905 +
143906 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
143907 +{
143908 + int ret;
143909 + if (pool->used == pool->total)
143910 + return -ENOMEM;
143911 + *fqid = pool->fqid_base + pool->next;
143912 + ret = test_and_set_bit(pool->next, pool->bits);
143913 + BUG_ON(ret);
143914 + if (++pool->used == pool->total)
143915 + return 0;
143916 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
143917 + if (pool->next >= pool->total)
143918 + pool->next = find_first_zero_bit(pool->bits, pool->total);
143919 + BUG_ON(pool->next >= pool->total);
143920 + return 0;
143921 +}
143922 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
143923 +
143924 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
143925 +{
143926 + int ret;
143927 +
143928 + fqid -= pool->fqid_base;
143929 + ret = test_and_clear_bit(fqid, pool->bits);
143930 + BUG_ON(!ret);
143931 + if (pool->used-- == pool->total)
143932 + pool->next = fqid;
143933 +}
143934 +EXPORT_SYMBOL(qman_fqid_pool_free);
143935 +
143936 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
143937 +{
143938 + return pool->used;
143939 +}
143940 +EXPORT_SYMBOL(qman_fqid_pool_used);
143941 --- /dev/null
143942 +++ b/include/linux/fsl_bman.h
143943 @@ -0,0 +1,532 @@
143944 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
143945 + *
143946 + * Redistribution and use in source and binary forms, with or without
143947 + * modification, are permitted provided that the following conditions are met:
143948 + * * Redistributions of source code must retain the above copyright
143949 + * notice, this list of conditions and the following disclaimer.
143950 + * * Redistributions in binary form must reproduce the above copyright
143951 + * notice, this list of conditions and the following disclaimer in the
143952 + * documentation and/or other materials provided with the distribution.
143953 + * * Neither the name of Freescale Semiconductor nor the
143954 + * names of its contributors may be used to endorse or promote products
143955 + * derived from this software without specific prior written permission.
143956 + *
143957 + *
143958 + * ALTERNATIVELY, this software may be distributed under the terms of the
143959 + * GNU General Public License ("GPL") as published by the Free Software
143960 + * Foundation, either version 2 of that License or (at your option) any
143961 + * later version.
143962 + *
143963 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143964 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143965 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143966 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143967 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143968 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143969 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143970 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143971 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143972 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143973 + */
143974 +
143975 +#ifndef FSL_BMAN_H
143976 +#define FSL_BMAN_H
143977 +
143978 +#ifdef __cplusplus
143979 +extern "C" {
143980 +#endif
143981 +
143982 +/* Last updated for v00.79 of the BG */
143983 +
143984 +/* Portal processing (interrupt) sources */
143985 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
143986 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
143987 +
143988 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
143989 + * buffer pools. */
143990 +struct bman_depletion {
143991 + u32 __state[2];
143992 +};
143993 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
143994 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
143995 +#define __bmdep_word(x) ((x) >> 5)
143996 +#define __bmdep_shift(x) ((x) & 0x1f)
143997 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
143998 +static inline void bman_depletion_init(struct bman_depletion *c)
143999 +{
144000 + c->__state[0] = c->__state[1] = 0;
144001 +}
144002 +static inline void bman_depletion_fill(struct bman_depletion *c)
144003 +{
144004 + c->__state[0] = c->__state[1] = ~0;
144005 +}
144006 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
144007 +{
144008 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
144009 +}
144010 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
144011 +{
144012 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
144013 +}
144014 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
144015 +{
144016 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
144017 +}
144018 +
144019 +/* ------------------------------------------------------- */
144020 +/* --- Bman data structures (and associated constants) --- */
144021 +
144022 +/* Represents s/w corenet portal mapped data structures */
144023 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
144024 +struct bm_mc_command; /* MC (Management Command) command */
144025 +struct bm_mc_result; /* MC result */
144026 +
144027 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
144028 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
144029 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
144030 +struct bm_buffer {
144031 + union {
144032 + struct {
144033 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144034 + u8 __reserved1;
144035 + u8 bpid;
144036 + u16 hi; /* High 16-bits of 48-bit address */
144037 + u32 lo; /* Low 32-bits of 48-bit address */
144038 +#else
144039 + u32 lo;
144040 + u16 hi;
144041 + u8 bpid;
144042 + u8 __reserved;
144043 +#endif
144044 + };
144045 + struct {
144046 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144047 + u64 __notaddress:16;
144048 + u64 addr:48;
144049 +#else
144050 + u64 addr:48;
144051 + u64 __notaddress:16;
144052 +#endif
144053 + };
144054 + u64 opaque;
144055 + };
144056 +} __aligned(8);
144057 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
144058 +{
144059 + return buf->addr;
144060 +}
144061 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
144062 +{
144063 + return (dma_addr_t)buf->addr;
144064 +}
144065 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144066 +#define bm_buffer_set64(buf, v) \
144067 + do { \
144068 + struct bm_buffer *__buf931 = (buf); \
144069 + __buf931->hi = upper_32_bits(v); \
144070 + __buf931->lo = lower_32_bits(v); \
144071 + } while (0)
144072 +
144073 +/* See 1.5.3.5.4: "Release Command" */
144074 +struct bm_rcr_entry {
144075 + union {
144076 + struct {
144077 + u8 __dont_write_directly__verb;
144078 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
144079 + u8 __reserved1[62];
144080 + };
144081 + struct bm_buffer bufs[8];
144082 + };
144083 +} __packed;
144084 +#define BM_RCR_VERB_VBIT 0x80
144085 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
144086 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
144087 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
144088 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
144089 +
144090 +/* See 1.5.3.1: "Acquire Command" */
144091 +/* See 1.5.3.2: "Query Command" */
144092 +struct bm_mcc_acquire {
144093 + u8 bpid;
144094 + u8 __reserved1[62];
144095 +} __packed;
144096 +struct bm_mcc_query {
144097 + u8 __reserved2[63];
144098 +} __packed;
144099 +struct bm_mc_command {
144100 + u8 __dont_write_directly__verb;
144101 + union {
144102 + struct bm_mcc_acquire acquire;
144103 + struct bm_mcc_query query;
144104 + };
144105 +} __packed;
144106 +#define BM_MCC_VERB_VBIT 0x80
144107 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
144108 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
144109 +#define BM_MCC_VERB_CMD_QUERY 0x40
144110 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
144111 +
144112 +/* See 1.5.3.3: "Acquire Response" */
144113 +/* See 1.5.3.4: "Query Response" */
144114 +struct bm_pool_state {
144115 + u8 __reserved1[32];
144116 + /* "availability state" and "depletion state" */
144117 + struct {
144118 + u8 __reserved1[8];
144119 + /* Access using bman_depletion_***() */
144120 + struct bman_depletion state;
144121 + } as, ds;
144122 +};
144123 +struct bm_mc_result {
144124 + union {
144125 + struct {
144126 + u8 verb;
144127 + u8 __reserved1[63];
144128 + };
144129 + union {
144130 + struct {
144131 + u8 __reserved1;
144132 + u8 bpid;
144133 + u8 __reserved2[62];
144134 + };
144135 + struct bm_buffer bufs[8];
144136 + } acquire;
144137 + struct bm_pool_state query;
144138 + };
144139 +} __packed;
144140 +#define BM_MCR_VERB_VBIT 0x80
144141 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
144142 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
144143 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
144144 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
144145 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
144146 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
144147 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
144148 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
144149 + bman_depletion_get(&r->query.as.state, p)
144150 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
144151 +#define BM_MCR_QUERY_DEPLETION(r, p) \
144152 + bman_depletion_get(&r->query.ds.state, p)
144153 +
144154 +/*******************************************************************/
144155 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
144156 +/*******************************************************************/
144157 +
144158 + /* Portal and Buffer Pools */
144159 + /* ----------------------- */
144160 +/* Represents a managed portal */
144161 +struct bman_portal;
144162 +
144163 +/* This object type represents Bman buffer pools. */
144164 +struct bman_pool;
144165 +
144166 +struct bman_portal_config {
144167 + /* This is used for any "core-affine" portals, ie. default portals
144168 + * associated to the corresponding cpu. -1 implies that there is no core
144169 + * affinity configured. */
144170 + int cpu;
144171 + /* portal interrupt line */
144172 + int irq;
144173 + /* the unique index of this portal */
144174 + u32 index;
144175 + /* Is this portal shared? (If so, it has coarser locking and demuxes
144176 + * processing on behalf of other CPUs.) */
144177 + int is_shared;
144178 + /* These are the buffer pool IDs that may be used via this portal. */
144179 + struct bman_depletion mask;
144180 +};
144181 +
144182 +/* This callback type is used when handling pool depletion entry/exit. The
144183 + * 'cb_ctx' value is the opaque value associated with the pool object in
144184 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
144185 + * depletion-exit. */
144186 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
144187 + struct bman_pool *pool, void *cb_ctx, int depleted);
144188 +
144189 +/* This struct specifies parameters for a bman_pool object. */
144190 +struct bman_pool_params {
144191 + /* index of the buffer pool to encapsulate (0-63), ignored if
144192 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
144193 + u32 bpid;
144194 + /* bit-mask of BMAN_POOL_FLAG_*** options */
144195 + u32 flags;
144196 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
144197 + bman_cb_depletion cb;
144198 + /* opaque user value passed as a parameter to 'cb' */
144199 + void *cb_ctx;
144200 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
144201 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
144202 + * when run in the control plane (which controls Bman CCSR). This array
144203 + * matches the definition of bm_pool_set(). */
144204 + u32 thresholds[4];
144205 +};
144206 +
144207 +/* Flags to bman_new_pool() */
144208 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
144209 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
144210 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
144211 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
144212 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
144213 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
144214 +
144215 +/* Flags to bman_release() */
144216 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
144217 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
144218 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
144219 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
144220 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
144221 +#endif
144222 +#endif
144223 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
144224 +
144225 +/* Flags to bman_acquire() */
144226 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
144227 +
144228 + /* Portal Management */
144229 + /* ----------------- */
144230 +/**
144231 + * bman_get_portal_config - get portal configuration settings
144232 + *
144233 + * This returns a read-only view of the current cpu's affine portal settings.
144234 + */
144235 +const struct bman_portal_config *bman_get_portal_config(void);
144236 +
144237 +/**
144238 + * bman_irqsource_get - return the portal work that is interrupt-driven
144239 + *
144240 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
144241 + * enabled for interrupt handling on the current cpu's affine portal. These
144242 + * sources will trigger the portal interrupt and the interrupt handler (or a
144243 + * tasklet/bottom-half it defers to) will perform the corresponding processing
144244 + * work. The bman_poll_***() functions will only process sources that are not in
144245 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
144246 + * this always returns zero.
144247 + */
144248 +u32 bman_irqsource_get(void);
144249 +
144250 +/**
144251 + * bman_irqsource_add - add processing sources to be interrupt-driven
144252 + * @bits: bitmask of BM_PIRQ_**I processing sources
144253 + *
144254 + * Adds processing sources that should be interrupt-driven (rather than
144255 + * processed via bman_poll_***() functions). Returns zero for success, or
144256 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144257 +int bman_irqsource_add(u32 bits);
144258 +
144259 +/**
144260 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
144261 + * @bits: bitmask of BM_PIRQ_**I processing sources
144262 + *
144263 + * Removes processing sources from being interrupt-driven, so that they will
144264 + * instead be processed via bman_poll_***() functions. Returns zero for success,
144265 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144266 +int bman_irqsource_remove(u32 bits);
144267 +
144268 +/**
144269 + * bman_affine_cpus - return a mask of cpus that have affine portals
144270 + */
144271 +const cpumask_t *bman_affine_cpus(void);
144272 +
144273 +/**
144274 + * bman_poll_slow - process anything that isn't interrupt-driven.
144275 + *
144276 + * This function does any portal processing that isn't interrupt-driven. If the
144277 + * current CPU is sharing a portal hosted on another CPU, this function will
144278 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
144279 + * indicating what interrupt sources were actually processed by the call.
144280 + *
144281 + * NB, unlike the legacy wrapper bman_poll(), this function will
144282 + * deterministically check for the presence of portal processing work and do it,
144283 + * which implies some latency even if there's nothing to do. The bman_poll()
144284 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
144285 + * checking for (and doing) portal processing infrequently. Ie. such that
144286 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
144287 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
144288 + * processing.
144289 + */
144290 +u32 bman_poll_slow(void);
144291 +
144292 +/**
144293 + * bman_poll - process anything that isn't interrupt-driven.
144294 + *
144295 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
144296 + * affine portal. This function does whatever processing is not triggered by
144297 + * interrupts. This is a legacy wrapper that can be used in core-processing
144298 + * loops but mitigates the performance overhead of portal processing by
144299 + * adaptively bypassing true portal processing most of the time. (Processing is
144300 + * done once every 10 calls if the previous processing revealed that work needed
144301 + * to be done, or once very 1000 calls if the previous processing revealed no
144302 + * work needed doing.) If you wish to control this yourself, call
144303 + * bman_poll_slow() instead, which always checks for portal processing work.
144304 + */
144305 +void bman_poll(void);
144306 +
144307 +/**
144308 + * bman_rcr_is_empty - Determine if portal's RCR is empty
144309 + *
144310 + * For use in situations where a cpu-affine caller needs to determine when all
144311 + * releases for the local portal have been processed by Bman but can't use the
144312 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
144313 + * The function forces tracking of RCR consumption (which normally doesn't
144314 + * happen until release processing needs to find space to put new release
144315 + * commands), and returns zero if the ring still has unprocessed entries,
144316 + * non-zero if it is empty.
144317 + */
144318 +int bman_rcr_is_empty(void);
144319 +
144320 +/**
144321 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
144322 + * @result: is set by the API to the base BPID of the allocated range
144323 + * @count: the number of BPIDs required
144324 + * @align: required alignment of the allocated range
144325 + * @partial: non-zero if the API can return fewer than @count BPIDs
144326 + *
144327 + * Returns the number of buffer pools allocated, or a negative error code. If
144328 + * @partial is non zero, the allocation request may return a smaller range of
144329 + * BPs than requested (though alignment will be as requested). If @partial is
144330 + * zero, the return value will either be 'count' or negative.
144331 + */
144332 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
144333 +static inline int bman_alloc_bpid(u32 *result)
144334 +{
144335 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
144336 + return (ret > 0) ? 0 : ret;
144337 +}
144338 +
144339 +/**
144340 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
144341 + * @bpid: the base BPID of the range to deallocate
144342 + * @count: the number of BPIDs in the range
144343 + *
144344 + * This function can also be used to seed the allocator with ranges of BPIDs
144345 + * that it can subsequently allocate from.
144346 + */
144347 +void bman_release_bpid_range(u32 bpid, unsigned int count);
144348 +static inline void bman_release_bpid(u32 bpid)
144349 +{
144350 + bman_release_bpid_range(bpid, 1);
144351 +}
144352 +
144353 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
144354 +static inline int bman_reserve_bpid(u32 bpid)
144355 +{
144356 + return bman_reserve_bpid_range(bpid, 1);
144357 +}
144358 +
144359 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
144360 +
144361 +
144362 +int bman_shutdown_pool(u32 bpid);
144363 +
144364 + /* Pool management */
144365 + /* --------------- */
144366 +/**
144367 + * bman_new_pool - Allocates a Buffer Pool object
144368 + * @params: parameters specifying the buffer pool ID and behaviour
144369 + *
144370 + * Creates a pool object for the given @params. A portal and the depletion
144371 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
144372 + * is set. NB, the fields from @params are copied into the new pool object, so
144373 + * the structure provided by the caller can be released or reused after the
144374 + * function returns.
144375 + */
144376 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
144377 +
144378 +/**
144379 + * bman_free_pool - Deallocates a Buffer Pool object
144380 + * @pool: the pool object to release
144381 + *
144382 + */
144383 +void bman_free_pool(struct bman_pool *pool);
144384 +
144385 +/**
144386 + * bman_get_params - Returns a pool object's parameters.
144387 + * @pool: the pool object
144388 + *
144389 + * The returned pointer refers to state within the pool object so must not be
144390 + * modified and can no longer be read once the pool object is destroyed.
144391 + */
144392 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
144393 +
144394 +/**
144395 + * bman_release - Release buffer(s) to the buffer pool
144396 + * @pool: the buffer pool object to release to
144397 + * @bufs: an array of buffers to release
144398 + * @num: the number of buffers in @bufs (1-8)
144399 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144400 + *
144401 + * Adds the given buffers to RCR entries. If the portal @p was created with the
144402 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
144403 + * utilisation of RCR. As such, these buffers may join an existing ring entry
144404 + * and/or it may not be issued right away so as to allow future releases to join
144405 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
144406 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
144407 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
144408 + * is selected, in which case it will sleep waiting for space to become
144409 + * available in RCR. If the function receives a signal before such time (and
144410 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
144411 + * it returns zero.
144412 + */
144413 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
144414 + u32 flags);
144415 +
144416 +/**
144417 + * bman_acquire - Acquire buffer(s) from a buffer pool
144418 + * @pool: the buffer pool object to acquire from
144419 + * @bufs: array for storing the acquired buffers
144420 + * @num: the number of buffers desired (@bufs is at least this big)
144421 + *
144422 + * Issues an "Acquire" command via the portal's management command interface.
144423 + * The return value will be the number of buffers obtained from the pool, or a
144424 + * negative error code if a h/w error or pool starvation was encountered. In
144425 + * the latter case, the content of @bufs is undefined.
144426 + */
144427 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
144428 + u32 flags);
144429 +
144430 +/**
144431 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
144432 + * @pool: the buffer pool object the stockpile belongs
144433 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144434 + *
144435 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
144436 + * The return value will be a negative error code if a h/w error occurred.
144437 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
144438 + * -EAGAIN will be returned.
144439 + */
144440 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
144441 +
144442 +/**
144443 + * bman_query_pools - Query all buffer pool states
144444 + * @state: storage for the queried availability and depletion states
144445 + */
144446 +int bman_query_pools(struct bm_pool_state *state);
144447 +
144448 +#ifdef CONFIG_FSL_BMAN_CONFIG
144449 +/**
144450 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
144451 + * @pool: the buffer pool object to query
144452 + *
144453 + * Return the number of the free buffers
144454 + */
144455 +u32 bman_query_free_buffers(struct bman_pool *pool);
144456 +
144457 +/**
144458 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
144459 + * @pool: the buffer pool object to which the thresholds will be set
144460 + * @thresholds: the new thresholds
144461 + */
144462 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
144463 +#endif
144464 +
144465 +/**
144466 + * The below bman_p_***() variant might be called in a situation that the cpu
144467 + * which the portal affine to is not online yet.
144468 + * @bman_portal specifies which portal the API will use.
144469 +*/
144470 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
144471 +#ifdef __cplusplus
144472 +}
144473 +#endif
144474 +
144475 +#endif /* FSL_BMAN_H */
144476 --- /dev/null
144477 +++ b/include/linux/fsl_qman.h
144478 @@ -0,0 +1,3888 @@
144479 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144480 + *
144481 + * Redistribution and use in source and binary forms, with or without
144482 + * modification, are permitted provided that the following conditions are met:
144483 + * * Redistributions of source code must retain the above copyright
144484 + * notice, this list of conditions and the following disclaimer.
144485 + * * Redistributions in binary form must reproduce the above copyright
144486 + * notice, this list of conditions and the following disclaimer in the
144487 + * documentation and/or other materials provided with the distribution.
144488 + * * Neither the name of Freescale Semiconductor nor the
144489 + * names of its contributors may be used to endorse or promote products
144490 + * derived from this software without specific prior written permission.
144491 + *
144492 + *
144493 + * ALTERNATIVELY, this software may be distributed under the terms of the
144494 + * GNU General Public License ("GPL") as published by the Free Software
144495 + * Foundation, either version 2 of that License or (at your option) any
144496 + * later version.
144497 + *
144498 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144499 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144500 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144501 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144502 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144503 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144504 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144505 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144506 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144507 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144508 + */
144509 +
144510 +#ifndef FSL_QMAN_H
144511 +#define FSL_QMAN_H
144512 +
144513 +#ifdef __cplusplus
144514 +extern "C" {
144515 +#endif
144516 +
144517 +/* Last updated for v00.800 of the BG */
144518 +
144519 +/* Hardware constants */
144520 +#define QM_CHANNEL_SWPORTAL0 0
144521 +#define QMAN_CHANNEL_POOL1 0x21
144522 +#define QMAN_CHANNEL_CAAM 0x80
144523 +#define QMAN_CHANNEL_PME 0xa0
144524 +#define QMAN_CHANNEL_POOL1_REV3 0x401
144525 +#define QMAN_CHANNEL_CAAM_REV3 0x840
144526 +#define QMAN_CHANNEL_PME_REV3 0x860
144527 +#define QMAN_CHANNEL_DCE 0x8a0
144528 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
144529 +extern u16 qm_channel_pool1;
144530 +extern u16 qm_channel_caam;
144531 +extern u16 qm_channel_pme;
144532 +extern u16 qm_channel_dce;
144533 +enum qm_dc_portal {
144534 + qm_dc_portal_fman0 = 0,
144535 + qm_dc_portal_fman1 = 1,
144536 + qm_dc_portal_caam = 2,
144537 + qm_dc_portal_pme = 3,
144538 + qm_dc_portal_rman = 4,
144539 + qm_dc_portal_dce = 5
144540 +};
144541 +
144542 +/* Portal processing (interrupt) sources */
144543 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
144544 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
144545 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
144546 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
144547 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
144548 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
144549 +/* This mask contains all the interrupt sources that need handling except DQRI,
144550 + * ie. that if present should trigger slow-path processing. */
144551 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
144552 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
144553 +
144554 +/* --- Clock speed --- */
144555 +/* A qman driver instance may or may not know the current qman clock speed.
144556 + * However, certain CEETM calculations may not be possible if this is not known.
144557 + * The 'set' function will only succeed (return zero) if the driver did not
144558 + * already know the clock speed. Likewise, the 'get' function will only succeed
144559 + * if the driver does know the clock speed (either because it knew when booting,
144560 + * or was told via 'set'). In cases where software is running on a driver
144561 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
144562 + * and the user can obtain the current qman clock speed by other means (eg. from
144563 + * a message sent from the control-plane), then the 'set' function can be used
144564 + * to enable rate-calculations in a driver where it would otherwise not be
144565 + * possible. */
144566 +int qm_get_clock(u64 *clock_hz);
144567 +int qm_set_clock(u64 clock_hz);
144568 +
144569 +/* For qman_static_dequeue_*** APIs */
144570 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
144571 +/* for n in [1,15] */
144572 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
144573 +/* for conversion from n of qm_channel */
144574 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
144575 +{
144576 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
144577 +}
144578 +
144579 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
144580 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
144581 + * FQID(n) to fill in the frame queue ID. */
144582 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
144583 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
144584 +#define QM_VDQCR_EXACT 0x40000000
144585 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
144586 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
144587 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
144588 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
144589 +
144590 +
144591 +/* ------------------------------------------------------- */
144592 +/* --- Qman data structures (and associated constants) --- */
144593 +
144594 +/* Represents s/w corenet portal mapped data structures */
144595 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
144596 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
144597 +struct qm_mr_entry; /* MR (Message Ring) entries */
144598 +struct qm_mc_command; /* MC (Management Command) command */
144599 +struct qm_mc_result; /* MC result */
144600 +
144601 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
144602 +#define QM_FD_FORMAT_SG 0x4
144603 +#define QM_FD_FORMAT_LONG 0x2
144604 +#define QM_FD_FORMAT_COMPOUND 0x1
144605 +enum qm_fd_format {
144606 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
144607 + * scatter-gather table. 'big' implies a 29-bit length with no offset
144608 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
144609 + * implies a s/g-like table, where each entry itself represents a frame
144610 + * (contiguous or scatter-gather) and the 29-bit "length" is
144611 + * interpreted purely for congestion calculations, ie. a "congestion
144612 + * weight". */
144613 + qm_fd_contig = 0,
144614 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
144615 + qm_fd_sg = QM_FD_FORMAT_SG,
144616 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
144617 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
144618 +};
144619 +
144620 +/* Capitalised versions are un-typed but can be used in static expressions */
144621 +#define QM_FD_CONTIG 0
144622 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
144623 +#define QM_FD_SG QM_FD_FORMAT_SG
144624 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
144625 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
144626 +
144627 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
144628 +struct qm_fd {
144629 + union {
144630 + struct {
144631 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144632 + u8 dd:2; /* dynamic debug */
144633 + u8 liodn_offset:6;
144634 + u8 bpid:8; /* Buffer Pool ID */
144635 + u8 eliodn_offset:4;
144636 + u8 __reserved:4;
144637 + u8 addr_hi; /* high 8-bits of 40-bit address */
144638 + u32 addr_lo; /* low 32-bits of 40-bit address */
144639 +#else
144640 + u32 addr_lo; /* low 32-bits of 40-bit address */
144641 + u8 addr_hi; /* high 8-bits of 40-bit address */
144642 + u8 __reserved:4;
144643 + u8 eliodn_offset:4;
144644 + u8 bpid:8; /* Buffer Pool ID */
144645 + u8 liodn_offset:6;
144646 + u8 dd:2; /* dynamic debug */
144647 +#endif
144648 + };
144649 + struct {
144650 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144651 + u64 __notaddress:24;
144652 + u64 addr:40;
144653 +#else
144654 + u64 addr:40;
144655 + u64 __notaddress:24;
144656 +#endif
144657 + };
144658 + u64 opaque_addr;
144659 + };
144660 + /* The 'format' field indicates the interpretation of the remaining 29
144661 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
144662 + * other union elements. Note, union'd structs are difficult to use with
144663 + * static initialisation under gcc, in which case use the "opaque" form
144664 + * with one of the macros. */
144665 + union {
144666 + /* For easier/faster copying of this part of the fd (eg. from a
144667 + * DQRR entry to an EQCR entry) copy 'opaque' */
144668 + u32 opaque;
144669 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
144670 + struct {
144671 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144672 + enum qm_fd_format format:3;
144673 + u16 offset:9;
144674 + u32 length20:20;
144675 +#else
144676 + u32 length20:20;
144677 + u16 offset:9;
144678 + enum qm_fd_format format:3;
144679 +#endif
144680 + };
144681 + /* If 'format' is _contig_big or _sg_big, 29b length */
144682 + struct {
144683 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144684 + enum qm_fd_format _format1:3;
144685 + u32 length29:29;
144686 +#else
144687 + u32 length29:29;
144688 + enum qm_fd_format _format1:3;
144689 +#endif
144690 + };
144691 + /* If 'format' is _compound, 29b "congestion weight" */
144692 + struct {
144693 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144694 + enum qm_fd_format _format2:3;
144695 + u32 cong_weight:29;
144696 +#else
144697 + u32 cong_weight:29;
144698 + enum qm_fd_format _format2:3;
144699 +#endif
144700 + };
144701 + };
144702 + union {
144703 + u32 cmd;
144704 + u32 status;
144705 + };
144706 +} __aligned(8);
144707 +#define QM_FD_DD_NULL 0x00
144708 +#define QM_FD_PID_MASK 0x3f
144709 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
144710 +{
144711 + return fd->addr;
144712 +}
144713 +
144714 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
144715 +{
144716 + return (dma_addr_t)fd->addr;
144717 +}
144718 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144719 +#define qm_fd_addr_set64(fd, v) \
144720 + do { \
144721 + struct qm_fd *__fd931 = (fd); \
144722 + __fd931->addr = v; \
144723 + } while (0)
144724 +
144725 +/* For static initialisation of FDs (which is complicated by the use of unions
144726 + * in "struct qm_fd"), use the following macros. Note that;
144727 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
144728 + * use-case),
144729 + * - use capitalised QM_FD_*** formats for static initialisation.
144730 + */
144731 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
144732 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
144733 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
144734 + { cmd } }
144735 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
144736 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
144737 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
144738 + { cmd } }
144739 +
144740 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
144741 +#define QM_SG_OFFSET_MASK 0x1FFF
144742 +struct qm_sg_entry {
144743 + union {
144744 + struct {
144745 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144746 + u8 __reserved1[3];
144747 + u8 addr_hi; /* high 8-bits of 40-bit address */
144748 + u32 addr_lo; /* low 32-bits of 40-bit address */
144749 +#else
144750 + u32 addr_lo; /* low 32-bits of 40-bit address */
144751 + u8 addr_hi; /* high 8-bits of 40-bit address */
144752 + u8 __reserved1[3];
144753 +#endif
144754 + };
144755 + struct {
144756 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144757 + u64 __notaddress:24;
144758 + u64 addr:40;
144759 +#else
144760 + u64 addr:40;
144761 + u64 __notaddress:24;
144762 +#endif
144763 + };
144764 + u64 opaque;
144765 + };
144766 + union {
144767 + struct {
144768 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144769 + u32 extension:1; /* Extension bit */
144770 + u32 final:1; /* Final bit */
144771 + u32 length:30;
144772 +#else
144773 + u32 length:30;
144774 + u32 final:1; /* Final bit */
144775 + u32 extension:1; /* Extension bit */
144776 +#endif
144777 + };
144778 + u32 sgt_efl;
144779 + };
144780 + u8 __reserved2;
144781 + u8 bpid;
144782 + union {
144783 + struct {
144784 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144785 + u16 __reserved3:3;
144786 + u16 offset:13;
144787 +#else
144788 + u16 offset:13;
144789 + u16 __reserved3:3;
144790 +#endif
144791 + };
144792 + u16 opaque_offset;
144793 + };
144794 +} __packed;
144795 +union qm_sg_efl {
144796 + struct {
144797 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144798 + u32 extension:1; /* Extension bit */
144799 + u32 final:1; /* Final bit */
144800 + u32 length:30;
144801 +#else
144802 + u32 length:30;
144803 + u32 final:1; /* Final bit */
144804 + u32 extension:1; /* Extension bit */
144805 +#endif
144806 + };
144807 + u32 efl;
144808 +};
144809 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
144810 +{
144811 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
144812 +}
144813 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
144814 +{
144815 + union qm_sg_efl u;
144816 +
144817 + u.efl = be32_to_cpu(sg->sgt_efl);
144818 + return u.extension;
144819 +}
144820 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
144821 +{
144822 + union qm_sg_efl u;
144823 +
144824 + u.efl = be32_to_cpu(sg->sgt_efl);
144825 + return u.final;
144826 +}
144827 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
144828 +{
144829 + union qm_sg_efl u;
144830 +
144831 + u.efl = be32_to_cpu(sg->sgt_efl);
144832 + return u.length;
144833 +}
144834 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
144835 +{
144836 + return sg->bpid;
144837 +}
144838 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
144839 +{
144840 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
144841 +
144842 + return opaque_offset & 0x1fff;
144843 +}
144844 +
144845 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144846 +#define qm_sg_entry_set64(sg, v) \
144847 + do { \
144848 + struct qm_sg_entry *__sg931 = (sg); \
144849 + __sg931->opaque = cpu_to_be64(v); \
144850 + } while (0)
144851 +#define qm_sg_entry_set_ext(sg, v) \
144852 + do { \
144853 + union qm_sg_efl __u932; \
144854 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
144855 + __u932.extension = v; \
144856 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
144857 + } while (0)
144858 +#define qm_sg_entry_set_final(sg, v) \
144859 + do { \
144860 + union qm_sg_efl __u933; \
144861 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
144862 + __u933.final = v; \
144863 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
144864 + } while (0)
144865 +#define qm_sg_entry_set_len(sg, v) \
144866 + do { \
144867 + union qm_sg_efl __u934; \
144868 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
144869 + __u934.length = v; \
144870 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
144871 + } while (0)
144872 +#define qm_sg_entry_set_bpid(sg, v) \
144873 + do { \
144874 + struct qm_sg_entry *__u935 = (sg); \
144875 + __u935->bpid = v; \
144876 + } while (0)
144877 +#define qm_sg_entry_set_offset(sg, v) \
144878 + do { \
144879 + struct qm_sg_entry *__u936 = (sg); \
144880 + __u936->opaque_offset = cpu_to_be16(v); \
144881 + } while (0)
144882 +
144883 +/* See 1.5.8.1: "Enqueue Command" */
144884 +struct qm_eqcr_entry {
144885 + u8 __dont_write_directly__verb;
144886 + u8 dca;
144887 + u16 seqnum;
144888 + u32 orp; /* 24-bit */
144889 + u32 fqid; /* 24-bit */
144890 + u32 tag;
144891 + struct qm_fd fd;
144892 + u8 __reserved3[32];
144893 +} __packed;
144894 +#define QM_EQCR_VERB_VBIT 0x80
144895 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
144896 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
144897 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
144898 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
144899 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
144900 +#define QM_EQCR_VERB_COLOUR_RED 0x10
144901 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
144902 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
144903 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
144904 +#define QM_EQCR_DCA_ENABLE 0x80
144905 +#define QM_EQCR_DCA_PARK 0x40
144906 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
144907 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
144908 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
144909 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
144910 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
144911 +
144912 +/* See 1.5.8.2: "Frame Dequeue Response" */
144913 +struct qm_dqrr_entry {
144914 + u8 verb;
144915 + u8 stat;
144916 + u16 seqnum; /* 15-bit */
144917 + u8 tok;
144918 + u8 __reserved2[3];
144919 + u32 fqid; /* 24-bit */
144920 + u32 contextB;
144921 + struct qm_fd fd;
144922 + u8 __reserved4[32];
144923 +};
144924 +#define QM_DQRR_VERB_VBIT 0x80
144925 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
144926 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
144927 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
144928 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
144929 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
144930 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
144931 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
144932 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
144933 +
144934 +/* See 1.5.8.3: "ERN Message Response" */
144935 +/* See 1.5.8.4: "FQ State Change Notification" */
144936 +struct qm_mr_entry {
144937 + u8 verb;
144938 + union {
144939 + struct {
144940 + u8 dca;
144941 + u16 seqnum;
144942 + u8 rc; /* Rejection Code */
144943 + u32 orp:24;
144944 + u32 fqid; /* 24-bit */
144945 + u32 tag;
144946 + struct qm_fd fd;
144947 + } __packed ern;
144948 + struct {
144949 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144950 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
144951 + u8 __reserved1:3;
144952 + enum qm_dc_portal portal:3;
144953 +#else
144954 + enum qm_dc_portal portal:3;
144955 + u8 __reserved1:3;
144956 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
144957 +#endif
144958 + u16 __reserved2;
144959 + u8 rc; /* Rejection Code */
144960 + u32 __reserved3:24;
144961 + u32 fqid; /* 24-bit */
144962 + u32 tag;
144963 + struct qm_fd fd;
144964 + } __packed dcern;
144965 + struct {
144966 + u8 fqs; /* Frame Queue Status */
144967 + u8 __reserved1[6];
144968 + u32 fqid; /* 24-bit */
144969 + u32 contextB;
144970 + u8 __reserved2[16];
144971 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
144972 + };
144973 + u8 __reserved2[32];
144974 +} __packed;
144975 +#define QM_MR_VERB_VBIT 0x80
144976 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
144977 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
144978 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
144979 + * the other MR types by noting if the 0x20 bit is unset. */
144980 +#define QM_MR_VERB_TYPE_MASK 0x27
144981 +#define QM_MR_VERB_DC_ERN 0x20
144982 +#define QM_MR_VERB_FQRN 0x21
144983 +#define QM_MR_VERB_FQRNI 0x22
144984 +#define QM_MR_VERB_FQRL 0x23
144985 +#define QM_MR_VERB_FQPN 0x24
144986 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
144987 +#define QM_MR_RC_CGR_TAILDROP 0x00
144988 +#define QM_MR_RC_WRED 0x10
144989 +#define QM_MR_RC_ERROR 0x20
144990 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
144991 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
144992 +#define QM_MR_RC_FQ_TAILDROP 0x50
144993 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
144994 +#define QM_MR_RC_ORP_ZERO 0x70
144995 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
144996 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
144997 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
144998 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
144999 +#define QM_MR_DCERN_COLOUR_RED 0x02
145000 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
145001 +
145002 +/* An identical structure of FQD fields is present in the "Init FQ" command and
145003 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
145004 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
145005 + * latter has two inlines to assist with converting to/from the mant+exp
145006 + * representation. */
145007 +struct qm_fqd_stashing {
145008 + /* See QM_STASHING_EXCL_<...> */
145009 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145010 + u8 exclusive;
145011 + u8 __reserved1:2;
145012 + /* Numbers of cachelines */
145013 + u8 annotation_cl:2;
145014 + u8 data_cl:2;
145015 + u8 context_cl:2;
145016 +#else
145017 + u8 context_cl:2;
145018 + u8 data_cl:2;
145019 + u8 annotation_cl:2;
145020 + u8 __reserved1:2;
145021 + u8 exclusive;
145022 +#endif
145023 +} __packed;
145024 +struct qm_fqd_taildrop {
145025 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145026 + u16 __reserved1:3;
145027 + u16 mant:8;
145028 + u16 exp:5;
145029 +#else
145030 + u16 exp:5;
145031 + u16 mant:8;
145032 + u16 __reserved1:3;
145033 +#endif
145034 +} __packed;
145035 +struct qm_fqd_oac {
145036 + /* See QM_OAC_<...> */
145037 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145038 + u8 oac:2; /* "Overhead Accounting Control" */
145039 + u8 __reserved1:6;
145040 +#else
145041 + u8 __reserved1:6;
145042 + u8 oac:2; /* "Overhead Accounting Control" */
145043 +#endif
145044 + /* Two's-complement value (-128 to +127) */
145045 + signed char oal; /* "Overhead Accounting Length" */
145046 +} __packed;
145047 +struct qm_fqd {
145048 + union {
145049 + u8 orpc;
145050 + struct {
145051 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145052 + u8 __reserved1:2;
145053 + u8 orprws:3;
145054 + u8 oa:1;
145055 + u8 olws:2;
145056 +#else
145057 + u8 olws:2;
145058 + u8 oa:1;
145059 + u8 orprws:3;
145060 + u8 __reserved1:2;
145061 +#endif
145062 + } __packed;
145063 + };
145064 + u8 cgid;
145065 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
145066 + union {
145067 + u16 dest_wq;
145068 + struct {
145069 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145070 + u16 channel:13; /* qm_channel */
145071 + u16 wq:3;
145072 +#else
145073 + u16 wq:3;
145074 + u16 channel:13; /* qm_channel */
145075 +#endif
145076 + } __packed dest;
145077 + };
145078 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145079 + u16 __reserved2:1;
145080 + u16 ics_cred:15;
145081 +#else
145082 + u16 __reserved2:1;
145083 + u16 ics_cred:15;
145084 +#endif
145085 + /* For "Initialize Frame Queue" commands, the write-enable mask
145086 + * determines whether 'td' or 'oac_init' is observed. For query
145087 + * commands, this field is always 'td', and 'oac_query' (below) reflects
145088 + * the Overhead ACcounting values. */
145089 + union {
145090 + struct qm_fqd_taildrop td;
145091 + struct qm_fqd_oac oac_init;
145092 + };
145093 + u32 context_b;
145094 + union {
145095 + /* Treat it as 64-bit opaque */
145096 + u64 opaque;
145097 + struct {
145098 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145099 + u32 hi;
145100 + u32 lo;
145101 +#else
145102 + u32 lo;
145103 + u32 hi;
145104 +#endif
145105 + };
145106 + /* Treat it as s/w portal stashing config */
145107 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145108 + struct {
145109 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145110 + struct qm_fqd_stashing stashing;
145111 + /* 48-bit address of FQ context to
145112 + * stash, must be cacheline-aligned */
145113 + u16 context_hi;
145114 + u32 context_lo;
145115 +#else
145116 + u32 context_lo;
145117 + u16 context_hi;
145118 + struct qm_fqd_stashing stashing;
145119 +#endif
145120 + } __packed;
145121 + } context_a;
145122 + struct qm_fqd_oac oac_query;
145123 +} __packed;
145124 +/* 64-bit converters for context_hi/lo */
145125 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
145126 +{
145127 + return ((u64)fqd->context_a.context_hi << 32) |
145128 + (u64)fqd->context_a.context_lo;
145129 +}
145130 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
145131 +{
145132 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
145133 +}
145134 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
145135 +{
145136 + return ((u64)fqd->context_a.hi << 32) |
145137 + (u64)fqd->context_a.lo;
145138 +}
145139 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
145140 +#define qm_fqd_stashing_set64(fqd, v) \
145141 + do { \
145142 + struct qm_fqd *__fqd931 = (fqd); \
145143 + __fqd931->context_a.context_hi = upper_32_bits(v); \
145144 + __fqd931->context_a.context_lo = lower_32_bits(v); \
145145 + } while (0)
145146 +#define qm_fqd_context_a_set64(fqd, v) \
145147 + do { \
145148 + struct qm_fqd *__fqd931 = (fqd); \
145149 + __fqd931->context_a.hi = upper_32_bits(v); \
145150 + __fqd931->context_a.lo = lower_32_bits(v); \
145151 + } while (0)
145152 +/* convert a threshold value into mant+exp representation */
145153 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
145154 + int roundup)
145155 +{
145156 + u32 e = 0;
145157 + int oddbit = 0;
145158 + if (val > 0xe0000000)
145159 + return -ERANGE;
145160 + while (val > 0xff) {
145161 + oddbit = val & 1;
145162 + val >>= 1;
145163 + e++;
145164 + if (roundup && oddbit)
145165 + val++;
145166 + }
145167 + td->exp = e;
145168 + td->mant = val;
145169 + return 0;
145170 +}
145171 +/* and the other direction */
145172 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
145173 +{
145174 + return (u32)td->mant << td->exp;
145175 +}
145176 +
145177 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
145178 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
145179 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
145180 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
145181 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
145182 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
145183 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
145184 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
145185 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
145186 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
145187 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
145188 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
145189 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
145190 +
145191 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145192 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
145193 +#define QM_STASHING_EXCL_ANNOTATION 0x04
145194 +#define QM_STASHING_EXCL_DATA 0x02
145195 +#define QM_STASHING_EXCL_CTX 0x01
145196 +
145197 +/* See 1.5.5.3: "Intra Class Scheduling" */
145198 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
145199 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
145200 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
145201 +
145202 +/* See 1.5.8.4: "FQ State Change Notification" */
145203 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
145204 + * and associated commands/responses. The WRED parameters are calculated from
145205 + * these fields as follows;
145206 + * MaxTH = MA * (2 ^ Mn)
145207 + * Slope = SA / (2 ^ Sn)
145208 + * MaxP = 4 * (Pn + 1)
145209 + */
145210 +struct qm_cgr_wr_parm {
145211 + union {
145212 + u32 word;
145213 + struct {
145214 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145215 + u32 MA:8;
145216 + u32 Mn:5;
145217 + u32 SA:7; /* must be between 64-127 */
145218 + u32 Sn:6;
145219 + u32 Pn:6;
145220 +#else
145221 + u32 Pn:6;
145222 + u32 Sn:6;
145223 + u32 SA:7; /* must be between 64-127 */
145224 + u32 Mn:5;
145225 + u32 MA:8;
145226 +#endif
145227 + } __packed;
145228 + };
145229 +} __packed;
145230 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
145231 + * management commands, this is padded to a 16-bit structure field, so that's
145232 + * how we represent it here. The congestion state threshold is calculated from
145233 + * these fields as follows;
145234 + * CS threshold = TA * (2 ^ Tn)
145235 + */
145236 +struct qm_cgr_cs_thres {
145237 + union {
145238 + u16 hword;
145239 + struct {
145240 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145241 + u16 __reserved:3;
145242 + u16 TA:8;
145243 + u16 Tn:5;
145244 +#else
145245 + u16 Tn:5;
145246 + u16 TA:8;
145247 + u16 __reserved:3;
145248 +#endif
145249 + } __packed;
145250 + };
145251 +} __packed;
145252 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
145253 + * commands and the "Query CGR" result. It's suctioned out here into its own
145254 + * struct. */
145255 +struct __qm_mc_cgr {
145256 + struct qm_cgr_wr_parm wr_parm_g;
145257 + struct qm_cgr_wr_parm wr_parm_y;
145258 + struct qm_cgr_wr_parm wr_parm_r;
145259 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
145260 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
145261 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
145262 + u8 cscn_en; /* boolean, use QM_CGR_EN */
145263 + union {
145264 + struct {
145265 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145266 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145267 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145268 +#else
145269 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145270 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145271 +#endif
145272 + };
145273 + u32 cscn_targ; /* use QM_CGR_TARG_* */
145274 + };
145275 + u8 cstd_en; /* boolean, use QM_CGR_EN */
145276 + u8 cs; /* boolean, only used in query response */
145277 + union {
145278 + /* use qm_cgr_cs_thres_set64() */
145279 + struct qm_cgr_cs_thres cs_thres;
145280 + u16 __cs_thres;
145281 + };
145282 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
145283 +} __packed;
145284 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
145285 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
145286 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
145287 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
145288 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
145289 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
145290 +/* Convert CGR thresholds to/from "cs_thres" format */
145291 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
145292 +{
145293 + return (u64)th->TA << th->Tn;
145294 +}
145295 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
145296 + int roundup)
145297 +{
145298 + u32 e = 0;
145299 + int oddbit = 0;
145300 + while (val > 0xff) {
145301 + oddbit = val & 1;
145302 + val >>= 1;
145303 + e++;
145304 + if (roundup && oddbit)
145305 + val++;
145306 + }
145307 + th->Tn = e;
145308 + th->TA = val;
145309 + return 0;
145310 +}
145311 +
145312 +/* See 1.5.8.5.1: "Initialize FQ" */
145313 +/* See 1.5.8.5.2: "Query FQ" */
145314 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
145315 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
145316 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
145317 +/* See 1.5.8.6.2: "CGR Test Write" */
145318 +/* See 1.5.8.6.3: "Query CGR" */
145319 +/* See 1.5.8.6.4: "Query Congestion Group State" */
145320 +struct qm_mcc_initfq {
145321 + u8 __reserved1;
145322 + u16 we_mask; /* Write Enable Mask */
145323 + u32 fqid; /* 24-bit */
145324 + u16 count; /* Initialises 'count+1' FQDs */
145325 + struct qm_fqd fqd; /* the FQD fields go here */
145326 + u8 __reserved3[30];
145327 +} __packed;
145328 +struct qm_mcc_queryfq {
145329 + u8 __reserved1[3];
145330 + u32 fqid; /* 24-bit */
145331 + u8 __reserved2[56];
145332 +} __packed;
145333 +struct qm_mcc_queryfq_np {
145334 + u8 __reserved1[3];
145335 + u32 fqid; /* 24-bit */
145336 + u8 __reserved2[56];
145337 +} __packed;
145338 +struct qm_mcc_alterfq {
145339 + u8 __reserved1[3];
145340 + u32 fqid; /* 24-bit */
145341 + u8 __reserved2;
145342 + u8 count; /* number of consecutive FQID */
145343 + u8 __reserved3[10];
145344 + u32 context_b; /* frame queue context b */
145345 + u8 __reserved4[40];
145346 +} __packed;
145347 +struct qm_mcc_initcgr {
145348 + u8 __reserved1;
145349 + u16 we_mask; /* Write Enable Mask */
145350 + struct __qm_mc_cgr cgr; /* CGR fields */
145351 + u8 __reserved2[2];
145352 + u8 cgid;
145353 + u8 __reserved4[32];
145354 +} __packed;
145355 +struct qm_mcc_cgrtestwrite {
145356 + u8 __reserved1[2];
145357 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145358 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145359 + u8 __reserved2[23];
145360 + u8 cgid;
145361 + u8 __reserved3[32];
145362 +} __packed;
145363 +struct qm_mcc_querycgr {
145364 + u8 __reserved1[30];
145365 + u8 cgid;
145366 + u8 __reserved2[32];
145367 +} __packed;
145368 +struct qm_mcc_querycongestion {
145369 + u8 __reserved[63];
145370 +} __packed;
145371 +struct qm_mcc_querywq {
145372 + u8 __reserved;
145373 + /* select channel if verb != QUERYWQ_DEDICATED */
145374 + union {
145375 + u16 channel_wq; /* ignores wq (3 lsbits) */
145376 + struct {
145377 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145378 + u16 id:13; /* qm_channel */
145379 + u16 __reserved1:3;
145380 +#else
145381 + u16 __reserved1:3;
145382 + u16 id:13; /* qm_channel */
145383 +#endif
145384 + } __packed channel;
145385 + };
145386 + u8 __reserved2[60];
145387 +} __packed;
145388 +
145389 +struct qm_mcc_ceetm_lfqmt_config {
145390 + u8 __reserved1[4];
145391 + u32 lfqid:24;
145392 + u8 __reserved2[2];
145393 + u16 cqid;
145394 + u8 __reserved3[2];
145395 + u16 dctidx;
145396 + u8 __reserved4[48];
145397 +} __packed;
145398 +
145399 +struct qm_mcc_ceetm_lfqmt_query {
145400 + u8 __reserved1[4];
145401 + u32 lfqid:24;
145402 + u8 __reserved2[56];
145403 +} __packed;
145404 +
145405 +struct qm_mcc_ceetm_cq_config {
145406 + u8 __reserved1;
145407 + u16 cqid;
145408 + u8 dcpid;
145409 + u8 __reserved2;
145410 + u16 ccgid;
145411 + u8 __reserved3[56];
145412 +} __packed;
145413 +
145414 +struct qm_mcc_ceetm_cq_query {
145415 + u8 __reserved1;
145416 + u16 cqid;
145417 + u8 dcpid;
145418 + u8 __reserved2[59];
145419 +} __packed;
145420 +
145421 +struct qm_mcc_ceetm_dct_config {
145422 + u8 __reserved1;
145423 + u16 dctidx;
145424 + u8 dcpid;
145425 + u8 __reserved2[15];
145426 + u32 context_b;
145427 + u64 context_a;
145428 + u8 __reserved3[32];
145429 +} __packed;
145430 +
145431 +struct qm_mcc_ceetm_dct_query {
145432 + u8 __reserved1;
145433 + u16 dctidx;
145434 + u8 dcpid;
145435 + u8 __reserved2[59];
145436 +} __packed;
145437 +
145438 +struct qm_mcc_ceetm_class_scheduler_config {
145439 + u8 __reserved1;
145440 + u16 cqcid;
145441 + u8 dcpid;
145442 + u8 __reserved2[6];
145443 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145444 + u8 gpc_reserved:1;
145445 + u8 gpc_combine_flag:1;
145446 + u8 gpc_prio_b:3;
145447 + u8 gpc_prio_a:3;
145448 +#else
145449 + u8 gpc_prio_a:3;
145450 + u8 gpc_prio_b:3;
145451 + u8 gpc_combine_flag:1;
145452 + u8 gpc_reserved:1;
145453 +#endif
145454 + u16 crem;
145455 + u16 erem;
145456 + u8 w[8];
145457 + u8 __reserved3[40];
145458 +} __packed;
145459 +
145460 +struct qm_mcc_ceetm_class_scheduler_query {
145461 + u8 __reserved1;
145462 + u16 cqcid;
145463 + u8 dcpid;
145464 + u8 __reserved2[59];
145465 +} __packed;
145466 +
145467 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
145468 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
145469 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
145470 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
145471 +#define CEETM_COMMAND_TCFC (4 << 12)
145472 +
145473 +#define CEETM_CCGRID_MASK 0x01FF
145474 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
145475 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
145476 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
145477 +#define CEETM_CCGR_CM_QUERY (0 << 14)
145478 +#define CEETM_CCGR_DN_QUERY (1 << 14)
145479 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
145480 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
145481 +
145482 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
145483 + u8 __reserved1;
145484 + u16 cid;
145485 + u8 dcpid;
145486 + union {
145487 + struct {
145488 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145489 + u8 map_shaped:1;
145490 + u8 map_reserved:4;
145491 + u8 map_lni_id:3;
145492 +#else
145493 + u8 map_lni_id:3;
145494 + u8 map_reserved:4;
145495 + u8 map_shaped:1;
145496 +#endif
145497 + u8 __reserved2[58];
145498 + } __packed channel_mapping;
145499 + struct {
145500 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145501 + u8 map_reserved:5;
145502 + u8 map_lni_id:3;
145503 +#else
145504 + u8 map_lni_id:3;
145505 + u8 map_reserved:5;
145506 +#endif
145507 + u8 __reserved2[58];
145508 + } __packed sp_mapping;
145509 + struct {
145510 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145511 + u8 cpl:1;
145512 + u8 cpl_reserved:2;
145513 + u8 oal:5;
145514 +#else
145515 + u8 oal:5;
145516 + u8 cpl_reserved:2;
145517 + u8 cpl:1;
145518 +#endif
145519 + u32 crtcr:24;
145520 + u32 ertcr:24;
145521 + u16 crtbl;
145522 + u16 ertbl;
145523 + u8 mps; /* This will be hardcoded by driver with 60 */
145524 + u8 __reserved2[47];
145525 + } __packed shaper_config;
145526 + struct {
145527 + u8 __reserved2[11];
145528 + u64 lnitcfcc;
145529 + u8 __reserved3[40];
145530 + } __packed tcfc_config;
145531 + };
145532 +} __packed;
145533 +
145534 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
145535 + u8 __reserved1;
145536 + u16 cid;
145537 + u8 dcpid;
145538 + u8 __reserved2[59];
145539 +} __packed;
145540 +
145541 +struct qm_mcc_ceetm_ccgr_config {
145542 + u8 __reserved1;
145543 + u16 ccgrid;
145544 + u8 dcpid;
145545 + u8 __reserved2;
145546 + u16 we_mask;
145547 + union {
145548 + struct {
145549 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145550 + u8 ctl_reserved:1;
145551 + u8 ctl_wr_en_g:1;
145552 + u8 ctl_wr_en_y:1;
145553 + u8 ctl_wr_en_r:1;
145554 + u8 ctl_td_en:1;
145555 + u8 ctl_td_mode:1;
145556 + u8 ctl_cscn_en:1;
145557 + u8 ctl_mode:1;
145558 +#else
145559 + u8 ctl_mode:1;
145560 + u8 ctl_cscn_en:1;
145561 + u8 ctl_td_mode:1;
145562 + u8 ctl_td_en:1;
145563 + u8 ctl_wr_en_r:1;
145564 + u8 ctl_wr_en_y:1;
145565 + u8 ctl_wr_en_g:1;
145566 + u8 ctl_reserved:1;
145567 +#endif
145568 + u8 cdv;
145569 + u16 cscn_tupd;
145570 + u8 oal;
145571 + u8 __reserved3;
145572 + struct qm_cgr_cs_thres cs_thres;
145573 + struct qm_cgr_cs_thres cs_thres_x;
145574 + struct qm_cgr_cs_thres td_thres;
145575 + struct qm_cgr_wr_parm wr_parm_g;
145576 + struct qm_cgr_wr_parm wr_parm_y;
145577 + struct qm_cgr_wr_parm wr_parm_r;
145578 + } __packed cm_config;
145579 + struct {
145580 + u8 dnc;
145581 + u8 dn0;
145582 + u8 dn1;
145583 + u64 dnba:40;
145584 + u8 __reserved3[2];
145585 + u16 dnth_0;
145586 + u8 __reserved4[2];
145587 + u16 dnth_1;
145588 + u8 __reserved5[8];
145589 + } __packed dn_config;
145590 + struct {
145591 + u8 __reserved3[3];
145592 + u64 i_cnt:40;
145593 + u8 __reserved4[16];
145594 + } __packed test_write;
145595 + };
145596 + u8 __reserved5[32];
145597 +} __packed;
145598 +
145599 +struct qm_mcc_ceetm_ccgr_query {
145600 + u8 __reserved1;
145601 + u16 ccgrid;
145602 + u8 dcpid;
145603 + u8 __reserved2[59];
145604 +} __packed;
145605 +
145606 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
145607 + u8 __reserved1;
145608 + u16 cqid;
145609 + u8 dcpid;
145610 + u8 ct;
145611 + u16 xsfdr;
145612 + u8 __reserved2[56];
145613 +} __packed;
145614 +
145615 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
145616 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
145617 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
145618 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
145619 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
145620 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
145621 +struct qm_mcc_ceetm_statistics_query_write {
145622 + u8 __reserved1;
145623 + u16 cid;
145624 + u8 dcpid;
145625 + u8 ct;
145626 + u8 __reserved2[13];
145627 + u64 frm_cnt:40;
145628 + u8 __reserved3[2];
145629 + u64 byte_cnt:48;
145630 + u8 __reserved[32];
145631 +} __packed;
145632 +
145633 +struct qm_mc_command {
145634 + u8 __dont_write_directly__verb;
145635 + union {
145636 + struct qm_mcc_initfq initfq;
145637 + struct qm_mcc_queryfq queryfq;
145638 + struct qm_mcc_queryfq_np queryfq_np;
145639 + struct qm_mcc_alterfq alterfq;
145640 + struct qm_mcc_initcgr initcgr;
145641 + struct qm_mcc_cgrtestwrite cgrtestwrite;
145642 + struct qm_mcc_querycgr querycgr;
145643 + struct qm_mcc_querycongestion querycongestion;
145644 + struct qm_mcc_querywq querywq;
145645 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
145646 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
145647 + struct qm_mcc_ceetm_cq_config cq_config;
145648 + struct qm_mcc_ceetm_cq_query cq_query;
145649 + struct qm_mcc_ceetm_dct_config dct_config;
145650 + struct qm_mcc_ceetm_dct_query dct_query;
145651 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
145652 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
145653 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
145654 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
145655 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
145656 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
145657 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
145658 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
145659 + };
145660 +} __packed;
145661 +#define QM_MCC_VERB_VBIT 0x80
145662 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
145663 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
145664 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
145665 +#define QM_MCC_VERB_QUERYFQ 0x44
145666 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
145667 +#define QM_MCC_VERB_QUERYWQ 0x46
145668 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
145669 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
145670 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
145671 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
145672 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
145673 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
145674 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
145675 +#define QM_MCC_VERB_INITCGR 0x50
145676 +#define QM_MCC_VERB_MODIFYCGR 0x51
145677 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
145678 +#define QM_MCC_VERB_QUERYCGR 0x58
145679 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
145680 +/* INITFQ-specific flags */
145681 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
145682 +#define QM_INITFQ_WE_OAC 0x0100
145683 +#define QM_INITFQ_WE_ORPC 0x0080
145684 +#define QM_INITFQ_WE_CGID 0x0040
145685 +#define QM_INITFQ_WE_FQCTRL 0x0020
145686 +#define QM_INITFQ_WE_DESTWQ 0x0010
145687 +#define QM_INITFQ_WE_ICSCRED 0x0008
145688 +#define QM_INITFQ_WE_TDTHRESH 0x0004
145689 +#define QM_INITFQ_WE_CONTEXTB 0x0002
145690 +#define QM_INITFQ_WE_CONTEXTA 0x0001
145691 +/* INITCGR/MODIFYCGR-specific flags */
145692 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
145693 +#define QM_CGR_WE_WR_PARM_G 0x0400
145694 +#define QM_CGR_WE_WR_PARM_Y 0x0200
145695 +#define QM_CGR_WE_WR_PARM_R 0x0100
145696 +#define QM_CGR_WE_WR_EN_G 0x0080
145697 +#define QM_CGR_WE_WR_EN_Y 0x0040
145698 +#define QM_CGR_WE_WR_EN_R 0x0020
145699 +#define QM_CGR_WE_CSCN_EN 0x0010
145700 +#define QM_CGR_WE_CSCN_TARG 0x0008
145701 +#define QM_CGR_WE_CSTD_EN 0x0004
145702 +#define QM_CGR_WE_CS_THRES 0x0002
145703 +#define QM_CGR_WE_MODE 0x0001
145704 +
145705 +/* See 1.5.9.7 CEETM Management Commands */
145706 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
145707 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
145708 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
145709 +#define QM_CEETM_VERB_CQ_QUERY 0x73
145710 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
145711 +#define QM_CEETM_VERB_DCT_QUERY 0x75
145712 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
145713 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
145714 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
145715 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
145716 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
145717 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
145718 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
145719 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
145720 +
145721 +/* See 1.5.8.5.1: "Initialize FQ" */
145722 +/* See 1.5.8.5.2: "Query FQ" */
145723 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
145724 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
145725 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
145726 +/* See 1.5.8.6.2: "CGR Test Write" */
145727 +/* See 1.5.8.6.3: "Query CGR" */
145728 +/* See 1.5.8.6.4: "Query Congestion Group State" */
145729 +struct qm_mcr_initfq {
145730 + u8 __reserved1[62];
145731 +} __packed;
145732 +struct qm_mcr_queryfq {
145733 + u8 __reserved1[8];
145734 + struct qm_fqd fqd; /* the FQD fields are here */
145735 + u8 __reserved2[30];
145736 +} __packed;
145737 +struct qm_mcr_queryfq_np {
145738 + u8 __reserved1;
145739 + u8 state; /* QM_MCR_NP_STATE_*** */
145740 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145741 + u8 __reserved2;
145742 + u32 fqd_link:24;
145743 + u16 __reserved3:2;
145744 + u16 odp_seq:14;
145745 + u16 __reserved4:2;
145746 + u16 orp_nesn:14;
145747 + u16 __reserved5:1;
145748 + u16 orp_ea_hseq:15;
145749 + u16 __reserved6:1;
145750 + u16 orp_ea_tseq:15;
145751 + u8 __reserved7;
145752 + u32 orp_ea_hptr:24;
145753 + u8 __reserved8;
145754 + u32 orp_ea_tptr:24;
145755 + u8 __reserved9;
145756 + u32 pfdr_hptr:24;
145757 + u8 __reserved10;
145758 + u32 pfdr_tptr:24;
145759 + u8 __reserved11[5];
145760 + u8 __reserved12:7;
145761 + u8 is:1;
145762 + u16 ics_surp;
145763 + u32 byte_cnt;
145764 + u8 __reserved13;
145765 + u32 frm_cnt:24;
145766 + u32 __reserved14;
145767 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
145768 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
145769 + u16 __reserved15;
145770 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
145771 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
145772 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
145773 +#else
145774 + u8 __reserved2;
145775 + u32 fqd_link:24;
145776 +
145777 + u16 odp_seq:14;
145778 + u16 __reserved3:2;
145779 +
145780 + u16 orp_nesn:14;
145781 + u16 __reserved4:2;
145782 +
145783 + u16 orp_ea_hseq:15;
145784 + u16 __reserved5:1;
145785 +
145786 + u16 orp_ea_tseq:15;
145787 + u16 __reserved6:1;
145788 +
145789 + u8 __reserved7;
145790 + u32 orp_ea_hptr:24;
145791 +
145792 + u8 __reserved8;
145793 + u32 orp_ea_tptr:24;
145794 +
145795 + u8 __reserved9;
145796 + u32 pfdr_hptr:24;
145797 +
145798 + u8 __reserved10;
145799 + u32 pfdr_tptr:24;
145800 +
145801 + u8 __reserved11[5];
145802 + u8 is:1;
145803 + u8 __reserved12:7;
145804 + u16 ics_surp;
145805 + u32 byte_cnt;
145806 + u8 __reserved13;
145807 + u32 frm_cnt:24;
145808 + u32 __reserved14;
145809 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
145810 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
145811 + u16 __reserved15;
145812 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
145813 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
145814 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
145815 +#endif
145816 +} __packed;
145817 +
145818 +
145819 +struct qm_mcr_alterfq {
145820 + u8 fqs; /* Frame Queue Status */
145821 + u8 __reserved1[61];
145822 +} __packed;
145823 +struct qm_mcr_initcgr {
145824 + u8 __reserved1[62];
145825 +} __packed;
145826 +struct qm_mcr_cgrtestwrite {
145827 + u16 __reserved1;
145828 + struct __qm_mc_cgr cgr; /* CGR fields */
145829 + u8 __reserved2[3];
145830 + u32 __reserved3:24;
145831 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145832 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145833 + u32 __reserved4:24;
145834 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
145835 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
145836 + u16 lgt; /* Last Group Tick */
145837 + u16 wr_prob_g;
145838 + u16 wr_prob_y;
145839 + u16 wr_prob_r;
145840 + u8 __reserved5[8];
145841 +} __packed;
145842 +struct qm_mcr_querycgr {
145843 + u16 __reserved1;
145844 + struct __qm_mc_cgr cgr; /* CGR fields */
145845 + u8 __reserved2[3];
145846 + union {
145847 + struct {
145848 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145849 + u32 __reserved3:24;
145850 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145851 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145852 +#else
145853 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145854 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145855 + u32 __reserved3:24;
145856 +#endif
145857 + };
145858 + u64 i_bcnt;
145859 + };
145860 + union {
145861 + struct {
145862 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145863 + u32 __reserved4:24;
145864 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
145865 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
145866 +#else
145867 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
145868 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
145869 + u32 __reserved4:24;
145870 +#endif
145871 + };
145872 + u64 a_bcnt;
145873 + };
145874 + union {
145875 + u32 cscn_targ_swp[4];
145876 + u8 __reserved5[16];
145877 + };
145878 +} __packed;
145879 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
145880 +{
145881 + return be64_to_cpu(q->i_bcnt);
145882 +}
145883 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
145884 +{
145885 + return be64_to_cpu(q->a_bcnt);
145886 +}
145887 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
145888 + const struct qm_mcr_cgrtestwrite *q)
145889 +{
145890 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
145891 +}
145892 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
145893 + const struct qm_mcr_cgrtestwrite *q)
145894 +{
145895 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
145896 +}
145897 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145898 +#define qm_mcr_querycgr_i_set64(q, v) \
145899 + do { \
145900 + struct qm_mcr_querycgr *__q931 = (fd); \
145901 + __q931->i_bcnt_hi = upper_32_bits(v); \
145902 + __q931->i_bcnt_lo = lower_32_bits(v); \
145903 + } while (0)
145904 +#define qm_mcr_querycgr_a_set64(q, v) \
145905 + do { \
145906 + struct qm_mcr_querycgr *__q931 = (fd); \
145907 + __q931->a_bcnt_hi = upper_32_bits(v); \
145908 + __q931->a_bcnt_lo = lower_32_bits(v); \
145909 + } while (0)
145910 +struct __qm_mcr_querycongestion {
145911 + u32 __state[8];
145912 +};
145913 +struct qm_mcr_querycongestion {
145914 + u8 __reserved[30];
145915 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
145916 + struct __qm_mcr_querycongestion state;
145917 +} __packed;
145918 +struct qm_mcr_querywq {
145919 + union {
145920 + u16 channel_wq; /* ignores wq (3 lsbits) */
145921 + struct {
145922 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145923 + u16 id:13; /* qm_channel */
145924 + u16 __reserved:3;
145925 +#else
145926 + u16 __reserved:3;
145927 + u16 id:13; /* qm_channel */
145928 +#endif
145929 + } __packed channel;
145930 + };
145931 + u8 __reserved[28];
145932 + u32 wq_len[8];
145933 +} __packed;
145934 +
145935 +/* QMAN CEETM Management Command Response */
145936 +struct qm_mcr_ceetm_lfqmt_config {
145937 + u8 __reserved1[62];
145938 +} __packed;
145939 +struct qm_mcr_ceetm_lfqmt_query {
145940 + u8 __reserved1[8];
145941 + u16 cqid;
145942 + u8 __reserved2[2];
145943 + u16 dctidx;
145944 + u8 __reserved3[2];
145945 + u16 ccgid;
145946 + u8 __reserved4[44];
145947 +} __packed;
145948 +
145949 +struct qm_mcr_ceetm_cq_config {
145950 + u8 __reserved1[62];
145951 +} __packed;
145952 +
145953 +struct qm_mcr_ceetm_cq_query {
145954 + u8 __reserved1[4];
145955 + u16 ccgid;
145956 + u16 state;
145957 + u32 pfdr_hptr:24;
145958 + u32 pfdr_tptr:24;
145959 + u16 od1_xsfdr;
145960 + u16 od2_xsfdr;
145961 + u16 od3_xsfdr;
145962 + u16 od4_xsfdr;
145963 + u16 od5_xsfdr;
145964 + u16 od6_xsfdr;
145965 + u16 ra1_xsfdr;
145966 + u16 ra2_xsfdr;
145967 + u8 __reserved2;
145968 + u32 frm_cnt:24;
145969 + u8 __reserved333[28];
145970 +} __packed;
145971 +
145972 +struct qm_mcr_ceetm_dct_config {
145973 + u8 __reserved1[62];
145974 +} __packed;
145975 +
145976 +struct qm_mcr_ceetm_dct_query {
145977 + u8 __reserved1[18];
145978 + u32 context_b;
145979 + u64 context_a;
145980 + u8 __reserved2[32];
145981 +} __packed;
145982 +
145983 +struct qm_mcr_ceetm_class_scheduler_config {
145984 + u8 __reserved1[62];
145985 +} __packed;
145986 +
145987 +struct qm_mcr_ceetm_class_scheduler_query {
145988 + u8 __reserved1[9];
145989 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145990 + u8 gpc_reserved:1;
145991 + u8 gpc_combine_flag:1;
145992 + u8 gpc_prio_b:3;
145993 + u8 gpc_prio_a:3;
145994 +#else
145995 + u8 gpc_prio_a:3;
145996 + u8 gpc_prio_b:3;
145997 + u8 gpc_combine_flag:1;
145998 + u8 gpc_reserved:1;
145999 +#endif
146000 + u16 crem;
146001 + u16 erem;
146002 + u8 w[8];
146003 + u8 __reserved2[5];
146004 + u32 wbfslist:24;
146005 + u32 d8;
146006 + u32 d9;
146007 + u32 d10;
146008 + u32 d11;
146009 + u32 d12;
146010 + u32 d13;
146011 + u32 d14;
146012 + u32 d15;
146013 +} __packed;
146014 +
146015 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
146016 + u16 cid;
146017 + u8 __reserved2[60];
146018 +} __packed;
146019 +
146020 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
146021 + u16 cid;
146022 + u8 __reserved1;
146023 + union {
146024 + struct {
146025 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146026 + u8 map_shaped:1;
146027 + u8 map_reserved:4;
146028 + u8 map_lni_id:3;
146029 +#else
146030 + u8 map_lni_id:3;
146031 + u8 map_reserved:4;
146032 + u8 map_shaped:1;
146033 +#endif
146034 + u8 __reserved2[58];
146035 + } __packed channel_mapping_query;
146036 + struct {
146037 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146038 + u8 map_reserved:5;
146039 + u8 map_lni_id:3;
146040 +#else
146041 + u8 map_lni_id:3;
146042 + u8 map_reserved:5;
146043 +#endif
146044 + u8 __reserved2[58];
146045 + } __packed sp_mapping_query;
146046 + struct {
146047 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146048 + u8 cpl:1;
146049 + u8 cpl_reserved:2;
146050 + u8 oal:5;
146051 +#else
146052 + u8 oal:5;
146053 + u8 cpl_reserved:2;
146054 + u8 cpl:1;
146055 +#endif
146056 + u32 crtcr:24;
146057 + u32 ertcr:24;
146058 + u16 crtbl;
146059 + u16 ertbl;
146060 + u8 mps;
146061 + u8 __reserved2[15];
146062 + u32 crat;
146063 + u32 erat;
146064 + u8 __reserved3[24];
146065 + } __packed shaper_query;
146066 + struct {
146067 + u8 __reserved1[11];
146068 + u64 lnitcfcc;
146069 + u8 __reserved3[40];
146070 + } __packed tcfc_query;
146071 + };
146072 +} __packed;
146073 +
146074 +struct qm_mcr_ceetm_ccgr_config {
146075 + u8 __reserved1[46];
146076 + union {
146077 + u8 __reserved2[8];
146078 + struct {
146079 + u16 timestamp;
146080 + u16 wr_porb_g;
146081 + u16 wr_prob_y;
146082 + u16 wr_prob_r;
146083 + } __packed test_write;
146084 + };
146085 + u8 __reserved3[8];
146086 +} __packed;
146087 +
146088 +struct qm_mcr_ceetm_ccgr_query {
146089 + u8 __reserved1[6];
146090 + union {
146091 + struct {
146092 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146093 + u8 ctl_reserved:1;
146094 + u8 ctl_wr_en_g:1;
146095 + u8 ctl_wr_en_y:1;
146096 + u8 ctl_wr_en_r:1;
146097 + u8 ctl_td_en:1;
146098 + u8 ctl_td_mode:1;
146099 + u8 ctl_cscn_en:1;
146100 + u8 ctl_mode:1;
146101 +#else
146102 + u8 ctl_mode:1;
146103 + u8 ctl_cscn_en:1;
146104 + u8 ctl_td_mode:1;
146105 + u8 ctl_td_en:1;
146106 + u8 ctl_wr_en_r:1;
146107 + u8 ctl_wr_en_y:1;
146108 + u8 ctl_wr_en_g:1;
146109 + u8 ctl_reserved:1;
146110 +#endif
146111 + u8 cdv;
146112 + u8 __reserved2[2];
146113 + u8 oal;
146114 + u8 __reserved3;
146115 + struct qm_cgr_cs_thres cs_thres;
146116 + struct qm_cgr_cs_thres cs_thres_x;
146117 + struct qm_cgr_cs_thres td_thres;
146118 + struct qm_cgr_wr_parm wr_parm_g;
146119 + struct qm_cgr_wr_parm wr_parm_y;
146120 + struct qm_cgr_wr_parm wr_parm_r;
146121 + u16 cscn_targ_dcp;
146122 + u8 dcp_lsn;
146123 + u64 i_cnt:40;
146124 + u8 __reserved4[3];
146125 + u64 a_cnt:40;
146126 + u32 cscn_targ_swp[4];
146127 + } __packed cm_query;
146128 + struct {
146129 + u8 dnc;
146130 + u8 dn0;
146131 + u8 dn1;
146132 + u64 dnba:40;
146133 + u8 __reserved2[2];
146134 + u16 dnth_0;
146135 + u8 __reserved3[2];
146136 + u16 dnth_1;
146137 + u8 __reserved4[10];
146138 + u16 dnacc_0;
146139 + u8 __reserved5[2];
146140 + u16 dnacc_1;
146141 + u8 __reserved6[24];
146142 + } __packed dn_query;
146143 + struct {
146144 + u8 __reserved2[24];
146145 + struct __qm_mcr_querycongestion state;
146146 + } __packed congestion_state;
146147 +
146148 + };
146149 +} __packed;
146150 +
146151 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
146152 + u8 stat;
146153 + u8 __reserved1[11];
146154 + u16 dctidx;
146155 + struct qm_fd fd;
146156 + u8 __reserved2[32];
146157 +} __packed;
146158 +
146159 +struct qm_mcr_ceetm_statistics_query {
146160 + u8 __reserved1[17];
146161 + u64 frm_cnt:40;
146162 + u8 __reserved2[2];
146163 + u64 byte_cnt:48;
146164 + u8 __reserved3[32];
146165 +} __packed;
146166 +
146167 +struct qm_mc_result {
146168 + u8 verb;
146169 + u8 result;
146170 + union {
146171 + struct qm_mcr_initfq initfq;
146172 + struct qm_mcr_queryfq queryfq;
146173 + struct qm_mcr_queryfq_np queryfq_np;
146174 + struct qm_mcr_alterfq alterfq;
146175 + struct qm_mcr_initcgr initcgr;
146176 + struct qm_mcr_cgrtestwrite cgrtestwrite;
146177 + struct qm_mcr_querycgr querycgr;
146178 + struct qm_mcr_querycongestion querycongestion;
146179 + struct qm_mcr_querywq querywq;
146180 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
146181 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
146182 + struct qm_mcr_ceetm_cq_config cq_config;
146183 + struct qm_mcr_ceetm_cq_query cq_query;
146184 + struct qm_mcr_ceetm_dct_config dct_config;
146185 + struct qm_mcr_ceetm_dct_query dct_query;
146186 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
146187 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
146188 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
146189 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
146190 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
146191 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
146192 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146193 + struct qm_mcr_ceetm_statistics_query stats_query;
146194 + };
146195 +} __packed;
146196 +
146197 +#define QM_MCR_VERB_RRID 0x80
146198 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
146199 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
146200 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
146201 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
146202 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
146203 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
146204 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
146205 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
146206 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
146207 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
146208 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
146209 +#define QM_MCR_RESULT_NULL 0x00
146210 +#define QM_MCR_RESULT_OK 0xf0
146211 +#define QM_MCR_RESULT_ERR_FQID 0xf1
146212 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
146213 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
146214 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
146215 +#define QM_MCR_RESULT_PENDING 0xf8
146216 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
146217 +#define QM_MCR_NP_STATE_FE 0x10
146218 +#define QM_MCR_NP_STATE_R 0x08
146219 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
146220 +#define QM_MCR_NP_STATE_OOS 0x00
146221 +#define QM_MCR_NP_STATE_RETIRED 0x01
146222 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
146223 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
146224 +#define QM_MCR_NP_STATE_PARKED 0x04
146225 +#define QM_MCR_NP_STATE_ACTIVE 0x05
146226 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
146227 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
146228 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
146229 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
146230 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
146231 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
146232 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
146233 +/* This extracts the state for congestion group 'n' from a query response.
146234 + * Eg.
146235 + * u8 cgr = [...];
146236 + * struct qm_mc_result *res = [...];
146237 + * printf("congestion group %d congestion state: %d\n", cgr,
146238 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
146239 + */
146240 +#define __CGR_WORD(num) (num >> 5)
146241 +#define __CGR_SHIFT(num) (num & 0x1f)
146242 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
146243 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
146244 + u8 cgr)
146245 +{
146246 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
146247 +}
146248 +
146249 +
146250 +/*********************/
146251 +/* Utility interface */
146252 +/*********************/
146253 +
146254 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
146255 + * spinlock them yourself if needed. */
146256 +struct qman_fqid_pool;
146257 +
146258 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
146259 + * always succeeds, but returns non-zero if there were "leaked" FQID
146260 + * allocations. */
146261 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
146262 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
146263 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
146264 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
146265 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
146266 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
146267 +
146268 +/*******************************************************************/
146269 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
146270 +/*******************************************************************/
146271 +
146272 + /* Portal and Frame Queues */
146273 + /* ----------------------- */
146274 +/* Represents a managed portal */
146275 +struct qman_portal;
146276 +
146277 +/* This object type represents Qman frame queue descriptors (FQD), it is
146278 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
146279 + * defined further down. */
146280 +struct qman_fq;
146281 +
146282 +/* This object type represents a Qman congestion group, it is defined further
146283 + * down. */
146284 +struct qman_cgr;
146285 +
146286 +struct qman_portal_config {
146287 + /* If the caller enables DQRR stashing (and thus wishes to operate the
146288 + * portal from only one cpu), this is the logical CPU that the portal
146289 + * will stash to. Whether stashing is enabled or not, this setting is
146290 + * also used for any "core-affine" portals, ie. default portals
146291 + * associated to the corresponding cpu. -1 implies that there is no core
146292 + * affinity configured. */
146293 + int cpu;
146294 + /* portal interrupt line */
146295 + int irq;
146296 + /* the unique index of this portal */
146297 + u32 index;
146298 + /* Is this portal shared? (If so, it has coarser locking and demuxes
146299 + * processing on behalf of other CPUs.) */
146300 + int is_shared;
146301 + /* The portal's dedicated channel id, use this value for initialising
146302 + * frame queues to target this portal when scheduled. */
146303 + u16 channel;
146304 + /* A mask of which pool channels this portal has dequeue access to
146305 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
146306 + u32 pools;
146307 +};
146308 +
146309 +/* This enum, and the callback type that returns it, are used when handling
146310 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
146311 + * portal object (for handling dequeues that do not demux because contextB is
146312 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
146313 +enum qman_cb_dqrr_result {
146314 + /* DQRR entry can be consumed */
146315 + qman_cb_dqrr_consume,
146316 + /* Like _consume, but requests parking - FQ must be held-active */
146317 + qman_cb_dqrr_park,
146318 + /* Does not consume, for DCA mode only. This allows out-of-order
146319 + * consumes by explicit calls to qman_dca() and/or the use of implicit
146320 + * DCA via EQCR entries. */
146321 + qman_cb_dqrr_defer,
146322 + /* Stop processing without consuming this ring entry. Exits the current
146323 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
146324 + * interrupt handler, the callback would typically call
146325 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
146326 + * otherwise the interrupt will reassert immediately. */
146327 + qman_cb_dqrr_stop,
146328 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
146329 + qman_cb_dqrr_consume_stop
146330 +};
146331 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
146332 + struct qman_fq *fq,
146333 + const struct qm_dqrr_entry *dqrr);
146334 +
146335 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
146336 + * are always consumed after the callback returns. */
146337 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
146338 + const struct qm_mr_entry *msg);
146339 +
146340 +/* This callback type is used when handling DCP ERNs */
146341 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
146342 + const struct qm_mr_entry *msg);
146343 +
146344 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
146345 + * held-active + held-suspended are just "sched". Things like "retired" will not
146346 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
146347 + * then, to indicate it's completing and to gate attempts to retry the retire
146348 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
146349 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
146350 + * index rather than the FQ that ring entry corresponds to), so repeated park
146351 + * commands are allowed (if you're silly enough to try) but won't change FQ
146352 + * state, and the resulting park notifications move FQs from "sched" to
146353 + * "parked". */
146354 +enum qman_fq_state {
146355 + qman_fq_state_oos,
146356 + qman_fq_state_parked,
146357 + qman_fq_state_sched,
146358 + qman_fq_state_retired
146359 +};
146360 +
146361 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
146362 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
146363 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
146364 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
146365 + * they should;
146366 + *
146367 + * (a) extend the qman_fq structure with their state; eg.
146368 + *
146369 + * // myfq is allocated and driver_fq callbacks filled in;
146370 + * struct my_fq {
146371 + * struct qman_fq base;
146372 + * int an_extra_field;
146373 + * [ ... add other fields to be associated with each FQ ...]
146374 + * } *myfq = some_my_fq_allocator();
146375 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
146376 + *
146377 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
146378 + * struct my_fq *myfq = (struct my_fq *)fq;
146379 + * do_something_with(myfq->an_extra_field);
146380 + * [...]
146381 + *
146382 + * (b) when and if configuring the FQ for context stashing, specify how ever
146383 + * many cachelines are required to stash 'struct my_fq', to accelerate not
146384 + * only the Qman driver but the callback as well.
146385 + */
146386 +
146387 +struct qman_fq_cb {
146388 + qman_cb_dqrr dqrr; /* for dequeued frames */
146389 + qman_cb_mr ern; /* for s/w ERNs */
146390 + qman_cb_mr fqs; /* frame-queue state changes*/
146391 +};
146392 +
146393 +struct qman_fq {
146394 + /* Caller of qman_create_fq() provides these demux callbacks */
146395 + struct qman_fq_cb cb;
146396 + /* These are internal to the driver, don't touch. In particular, they
146397 + * may change, be removed, or extended (so you shouldn't rely on
146398 + * sizeof(qman_fq) being a constant). */
146399 + spinlock_t fqlock;
146400 + u32 fqid;
146401 + volatile unsigned long flags;
146402 + enum qman_fq_state state;
146403 + int cgr_groupid;
146404 + struct rb_node node;
146405 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
146406 + u32 key;
146407 +#endif
146408 +};
146409 +
146410 +/* This callback type is used when handling congestion group entry/exit.
146411 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
146412 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
146413 + struct qman_cgr *cgr, int congested);
146414 +
146415 +struct qman_cgr {
146416 + /* Set these prior to qman_create_cgr() */
146417 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
146418 + qman_cb_cgr cb;
146419 + /* These are private to the driver */
146420 + u16 chan; /* portal channel this object is created on */
146421 + struct list_head node;
146422 +};
146423 +
146424 +/* Flags to qman_create_fq() */
146425 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
146426 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
146427 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
146428 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
146429 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
146430 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
146431 +
146432 +/* Flags to qman_destroy_fq() */
146433 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
146434 +
146435 +/* Flags from qman_fq_state() */
146436 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
146437 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
146438 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
146439 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
146440 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
146441 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
146442 +
146443 +/* Flags to qman_init_fq() */
146444 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
146445 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
146446 +
146447 +/* Flags to qman_volatile_dequeue() */
146448 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146449 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
146450 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
146451 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
146452 +#endif
146453 +
146454 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
146455 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
146456 + * any change here should be audited in PME.) */
146457 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146458 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
146459 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
146460 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
146461 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
146462 +#endif
146463 +#endif
146464 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
146465 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
146466 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
146467 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
146468 + (((u32)(p) << 2) & 0x00000f00)
146469 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
146470 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
146471 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
146472 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
146473 +/* For the ORP-specific qman_enqueue_orp() variant;
146474 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
146475 + * of a frame. */
146476 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
146477 +/* - this flag performs no enqueue but fills in an ORP sequence number that
146478 + * would otherwise block it (eg. if a frame has been dropped). */
146479 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
146480 +/* - this flag performs no enqueue but advances NESN to the given sequence
146481 + * number. */
146482 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
146483 +
146484 +/* Flags to qman_modify_cgr() */
146485 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
146486 +#define QMAN_CGR_MODE_FRAME 0x00000001
146487 +
146488 + /* Portal Management */
146489 + /* ----------------- */
146490 +/**
146491 + * qman_get_portal_config - get portal configuration settings
146492 + *
146493 + * This returns a read-only view of the current cpu's affine portal settings.
146494 + */
146495 +const struct qman_portal_config *qman_get_portal_config(void);
146496 +
146497 +/**
146498 + * qman_irqsource_get - return the portal work that is interrupt-driven
146499 + *
146500 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
146501 + * enabled for interrupt handling on the current cpu's affine portal. These
146502 + * sources will trigger the portal interrupt and the interrupt handler (or a
146503 + * tasklet/bottom-half it defers to) will perform the corresponding processing
146504 + * work. The qman_poll_***() functions will only process sources that are not in
146505 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
146506 + * this always returns zero.
146507 + */
146508 +u32 qman_irqsource_get(void);
146509 +
146510 +/**
146511 + * qman_irqsource_add - add processing sources to be interrupt-driven
146512 + * @bits: bitmask of QM_PIRQ_**I processing sources
146513 + *
146514 + * Adds processing sources that should be interrupt-driven (rather than
146515 + * processed via qman_poll_***() functions). Returns zero for success, or
146516 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
146517 + */
146518 +int qman_irqsource_add(u32 bits);
146519 +
146520 +/**
146521 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
146522 + * @bits: bitmask of QM_PIRQ_**I processing sources
146523 + *
146524 + * Removes processing sources from being interrupt-driven, so that they will
146525 + * instead be processed via qman_poll_***() functions. Returns zero for success,
146526 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
146527 + */
146528 +int qman_irqsource_remove(u32 bits);
146529 +
146530 +/**
146531 + * qman_affine_cpus - return a mask of cpus that have affine portals
146532 + */
146533 +const cpumask_t *qman_affine_cpus(void);
146534 +
146535 +/**
146536 + * qman_affine_channel - return the channel ID of an portal
146537 + * @cpu: the cpu whose affine portal is the subject of the query
146538 + *
146539 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
146540 + * bug to call this function for any value of @cpu (other than -1) that is not a
146541 + * member of the mask returned from qman_affine_cpus().
146542 + */
146543 +u16 qman_affine_channel(int cpu);
146544 +
146545 +/**
146546 + * qman_get_affine_portal - return the portal pointer affine to cpu
146547 + * @cpu: the cpu whose affine portal is the subject of the query
146548 + *
146549 + */
146550 +void *qman_get_affine_portal(int cpu);
146551 +
146552 +/**
146553 + * qman_poll_dqrr - process DQRR (fast-path) entries
146554 + * @limit: the maximum number of DQRR entries to process
146555 + *
146556 + * Use of this function requires that DQRR processing not be interrupt-driven.
146557 + * Ie. the value returned by qman_irqsource_get() should not include
146558 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
146559 + * this function will return -EINVAL, otherwise the return value is >=0 and
146560 + * represents the number of DQRR entries processed.
146561 + */
146562 +int qman_poll_dqrr(unsigned int limit);
146563 +
146564 +/**
146565 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
146566 + *
146567 + * This function does any portal processing that isn't interrupt-driven. If the
146568 + * current CPU is sharing a portal hosted on another CPU, this function will
146569 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
146570 + * indicating what interrupt sources were actually processed by the call.
146571 + */
146572 +u32 qman_poll_slow(void);
146573 +
146574 +/**
146575 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
146576 + *
146577 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
146578 + * affine portal. There are two classes of portal processing in question;
146579 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
146580 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
146581 + * thresholds, congestion state changes, etc). This function does whatever
146582 + * processing is not triggered by interrupts.
146583 + *
146584 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
146585 + * interrupt-driven) then this function uses a heuristic to determine how often
146586 + * to run slow-path processing - as slow-path processing introduces at least a
146587 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
146588 + * close to zero-cost if there is no work to be done. Applications can tune this
146589 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
146590 + * rather than going via this wrapper.
146591 + */
146592 +void qman_poll(void);
146593 +
146594 +/**
146595 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
146596 + *
146597 + * Disables DQRR processing of the portal. This is reference-counted, so
146598 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
146599 + * truly re-enable dequeuing.
146600 + */
146601 +void qman_stop_dequeues(void);
146602 +
146603 +/**
146604 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
146605 + *
146606 + * Enables DQRR processing of the portal. This is reference-counted, so
146607 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
146608 + * truly re-enable dequeuing.
146609 + */
146610 +void qman_start_dequeues(void);
146611 +
146612 +/**
146613 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
146614 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
146615 + *
146616 + * Adds a set of pool channels to the portal's static dequeue command register
146617 + * (SDQCR). The requested pools are limited to those the portal has dequeue
146618 + * access to.
146619 + */
146620 +void qman_static_dequeue_add(u32 pools);
146621 +
146622 +/**
146623 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
146624 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
146625 + *
146626 + * Removes a set of pool channels from the portal's static dequeue command
146627 + * register (SDQCR). The requested pools are limited to those the portal has
146628 + * dequeue access to.
146629 + */
146630 +void qman_static_dequeue_del(u32 pools);
146631 +
146632 +/**
146633 + * qman_static_dequeue_get - return the portal's current SDQCR
146634 + *
146635 + * Returns the portal's current static dequeue command register (SDQCR). The
146636 + * entire register is returned, so if only the currently-enabled pool channels
146637 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
146638 + */
146639 +u32 qman_static_dequeue_get(void);
146640 +
146641 +/**
146642 + * qman_dca - Perform a Discrete Consumption Acknowledgement
146643 + * @dq: the DQRR entry to be consumed
146644 + * @park_request: indicates whether the held-active @fq should be parked
146645 + *
146646 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
146647 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
146648 + * does not take a 'portal' argument but implies the core affine portal from the
146649 + * cpu that is currently executing the function. For reasons of locking, this
146650 + * function must be called from the same CPU as that which processed the DQRR
146651 + * entry in the first place.
146652 + */
146653 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
146654 +
146655 +/**
146656 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
146657 + *
146658 + * For use in situations where a cpu-affine caller needs to determine when all
146659 + * enqueues for the local portal have been processed by Qman but can't use the
146660 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
146661 + * The function forces tracking of EQCR consumption (which normally doesn't
146662 + * happen until enqueue processing needs to find space to put new enqueue
146663 + * commands), and returns zero if the ring still has unprocessed entries,
146664 + * non-zero if it is empty.
146665 + */
146666 +int qman_eqcr_is_empty(void);
146667 +
146668 +/**
146669 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
146670 + * @handler: callback for processing DCP ERNs
146671 + * @affine: whether this handler is specific to the locally affine portal
146672 + *
146673 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
146674 + * DCP) is configured not to receive enqueue rejections, then any enqueues
146675 + * through that DCP that are rejected will be sent to a given software portal.
146676 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
146677 + * received on the portal affine to the current CPU. If multiple CPUs share a
146678 + * portal and they all call this function, they will be setting the handler for
146679 + * the same portal! If @affine is zero, then this handler will be global to all
146680 + * portals handled by this instance of the driver. Only those portals that do
146681 + * not have their own affine handler will use the global handler.
146682 + */
146683 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
146684 +
146685 + /* FQ management */
146686 + /* ------------- */
146687 +/**
146688 + * qman_create_fq - Allocates a FQ
146689 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
146690 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
146691 + * @fq: memory for storing the 'fq', with callbacks filled in
146692 + *
146693 + * Creates a frame queue object for the given @fqid, unless the
146694 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
146695 + * dynamically allocated (or the function fails if none are available). Once
146696 + * created, the caller should not touch the memory at 'fq' except as extended to
146697 + * adjacent memory for user-defined fields (see the definition of "struct
146698 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
146699 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
146700 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
146701 + * causes the driver to honour any contextB modifications requested in the
146702 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
146703 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
146704 + * software portals, the contextB field is controlled by the driver and can't be
146705 + * modified by the caller. If the AS_IS flag is specified, management commands
146706 + * will be used on portal @p to query state for frame queue @fqid and construct
146707 + * a frame queue object based on that, rather than assuming/requiring that it be
146708 + * Out of Service.
146709 + */
146710 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
146711 +
146712 +/**
146713 + * qman_destroy_fq - Deallocates a FQ
146714 + * @fq: the frame queue object to release
146715 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
146716 + *
146717 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
146718 + * not deallocated but the caller regains ownership, to do with as desired. The
146719 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
146720 + * is specified, in which case it may also be in the 'parked' state.
146721 + */
146722 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
146723 +
146724 +/**
146725 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
146726 + * @fq: the frame queue object to query
146727 + */
146728 +u32 qman_fq_fqid(struct qman_fq *fq);
146729 +
146730 +/**
146731 + * qman_fq_state - Queries the state of a FQ object
146732 + * @fq: the frame queue object to query
146733 + * @state: pointer to state enum to return the FQ scheduling state
146734 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
146735 + *
146736 + * Queries the state of the FQ object, without performing any h/w commands.
146737 + * This captures the state, as seen by the driver, at the time the function
146738 + * executes.
146739 + */
146740 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
146741 +
146742 +/**
146743 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
146744 + * @fq: the frame queue object to modify, must be 'parked' or new.
146745 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
146746 + * @opts: the FQ-modification settings, as defined in the low-level API
146747 + *
146748 + * The @opts parameter comes from the low-level portal API. Select
146749 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
146750 + * rather than parked. NB, @opts can be NULL.
146751 + *
146752 + * Note that some fields and options within @opts may be ignored or overwritten
146753 + * by the driver;
146754 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
146755 + * affects one frame queue: @fq).
146756 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
146757 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
146758 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
146759 + * initialised to a value used by the driver for demux.
146760 + * - if context_b is initialised for demux, so is context_a in case stashing
146761 + * is requested (see item 4).
146762 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
146763 + * objects.)
146764 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
146765 + * 'dest::channel' field will be overwritten to match the portal used to issue
146766 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
146767 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
146768 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
146769 + * isn't set, the destination channel/workqueue fields and the write-enable bit
146770 + * are left as-is.
146771 + * 4. if the driver overwrites context_a/b for demux, then if
146772 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
146773 + * context_a.address fields and will leave the stashing fields provided by the
146774 + * user alone, otherwise it will zero out the context_a.stashing fields.
146775 + */
146776 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
146777 +
146778 +/**
146779 + * qman_schedule_fq - Schedules a FQ
146780 + * @fq: the frame queue object to schedule, must be 'parked'
146781 + *
146782 + * Schedules the frame queue, which must be Parked, which takes it to
146783 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
146784 + */
146785 +int qman_schedule_fq(struct qman_fq *fq);
146786 +
146787 +/**
146788 + * qman_retire_fq - Retires a FQ
146789 + * @fq: the frame queue object to retire
146790 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
146791 + *
146792 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
146793 + * the retirement was started asynchronously, otherwise it returns negative for
146794 + * failure. When this function returns zero, @flags is set to indicate whether
146795 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
146796 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
146797 + * FQRN message shows up on the portal's message ring.
146798 + *
146799 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
146800 + * Active state), the completion will be via the message ring as a FQRN - but
146801 + * the corresponding callback may occur before this function returns!! Ie. the
146802 + * caller should be prepared to accept the callback as the function is called,
146803 + * not only once it has returned.
146804 + */
146805 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
146806 +
146807 +/**
146808 + * qman_oos_fq - Puts a FQ "out of service"
146809 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
146810 + *
146811 + * The frame queue must be retired and empty, and if any order restoration list
146812 + * was released as ERNs at the time of retirement, they must all be consumed.
146813 + */
146814 +int qman_oos_fq(struct qman_fq *fq);
146815 +
146816 +/**
146817 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
146818 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
146819 + * or 'retired' or 'parked' state
146820 + * @xon: boolean to set fq in XON or XOFF state
146821 + *
146822 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
146823 + * otherwise the IFSI interrupt will be asserted.
146824 + */
146825 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
146826 +
146827 +/**
146828 + * qman_query_fq - Queries FQD fields (via h/w query command)
146829 + * @fq: the frame queue object to be queried
146830 + * @fqd: storage for the queried FQD fields
146831 + */
146832 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
146833 +
146834 +/**
146835 + * qman_query_fq_np - Queries non-programmable FQD fields
146836 + * @fq: the frame queue object to be queried
146837 + * @np: storage for the queried FQD fields
146838 + */
146839 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
146840 +
146841 +/**
146842 + * qman_query_wq - Queries work queue lengths
146843 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
146844 + * to this software portal. Otherwise, query length of WQs in a
146845 + * channel specified in wq.
146846 + * @wq: storage for the queried WQs lengths. Also specified the channel to
146847 + * to query if query_dedicated is zero.
146848 + */
146849 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
146850 +
146851 +/**
146852 + * qman_volatile_dequeue - Issue a volatile dequeue command
146853 + * @fq: the frame queue object to dequeue from
146854 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
146855 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
146856 + *
146857 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
146858 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
146859 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
146860 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
146861 + * the VDQCR command has finished executing (ie. once the callback for the last
146862 + * DQRR entry resulting from the VDQCR command has been called). If not using
146863 + * the FINISH flag, completion can be determined either by detecting the
146864 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
146865 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
146866 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
146867 + * "flags" retrieved from qman_fq_state().
146868 + */
146869 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
146870 +
146871 +/**
146872 + * qman_enqueue - Enqueue a frame to a frame queue
146873 + * @fq: the frame queue object to enqueue to
146874 + * @fd: a descriptor of the frame to be enqueued
146875 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
146876 + *
146877 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
146878 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
146879 + * field is ignored. The return value is non-zero on error, such as ring full
146880 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
146881 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
146882 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
146883 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
146884 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
146885 + * perform an implied "discrete consumption acknowledgement" on the dequeue
146886 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
146887 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
146888 + * this implicit DCA can delay the release of a "held active" frame queue
146889 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
146890 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
146891 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
146892 + * acknowledgement should "park request" the "held active" frame queue. Ie.
146893 + * when the portal eventually releases that frame queue, it will be left in the
146894 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
146895 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
146896 + * is requested, and the FQ is a member of a congestion group, then this
146897 + * function returns -EAGAIN if the congestion group is currently congested.
146898 + * Note, this does not eliminate ERNs, as the async interface means we can be
146899 + * sending enqueue commands to an un-congested FQ that becomes congested before
146900 + * the enqueue commands are processed, but it does minimise needless thrashing
146901 + * of an already busy hardware resource by throttling many of the to-be-dropped
146902 + * enqueues "at the source".
146903 + */
146904 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
146905 +
146906 +typedef int (*qman_cb_precommit) (void *arg);
146907 +/**
146908 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
146909 + * @fq: the frame queue object to enqueue to
146910 + * @fd: a descriptor of the frame to be enqueued
146911 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
146912 + * @cb: user supplied callback function to invoke before writing commit verb.
146913 + * @cb_arg: callback function argument
146914 + *
146915 + * This is similar to qman_enqueue except that it will invoke a user supplied
146916 + * callback function just before writng the commit verb. This is useful
146917 + * when the user want to do something *just before* enqueuing the request and
146918 + * the enqueue can't fail.
146919 + */
146920 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
146921 + u32 flags, qman_cb_precommit cb, void *cb_arg);
146922 +
146923 +/**
146924 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
146925 + * @fq: the frame queue object to enqueue to
146926 + * @fd: a descriptor of the frame to be enqueued
146927 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
146928 + * @orp: the frame queue object used as an order restoration point.
146929 + * @orp_seqnum: the sequence number of this frame in the order restoration path
146930 + *
146931 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
146932 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
146933 + * enqueue operation to employ order restoration. Each frame queue object acts
146934 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
146935 + * with an incrementing sequence number, this value is generally ignored unless
146936 + * that sequence of dequeued frames will need order restoration later. Each
146937 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
146938 + * is a re-assembly context for re-ordering frames relative to their sequence
146939 + * numbers as they are enqueued. The ORP does not have to be within the frame
146940 + * queue that receives the enqueued frame, in fact it is usually the frame
146941 + * queue from which the frames were originally dequeued. For the purposes of
146942 + * order restoration, multiple frames (or "fragments") can be enqueued for a
146943 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
146944 + * enqueues except the final fragment of a given sequence number. Ordering
146945 + * between sequence numbers is guaranteed, even if fragments of different
146946 + * sequence numbers are interlaced with one another. Fragments of the same
146947 + * sequence number will retain the order in which they are enqueued. If no
146948 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
146949 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
146950 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
146951 + * sequence number should become the ORP's "Next Expected Sequence Number".
146952 + *
146953 + * Side note: a frame queue object can be used purely as an ORP, without
146954 + * carrying any frames at all. Care should be taken not to deallocate a frame
146955 + * queue object that is being actively used as an ORP, as a future allocation
146956 + * of the frame queue object may start using the internal ORP before the
146957 + * previous use has finished.
146958 + */
146959 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
146960 + struct qman_fq *orp, u16 orp_seqnum);
146961 +
146962 +/**
146963 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
146964 + * @result: is set by the API to the base FQID of the allocated range
146965 + * @count: the number of FQIDs required
146966 + * @align: required alignment of the allocated range
146967 + * @partial: non-zero if the API can return fewer than @count FQIDs
146968 + *
146969 + * Returns the number of frame queues allocated, or a negative error code. If
146970 + * @partial is non zero, the allocation request may return a smaller range of
146971 + * FQs than requested (though alignment will be as requested). If @partial is
146972 + * zero, the return value will either be 'count' or negative.
146973 + */
146974 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
146975 +static inline int qman_alloc_fqid(u32 *result)
146976 +{
146977 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
146978 + return (ret > 0) ? 0 : ret;
146979 +}
146980 +
146981 +/**
146982 + * qman_release_fqid_range - Release the specified range of frame queue IDs
146983 + * @fqid: the base FQID of the range to deallocate
146984 + * @count: the number of FQIDs in the range
146985 + *
146986 + * This function can also be used to seed the allocator with ranges of FQIDs
146987 + * that it can subsequently allocate from.
146988 + */
146989 +void qman_release_fqid_range(u32 fqid, unsigned int count);
146990 +static inline void qman_release_fqid(u32 fqid)
146991 +{
146992 + qman_release_fqid_range(fqid, 1);
146993 +}
146994 +
146995 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
146996 +
146997 +
146998 +int qman_shutdown_fq(u32 fqid);
146999 +
147000 +/**
147001 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
147002 + * @fqid: the base FQID of the range to deallocate
147003 + * @count: the number of FQIDs in the range
147004 + */
147005 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
147006 +static inline int qman_reserve_fqid(u32 fqid)
147007 +{
147008 + return qman_reserve_fqid_range(fqid, 1);
147009 +}
147010 +
147011 + /* Pool-channel management */
147012 + /* ----------------------- */
147013 +/**
147014 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
147015 + * @result: is set by the API to the base pool-channel ID of the allocated range
147016 + * @count: the number of pool-channel IDs required
147017 + * @align: required alignment of the allocated range
147018 + * @partial: non-zero if the API can return fewer than @count
147019 + *
147020 + * Returns the number of pool-channel IDs allocated, or a negative error code.
147021 + * If @partial is non zero, the allocation request may return a smaller range of
147022 + * than requested (though alignment will be as requested). If @partial is zero,
147023 + * the return value will either be 'count' or negative.
147024 + */
147025 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
147026 +static inline int qman_alloc_pool(u32 *result)
147027 +{
147028 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
147029 + return (ret > 0) ? 0 : ret;
147030 +}
147031 +
147032 +/**
147033 + * qman_release_pool_range - Release the specified range of pool-channel IDs
147034 + * @id: the base pool-channel ID of the range to deallocate
147035 + * @count: the number of pool-channel IDs in the range
147036 + */
147037 +void qman_release_pool_range(u32 id, unsigned int count);
147038 +static inline void qman_release_pool(u32 id)
147039 +{
147040 + qman_release_pool_range(id, 1);
147041 +}
147042 +
147043 +/**
147044 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
147045 + * @id: the base pool-channel ID of the range to reserve
147046 + * @count: the number of pool-channel IDs in the range
147047 + */
147048 +int qman_reserve_pool_range(u32 id, unsigned int count);
147049 +static inline int qman_reserve_pool(u32 id)
147050 +{
147051 + return qman_reserve_pool_range(id, 1);
147052 +}
147053 +
147054 +void qman_seed_pool_range(u32 id, unsigned int count);
147055 +
147056 + /* CGR management */
147057 + /* -------------- */
147058 +/**
147059 + * qman_create_cgr - Register a congestion group object
147060 + * @cgr: the 'cgr' object, with fields filled in
147061 + * @flags: QMAN_CGR_FLAG_* values
147062 + * @opts: optional state of CGR settings
147063 + *
147064 + * Registers this object to receiving congestion entry/exit callbacks on the
147065 + * portal affine to the cpu portal on which this API is executed. If opts is
147066 + * NULL then only the callback (cgr->cb) function is registered. If @flags
147067 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
147068 + * any unspecified parameters) will be used rather than a modify hw hardware
147069 + * (which only modifies the specified parameters).
147070 + */
147071 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
147072 + struct qm_mcc_initcgr *opts);
147073 +
147074 +/**
147075 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
147076 + * @cgr: the 'cgr' object, with fields filled in
147077 + * @flags: QMAN_CGR_FLAG_* values
147078 + * @dcp_portal: the DCP portal to which the cgr object is registered.
147079 + * @opts: optional state of CGR settings
147080 + *
147081 + */
147082 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
147083 + struct qm_mcc_initcgr *opts);
147084 +
147085 +/**
147086 + * qman_delete_cgr - Deregisters a congestion group object
147087 + * @cgr: the 'cgr' object to deregister
147088 + *
147089 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
147090 + * is executed. This must be excuted on the same affine portal on which it was
147091 + * created.
147092 + */
147093 +int qman_delete_cgr(struct qman_cgr *cgr);
147094 +
147095 +/**
147096 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
147097 + * @cgr: the 'cgr' object to deregister
147098 + *
147099 + * This will select the proper CPU and run there qman_delete_cgr().
147100 + */
147101 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
147102 +
147103 +/**
147104 + * qman_modify_cgr - Modify CGR fields
147105 + * @cgr: the 'cgr' object to modify
147106 + * @flags: QMAN_CGR_FLAG_* values
147107 + * @opts: the CGR-modification settings
147108 + *
147109 + * The @opts parameter comes from the low-level portal API, and can be NULL.
147110 + * Note that some fields and options within @opts may be ignored or overwritten
147111 + * by the driver, in particular the 'cgrid' field is ignored (this operation
147112 + * only affects the given CGR object). If @flags contains
147113 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
147114 + * unspecified parameters) will be used rather than a modify hw hardware (which
147115 + * only modifies the specified parameters).
147116 + */
147117 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
147118 + struct qm_mcc_initcgr *opts);
147119 +
147120 +/**
147121 +* qman_query_cgr - Queries CGR fields
147122 +* @cgr: the 'cgr' object to query
147123 +* @result: storage for the queried congestion group record
147124 +*/
147125 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
147126 +
147127 +/**
147128 + * qman_query_congestion - Queries the state of all congestion groups
147129 + * @congestion: storage for the queried state of all congestion groups
147130 + */
147131 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
147132 +
147133 +/**
147134 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
147135 + * @result: is set by the API to the base CGR ID of the allocated range
147136 + * @count: the number of CGR IDs required
147137 + * @align: required alignment of the allocated range
147138 + * @partial: non-zero if the API can return fewer than @count
147139 + *
147140 + * Returns the number of CGR IDs allocated, or a negative error code.
147141 + * If @partial is non zero, the allocation request may return a smaller range of
147142 + * than requested (though alignment will be as requested). If @partial is zero,
147143 + * the return value will either be 'count' or negative.
147144 + */
147145 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
147146 +static inline int qman_alloc_cgrid(u32 *result)
147147 +{
147148 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
147149 + return (ret > 0) ? 0 : ret;
147150 +}
147151 +
147152 +/**
147153 + * qman_release_cgrid_range - Release the specified range of CGR IDs
147154 + * @id: the base CGR ID of the range to deallocate
147155 + * @count: the number of CGR IDs in the range
147156 + */
147157 +void qman_release_cgrid_range(u32 id, unsigned int count);
147158 +static inline void qman_release_cgrid(u32 id)
147159 +{
147160 + qman_release_cgrid_range(id, 1);
147161 +}
147162 +
147163 +/**
147164 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
147165 + * @id: the base CGR ID of the range to reserve
147166 + * @count: the number of CGR IDs in the range
147167 + */
147168 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
147169 +static inline int qman_reserve_cgrid(u32 id)
147170 +{
147171 + return qman_reserve_cgrid_range(id, 1);
147172 +}
147173 +
147174 +void qman_seed_cgrid_range(u32 id, unsigned int count);
147175 +
147176 +
147177 + /* Helpers */
147178 + /* ------- */
147179 +/**
147180 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
147181 + * @fqid: the FQID that will be initialised by other s/w
147182 + *
147183 + * In many situations, a FQID is provided for communication between s/w
147184 + * entities, and whilst the consumer is responsible for initialising and
147185 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
147186 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
147187 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
147188 + * However, data can not be enqueued to the FQ until it is initialised out of
147189 + * the OOS state - this function polls for that condition. It is particularly
147190 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
147191 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
147192 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
147193 + * synchronise. The function returns zero for success, +1 if the FQ is still in
147194 + * the OOS state, or negative if there was an error.
147195 + */
147196 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
147197 +{
147198 + struct qm_mcr_queryfq_np np;
147199 + int err;
147200 + err = qman_query_fq_np(fq, &np);
147201 + if (err)
147202 + return err;
147203 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
147204 + return 1;
147205 + return 0;
147206 +}
147207 +
147208 + /* -------------- */
147209 + /* CEETM :: types */
147210 + /* -------------- */
147211 +/**
147212 + * Token Rate Structure
147213 + * Shaping rates are based on a "credit" system and a pre-configured h/w
147214 + * internal timer. The following type represents a shaper "rate" parameter as a
147215 + * fractional number of "tokens". Here's how it works. This (fractional) number
147216 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
147217 + * (up to a limit which is set by another shaper parameter). Every time a frame
147218 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
147219 + * bytes of data in the enqueued frame. A shaper will not allow itself to
147220 + * enqueue any frames if its token count is negative. As such;
147221 + *
147222 + * The rate at which data is enqueued is limited by the
147223 + * rate at which tokens are added.
147224 + *
147225 + * Therefore if the user knows the period between these h/w timer updates in
147226 + * seconds, they can calculate the maximum traffic rate of the shaper (in
147227 + * bytes-per-second) from the token rate. And vice versa, they can calculate
147228 + * the token rate to use in order to achieve a given traffic rate.
147229 + */
147230 +struct qm_ceetm_rate {
147231 + /* The token rate is; whole + (fraction/8192) */
147232 + u32 whole:11; /* 0..2047 */
147233 + u32 fraction:13; /* 0..8191 */
147234 +};
147235 +
147236 +struct qm_ceetm_weight_code {
147237 + /* The weight code is; 5 msbits + 3 lsbits */
147238 + u8 y:5;
147239 + u8 x:3;
147240 +};
147241 +
147242 +struct qm_ceetm {
147243 + unsigned int idx;
147244 + struct list_head sub_portals;
147245 + struct list_head lnis;
147246 + unsigned int sp_range[2];
147247 + unsigned int lni_range[2];
147248 +};
147249 +
147250 +struct qm_ceetm_sp {
147251 + struct list_head node;
147252 + unsigned int idx;
147253 + unsigned int dcp_idx;
147254 + int is_claimed;
147255 + struct qm_ceetm_lni *lni;
147256 +};
147257 +
147258 +/* Logical Network Interface */
147259 +struct qm_ceetm_lni {
147260 + struct list_head node;
147261 + unsigned int idx;
147262 + unsigned int dcp_idx;
147263 + int is_claimed;
147264 + struct qm_ceetm_sp *sp;
147265 + struct list_head channels;
147266 + int shaper_enable;
147267 + int shaper_couple;
147268 + int oal;
147269 + struct qm_ceetm_rate cr_token_rate;
147270 + struct qm_ceetm_rate er_token_rate;
147271 + u16 cr_token_bucket_limit;
147272 + u16 er_token_bucket_limit;
147273 +};
147274 +
147275 +/* Class Queue Channel */
147276 +struct qm_ceetm_channel {
147277 + struct list_head node;
147278 + unsigned int idx;
147279 + unsigned int lni_idx;
147280 + unsigned int dcp_idx;
147281 + struct list_head class_queues;
147282 + struct list_head ccgs;
147283 + u8 shaper_enable;
147284 + u8 shaper_couple;
147285 + struct qm_ceetm_rate cr_token_rate;
147286 + struct qm_ceetm_rate er_token_rate;
147287 + u16 cr_token_bucket_limit;
147288 + u16 er_token_bucket_limit;
147289 +};
147290 +
147291 +struct qm_ceetm_ccg;
147292 +
147293 +/* This callback type is used when handling congestion entry/exit. The
147294 + * 'cb_ctx' value is the opaque value associated with ccg object.
147295 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
147296 + */
147297 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
147298 + int congested);
147299 +
147300 +/* Class Congestion Group */
147301 +struct qm_ceetm_ccg {
147302 + struct qm_ceetm_channel *parent;
147303 + struct list_head node;
147304 + struct list_head cb_node;
147305 + qman_cb_ccgr cb;
147306 + void *cb_ctx;
147307 + unsigned int idx;
147308 +};
147309 +
147310 +/* Class Queue */
147311 +struct qm_ceetm_cq {
147312 + struct qm_ceetm_channel *parent;
147313 + struct qm_ceetm_ccg *ccg;
147314 + struct list_head node;
147315 + unsigned int idx;
147316 + int is_claimed;
147317 + struct list_head bound_lfqids;
147318 + struct list_head binding_node;
147319 +};
147320 +
147321 +/* Logical Frame Queue */
147322 +struct qm_ceetm_lfq {
147323 + struct qm_ceetm_channel *parent;
147324 + struct list_head node;
147325 + unsigned int idx;
147326 + unsigned int dctidx;
147327 + u64 context_a;
147328 + u32 context_b;
147329 + qman_cb_mr ern;
147330 +};
147331 +
147332 +/**
147333 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
147334 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
147335 + * approximates that rate.
147336 + * @bps: the desired shaper rate in bps.
147337 + * @token_rate: the output token rate computed with the given kbps.
147338 + * @rounding: dictates how to round if an exact conversion is not possible; if
147339 + * it is negative then 'token_rate' will round down to the highest value that
147340 + * does not exceed the desired rate, if it is positive then 'token_rate' will
147341 + * round up to the lowest value that is greater than or equal to the desired
147342 + * rate, and if it is zero then it will round to the nearest approximation,
147343 + * whether that be up or down.
147344 + *
147345 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147346 + */
147347 +int qman_ceetm_bps2tokenrate(u64 bps,
147348 + struct qm_ceetm_rate *token_rate,
147349 + int rounding);
147350 +
147351 +/**
147352 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
147353 + * corresponding number of 'bps'.
147354 + * @token_rate: the input desired token_rate fraction.
147355 + * @bps: the output shaper rate in bps computed with the give token rate.
147356 + * @rounding: has the same semantics as the previous function.
147357 + *
147358 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147359 + */
147360 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
147361 + u64 *bps,
147362 + int rounding);
147363 +
147364 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
147365 + int partial);
147366 +static inline int qman_alloc_ceetm0_channel(u32 *result)
147367 +{
147368 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
147369 + return (ret > 0) ? 0 : ret;
147370 +}
147371 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
147372 +static inline void qman_release_ceetm0_channelid(u32 channelid)
147373 +{
147374 + qman_release_ceetm0_channel_range(channelid, 1);
147375 +}
147376 +
147377 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
147378 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
147379 +{
147380 + return qman_reserve_ceetm0_channel_range(channelid, 1);
147381 +}
147382 +
147383 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
147384 +
147385 +
147386 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
147387 + int partial);
147388 +static inline int qman_alloc_ceetm1_channel(u32 *result)
147389 +{
147390 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
147391 + return (ret > 0) ? 0 : ret;
147392 +}
147393 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
147394 +static inline void qman_release_ceetm1_channelid(u32 channelid)
147395 +{
147396 + qman_release_ceetm1_channel_range(channelid, 1);
147397 +}
147398 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
147399 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
147400 +{
147401 + return qman_reserve_ceetm1_channel_range(channelid, 1);
147402 +}
147403 +
147404 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
147405 +
147406 +
147407 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
147408 + int partial);
147409 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
147410 +{
147411 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
147412 + return (ret > 0) ? 0 : ret;
147413 +}
147414 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
147415 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
147416 +{
147417 + qman_release_ceetm0_lfqid_range(lfqid, 1);
147418 +}
147419 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
147420 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
147421 +{
147422 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
147423 +}
147424 +
147425 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
147426 +
147427 +
147428 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
147429 + int partial);
147430 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
147431 +{
147432 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
147433 + return (ret > 0) ? 0 : ret;
147434 +}
147435 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
147436 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
147437 +{
147438 + qman_release_ceetm1_lfqid_range(lfqid, 1);
147439 +}
147440 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
147441 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
147442 +{
147443 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
147444 +}
147445 +
147446 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
147447 +
147448 +
147449 + /* ----------------------------- */
147450 + /* CEETM :: sub-portals */
147451 + /* ----------------------------- */
147452 +
147453 +/**
147454 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
147455 + * to us and configured for traffic-management.
147456 + * @sp: the returned sub-portal object, if successful.
147457 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147458 + * instance),
147459 + * @sp_idx" is the desired sub-portal index from 0 to 15.
147460 + *
147461 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
147462 + * if the sp_idx is out of range.
147463 + *
147464 + * Note that if there are multiple driver domains (eg. a linux kernel versus
147465 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
147466 + * then a sub-portal may be accessible by more than one instance of a qman
147467 + * driver and so it may be claimed multiple times. If this is the case, it is
147468 + * up to the system architect to prevent conflicting configuration actions
147469 + * coming from the different driver domains. The qman drivers do not have any
147470 + * behind-the-scenes coordination to prevent this from happening.
147471 + */
147472 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
147473 + enum qm_dc_portal dcp_idx,
147474 + unsigned int sp_idx);
147475 +
147476 +/**
147477 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
147478 + * @sp: the sub-portal to be released.
147479 + *
147480 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
147481 + * released.
147482 + */
147483 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
147484 +
147485 + /* ----------------------------------- */
147486 + /* CEETM :: logical network interfaces */
147487 + /* ----------------------------------- */
147488 +
147489 +/**
147490 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
147491 + * @lni: the returned LNI object, if successful.
147492 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147493 + * instance)
147494 + * @lni_idx: is the desired LNI index.
147495 + *
147496 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
147497 + * is not available or has already been claimed (and not yet successfully
147498 + * released), or lni_dix is out of range.
147499 + *
147500 + * Note that there may be multiple driver domains (or instances) that need to
147501 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
147502 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
147503 + * qman_ceetm_sp_get_lni() for more information.
147504 + */
147505 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
147506 + enum qm_dc_portal dcp_id,
147507 + unsigned int lni_idx);
147508 +
147509 +/**
147510 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
147511 + * @lni: the lni needs to be released.
147512 + *
147513 + * This will only succeed if all dependent objects have been released.
147514 + * Returns zero for success, or -EBUSY if the dependencies are not released.
147515 + */
147516 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
147517 +
147518 +/**
147519 + * qman_ceetm_sp_set_lni
147520 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
147521 + * mapped to.
147522 + * @sp: the given sub-portal.
147523 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
147524 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
147525 + *
147526 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
147527 + * mapping has been set, or configure mapping command returns error, and
147528 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
147529 + * mapping command returns error.
147530 + *
147531 + * This may be useful in situations where multiple driver domains have access
147532 + * to the same sub-portals in order to all be able to transmit out the same
147533 + * physical interface (perhaps they're on different IP addresses or VPNs, so
147534 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
147535 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
147536 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
147537 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
147538 + * in order to determine the LNI that the control-plane had assigned. This is
147539 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
147540 + * LNI object.
147541 + */
147542 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
147543 + struct qm_ceetm_lni *lni);
147544 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
147545 + unsigned int *lni_idx);
147546 +
147547 +/**
147548 + * qman_ceetm_lni_enable_shaper
147549 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
147550 + * @lni: the given LNI.
147551 + * @coupled: indicates whether CR and ER are coupled.
147552 + * @oal: the overhead accounting length which is added to the actual length of
147553 + * each frame when performing shaper calculations.
147554 + *
147555 + * When the number of (unused) committed-rate tokens reach the committed-rate
147556 + * token limit, 'coupled' indicates whether surplus tokens should be added to
147557 + * the excess-rate token count (up to the excess-rate token limit).
147558 + * When LNI is claimed, the shaper is disabled by default. The enable function
147559 + * will turn on this shaper for this lni.
147560 + * Whenever a claimed LNI is first enabled for shaping, its committed and
147561 + * excess token rates and limits are zero, so will need to be changed to do
147562 + * anything useful. The shaper can subsequently be enabled/disabled without
147563 + * resetting the shaping parameters, but the shaping parameters will be reset
147564 + * when the LNI is released.
147565 + *
147566 + * Returns zero for success, or errno for "enable" function in the cases as:
147567 + * a) -EINVAL if the shaper is already enabled,
147568 + * b) -EIO if the configure shaper command returns error.
147569 + * For "disable" function, returns:
147570 + * a) -EINVAL if the shaper is has already disabled.
147571 + * b) -EIO if calling configure shaper command returns error.
147572 + */
147573 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
147574 + int oal);
147575 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
147576 +
147577 +/**
147578 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
147579 + * @lni: the give LNI
147580 + */
147581 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
147582 +
147583 +/**
147584 + * qman_ceetm_lni_set_commit_rate
147585 + * qman_ceetm_lni_get_commit_rate
147586 + * qman_ceetm_lni_set_excess_rate
147587 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
147588 + * token limit for the given LNI.
147589 + * @lni: the given LNI.
147590 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
147591 + * the LNI queried by "get" function.
147592 + * @token_limit: the desired token bucket limit for "set" function, or the token
147593 + * limit of the given LNI queried by "get" function.
147594 + *
147595 + * Returns zero for success. The "set" function returns -EINVAL if the given
147596 + * LNI is unshapped or -EIO if the configure shaper command returns error.
147597 + * The "get" function returns -EINVAL if the token rate or the token limit is
147598 + * not set or the query command returns error.
147599 + */
147600 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
147601 + const struct qm_ceetm_rate *token_rate,
147602 + u16 token_limit);
147603 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
147604 + struct qm_ceetm_rate *token_rate,
147605 + u16 *token_limit);
147606 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
147607 + const struct qm_ceetm_rate *token_rate,
147608 + u16 token_limit);
147609 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
147610 + struct qm_ceetm_rate *token_rate,
147611 + u16 *token_limit);
147612 +/**
147613 + * qman_ceetm_lni_set_commit_rate_bps
147614 + * qman_ceetm_lni_get_commit_rate_bps
147615 + * qman_ceetm_lni_set_excess_rate_bps
147616 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
147617 + * and token limit for the given LNI.
147618 + * @lni: the given LNI.
147619 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
147620 + * of the LNI queried by "get" function.
147621 + * @token_limit: the desired token bucket limit for "set" function, or the token
147622 + * limit of the given LNI queried by "get" function.
147623 + *
147624 + * Returns zero for success. The "set" function returns -EINVAL if the given
147625 + * LNI is unshapped or -EIO if the configure shaper command returns error.
147626 + * The "get" function returns -EINVAL if the token rate or the token limit is
147627 + * not set or the query command returns error.
147628 + */
147629 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
147630 + u64 bps,
147631 + u16 token_limit);
147632 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
147633 + u64 *bps, u16 *token_limit);
147634 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
147635 + u64 bps,
147636 + u16 token_limit);
147637 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
147638 + u64 *bps, u16 *token_limit);
147639 +
147640 +/**
147641 + * qman_ceetm_lni_set_tcfcc
147642 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
147643 + * @lni: the given LNI.
147644 + * @cq_level: is between 0 and 15, representing individual class queue levels
147645 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
147646 + * for every channel).
147647 + * @traffic_class: is between 0 and 7 when associating a given class queue level
147648 + * to a traffic class, or -1 when disabling traffic class flow control for this
147649 + * class queue level.
147650 + *
147651 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
147652 + * of range as indicated above, or -EIO if the configure/query tcfcc command
147653 + * returns error.
147654 + *
147655 + * Refer to the section of QMan CEETM traffic class flow control in the
147656 + * Reference Manual.
147657 + */
147658 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
147659 + unsigned int cq_level,
147660 + int traffic_class);
147661 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
147662 + unsigned int cq_level,
147663 + int *traffic_class);
147664 +
147665 + /* ----------------------------- */
147666 + /* CEETM :: class queue channels */
147667 + /* ----------------------------- */
147668 +
147669 +/**
147670 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
147671 + * the given LNI.
147672 + * @channel: the returned class queue channel object, if successful.
147673 + * @lni: the LNI that the channel belongs to.
147674 + *
147675 + * Channels are always initially "unshaped".
147676 + *
147677 + * Return zero for success, or -ENODEV if there is no channel available(all 32
147678 + * channels are claimed) or -EINVAL if the channel mapping command returns
147679 + * error.
147680 + */
147681 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
147682 + struct qm_ceetm_lni *lni);
147683 +
147684 +/**
147685 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
147686 + * @channel: the channel needs to be released.
147687 + *
147688 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
147689 + *
147690 + * Note any shaping of the channel will be cleared to leave it in an unshaped
147691 + * state.
147692 + */
147693 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
147694 +
147695 +/**
147696 + * qman_ceetm_channel_enable_shaper
147697 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
147698 + * @channel: the given channel.
147699 + * @coupled: indicates whether surplus CR tokens should be added to the
147700 + * excess-rate token count (up to the excess-rate token limit) when the number
147701 + * of (unused) committed-rate tokens reach the committed_rate token limit.
147702 + *
147703 + * Whenever a claimed channel is first enabled for shaping, its committed and
147704 + * excess token rates and limits are zero, so will need to be changed to do
147705 + * anything useful. The shaper can subsequently be enabled/disabled without
147706 + * resetting the shaping parameters, but the shaping parameters will be reset
147707 + * when the channel is released.
147708 + *
147709 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
147710 + * shaper has been enabled/disabled or the management command returns error.
147711 + */
147712 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
147713 + int coupled);
147714 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
147715 +
147716 +/**
147717 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
147718 + * @channel: the give channel.
147719 + */
147720 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
147721 +
147722 +/**
147723 + * qman_ceetm_channel_set_commit_rate
147724 + * qman_ceetm_channel_get_commit_rate
147725 + * qman_ceetm_channel_set_excess_rate
147726 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
147727 + * @channel: the given channel.
147728 + * @token_rate: the desired token rate for "set" function, or the queried token
147729 + * rate for "get" function.
147730 + * @token_limit: the desired token limit for "set" function, or the queried
147731 + * token limit for "get" function.
147732 + *
147733 + * Return zero for success. The "set" function returns -EINVAL if the channel
147734 + * is unshaped, or -EIO if the configure shapper command returns error. The
147735 + * "get" function returns -EINVAL if token rate of token limit is not set, or
147736 + * the query shaper command returns error.
147737 + */
147738 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
147739 + const struct qm_ceetm_rate *token_rate,
147740 + u16 token_limit);
147741 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
147742 + struct qm_ceetm_rate *token_rate,
147743 + u16 *token_limit);
147744 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
147745 + const struct qm_ceetm_rate *token_rate,
147746 + u16 token_limit);
147747 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
147748 + struct qm_ceetm_rate *token_rate,
147749 + u16 *token_limit);
147750 +/**
147751 + * qman_ceetm_channel_set_commit_rate_bps
147752 + * qman_ceetm_channel_get_commit_rate_bps
147753 + * qman_ceetm_channel_set_excess_rate_bps
147754 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
147755 + * parameters.
147756 + * @channel: the given channel.
147757 + * @token_rate: the desired shaper rate in bps for "set" function, or the
147758 + * shaper rate in bps for "get" function.
147759 + * @token_limit: the desired token limit for "set" function, or the queried
147760 + * token limit for "get" function.
147761 + *
147762 + * Return zero for success. The "set" function returns -EINVAL if the channel
147763 + * is unshaped, or -EIO if the configure shapper command returns error. The
147764 + * "get" function returns -EINVAL if token rate of token limit is not set, or
147765 + * the query shaper command returns error.
147766 + */
147767 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
147768 + u64 bps, u16 token_limit);
147769 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
147770 + u64 *bps, u16 *token_limit);
147771 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
147772 + u64 bps, u16 token_limit);
147773 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
147774 + u64 *bps, u16 *token_limit);
147775 +
147776 +/**
147777 + * qman_ceetm_channel_set_weight
147778 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
147779 + * @channel: the given channel.
147780 + * @token_limit: the desired token limit as the weight of the unshaped channel
147781 + * for "set" function, or the queried token limit for "get" function.
147782 + *
147783 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
147784 + * It allows the unshaped channels to be included in the CR time eligible list,
147785 + * and thus use the configured CR token limit value as their fair queuing
147786 + * weight.
147787 + *
147788 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
147789 + * the management command returns error.
147790 + */
147791 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
147792 + u16 token_limit);
147793 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
147794 + u16 *token_limit);
147795 +
147796 +/**
147797 + * qman_ceetm_channel_set_group
147798 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
147799 + * @channel: the given channel.
147800 + * @group_b: indicates whether there is group B in this channel.
147801 + * @prio_a: the priority of group A.
147802 + * @prio_b: the priority of group B.
147803 + *
147804 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
147805 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
147806 + * group A, otherwise they are split into group A (CQ8-11) and group B
147807 + * (CQ12-C15). The individual class queues and the group(s) are in strict
147808 + * priority order relative to each other. Within the group(s), the scheduling
147809 + * is not strict priority order, but the result of scheduling within a group
147810 + * is in strict priority order relative to the other class queues in the
147811 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
147812 + * relative to the individual class queues, and take values from 0-7. Eg. if
147813 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
147814 + * priority order would be;
147815 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
147816 + *
147817 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
147818 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
147819 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
147820 + * the configure scheduler command returns error. For "get" function, return
147821 + * -EINVAL if the query scheduler command returns error.
147822 + */
147823 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
147824 + int group_b,
147825 + unsigned int prio_a,
147826 + unsigned int prio_b);
147827 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
147828 + int *group_b,
147829 + unsigned int *prio_a,
147830 + unsigned int *prio_b);
147831 +
147832 +/**
147833 + * qman_ceetm_channel_set_group_cr_eligibility
147834 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
147835 + * @channel: the given channel object
147836 + * @group_b: indicates whether there is group B in this channel.
147837 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
147838 + *
147839 + * Return zero for success, or -EINVAL if eligibility setting fails.
147840 +*/
147841 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
147842 + *channel, int group_b, int cre);
147843 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
147844 + *channel, int group_b, int ere);
147845 +
147846 +/**
147847 + * qman_ceetm_channel_set_cq_cr_eligibility
147848 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
147849 + * @channel: the given channel object
147850 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
147851 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
147852 + *
147853 + * Return zero for success, or -EINVAL if eligibility setting fails.
147854 +*/
147855 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
147856 + unsigned int idx, int cre);
147857 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
147858 + unsigned int idx, int ere);
147859 +
147860 + /* --------------------- */
147861 + /* CEETM :: class queues */
147862 + /* --------------------- */
147863 +
147864 +/**
147865 + * qman_ceetm_cq_claim - Claims an individual class queue.
147866 + * @cq: the returned class queue object, if successful.
147867 + * @channel: the class queue channel.
147868 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
147869 + * @ccg: represents the class congestion group that this class queue should be
147870 + * subscribed to, or NULL if no congestion group membership is desired.
147871 + *
147872 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
147873 + * if this class queue has been claimed, or configure class queue command
147874 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
147875 + */
147876 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
147877 + struct qm_ceetm_channel *channel,
147878 + unsigned int idx,
147879 + struct qm_ceetm_ccg *ccg);
147880 +
147881 +/**
147882 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
147883 + * @cq: the returned class queue object, if successful.
147884 + * @channel: the class queue channel.
147885 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
147886 + * @ccg: represents the class congestion group that this class queue should be
147887 + * subscribed to, or NULL if no congestion group membership is desired.
147888 + *
147889 + * Return zero for success, or -EINVAL if @idx is out the range or if
147890 + * this class queue has been claimed or configure class queue command returns
147891 + * error, or returns -ENOMEM if allocating CQ memory fails.
147892 + */
147893 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
147894 + struct qm_ceetm_channel *channel,
147895 + unsigned int idx,
147896 + struct qm_ceetm_ccg *ccg);
147897 +
147898 +/**
147899 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
147900 + * @cq: the returned class queue object, if successful.
147901 + * @channel: the class queue channel.
147902 + * @idx: is from 0 to 3 (CQ12 to CQ15).
147903 + * @ccg: represents the class congestion group that this class queue should be
147904 + * subscribed to, or NULL if no congestion group membership is desired.
147905 + *
147906 + * Return zero for success, or -EINVAL if @idx is out the range or if
147907 + * this class queue has been claimed or configure class queue command returns
147908 + * error, or returns -ENOMEM if allocating CQ memory fails.
147909 + */
147910 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
147911 + struct qm_ceetm_channel *channel,
147912 + unsigned int idx,
147913 + struct qm_ceetm_ccg *ccg);
147914 +
147915 +/**
147916 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
147917 + * @cq: The class queue to be released.
147918 + *
147919 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
147920 + * FQIDs) have not been released.
147921 + */
147922 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
147923 +
147924 +/**
147925 + * qman_ceetm_set_queue_weight
147926 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
147927 + * queue.
147928 + * @cq: the given class queue.
147929 + * @weight_code: the desired weight code to set for the given class queue for
147930 + * "set" function or the queired weight code for "get" function.
147931 + *
147932 + * Grouped class queues have a default weight code of zero, which corresponds to
147933 + * a scheduler weighting of 1. This function can be used to modify a grouped
147934 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
147935 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
147936 + * and the corresponding sharing weight.)
147937 + *
147938 + * Returns zero for success, or -EIO if the configure weight command returns
147939 + * error for "set" function, or -EINVAL if the query command returns
147940 + * error for "get" function.
147941 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
147942 + * Manual for weight and weight code.
147943 + */
147944 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
147945 + struct qm_ceetm_weight_code *weight_code);
147946 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
147947 + struct qm_ceetm_weight_code *weight_code);
147948 +
147949 +/**
147950 + * qman_ceetm_set_queue_weight_in_ratio
147951 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
147952 + * grouped class queue.
147953 + * @cq: the given class queue.
147954 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
147955 + * by 100 to get rid of fraction.
147956 + *
147957 + * Returns zero for success, or -EIO if the configure weight command returns
147958 + * error for "set" function, or -EINVAL if the query command returns
147959 + * error for "get" function.
147960 + */
147961 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
147962 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
147963 +
147964 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
147965 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
147966 + * corresponding to intermediate weight codes are calculated using linear
147967 + * interpolation on the inverted values. Or put another way, the inverse weights
147968 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
147969 + * between these are divided linearly into 32 intermediate values, the inverses
147970 + * of which form the remaining weight codes.
147971 + *
147972 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
147973 + * scheduling within a group of class queues (group A or B). Weights are used to
147974 + * normalise the class queues to an underlying BFS algorithm where all class
147975 + * queues are assumed to require "equal bandwidth". So the weights referred to
147976 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
147977 + * one class queue in a group is assigned a weight of 2 whilst the other class
147978 + * queues in the group keep the default weight of 1, then the WBFS scheduler
147979 + * will effectively treat all frames enqueued on the weight-2 class queue as
147980 + * having half the number of bytes they really have. Ie. if all other things are
147981 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
147982 + * the others. So weights should be chosen to provide bandwidth ratios between
147983 + * members of the same class queue group. These weights have no bearing on
147984 + * behaviour outside that group's WBFS mechanism though.
147985 + */
147986 +
147987 +/**
147988 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
147989 + * representation of the corresponding weight is given (in order to not lose
147990 + * any precision).
147991 + * @weight_code: The given weight code in WBFS.
147992 + * @numerator: the numerator part of the weight computed by the weight code.
147993 + * @denominator: the denominator part of the weight computed by the weight code
147994 + *
147995 + * Returns zero for success or -EINVAL if the given weight code is illegal.
147996 + */
147997 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
147998 + u32 *numerator,
147999 + u32 *denominator);
148000 +/**
148001 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
148002 + * If the user needs to know how close this is, convert the resulting weight
148003 + * code back to a weight and compare.
148004 + * @numerator: numerator part of the given weight.
148005 + * @denominator: denominator part of the given weight.
148006 + * @weight_code: the weight code computed from the given weight.
148007 + *
148008 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
148009 + * the range of weights.
148010 + */
148011 +int qman_ceetm_ratio2wbfs(u32 numerator,
148012 + u32 denominator,
148013 + struct qm_ceetm_weight_code *weight_code,
148014 + int rounding);
148015 +
148016 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
148017 +/**
148018 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
148019 + * CQ counters.
148020 + * @cq: the given CQ object.
148021 + * @flags: indicates whether the statistics counter will be cleared after query.
148022 + * @frame_count: The number of the frames that have been counted since the
148023 + * counter was cleared last time.
148024 + * @byte_count: the number of bytes in all frames that have been counted.
148025 + *
148026 + * Return zero for success or -EINVAL if query statistics command returns error.
148027 + *
148028 + */
148029 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
148030 + u64 *frame_count, u64 *byte_count);
148031 +
148032 +/**
148033 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
148034 + * @cq: the give CQ object.
148035 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
148036 + */
148037 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
148038 +
148039 + /* ---------------------- */
148040 + /* CEETM :: logical FQIDs */
148041 + /* ---------------------- */
148042 +/**
148043 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
148044 + * the given class queue.
148045 + * @lfq: the returned lfq object, if successful.
148046 + * @cq: the class queue which needs to claim a LFQID.
148047 + *
148048 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
148049 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
148050 + */
148051 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
148052 + struct qm_ceetm_cq *cq);
148053 +
148054 +/**
148055 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
148056 + * @lfq: the lfq to be released.
148057 + *
148058 + * Return zero for success.
148059 + */
148060 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
148061 +
148062 +/**
148063 + * qman_ceetm_lfq_set_context
148064 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
148065 + * "dequeue context table" associated with the logical FQID.
148066 + * @lfq: the given logical FQ object.
148067 + * @context_a: contextA of the dequeue context.
148068 + * @context_b: contextB of the dequeue context.
148069 + *
148070 + * Returns zero for success, or -EINVAL if there is error to set/get the
148071 + * context pair.
148072 + */
148073 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
148074 + u64 context_a,
148075 + u32 context_b);
148076 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
148077 + u64 *context_a,
148078 + u32 *context_b);
148079 +
148080 +/**
148081 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
148082 + * @lfq: the given logic fq.
148083 + * @fq: the fq object created for the given logic fq.
148084 + *
148085 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
148086 + * target a logical FQID (and the class queue it is associated with).
148087 + * Note that this FQ object can only be used for enqueues, and
148088 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
148089 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
148090 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
148091 + * responsibility to ensure that the underlying 'lfq' is not released until any
148092 + * enqueues to this FQ object have completed. The only field the user needs to
148093 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
148094 + * could conceivably be called on this FQ object. This API can be called
148095 + * multiple times to create multiple FQ objects referring to the same logical
148096 + * FQID, and any enqueue rejections will respect the callback of the object that
148097 + * issued the enqueue (and will identify the object via the parameter passed to
148098 + * the callback too). There is no 'flags' parameter to this API as there is for
148099 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
148100 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
148101 + *
148102 + * Returns 0 for success.
148103 + */
148104 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
148105 +
148106 + /* -------------------------------- */
148107 + /* CEETM :: class congestion groups */
148108 + /* -------------------------------- */
148109 +
148110 +/**
148111 + * qman_ceetm_ccg_claim - Claims an unused CCG.
148112 + * @ccg: the returned CCG object, if successful.
148113 + * @channel: the given class queue channel
148114 + * @cscn: the callback function of this CCG.
148115 + * @cb_ctx: the corresponding context to be used used if state change
148116 + * notifications are later enabled for this CCG.
148117 + *
148118 + * The congestion group is local to the given class queue channel, so only
148119 + * class queues within the channel can be associated with that congestion group.
148120 + * The association of class queues to congestion groups occurs when the class
148121 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
148122 + * Congestion groups are in a "zero" state when initially claimed, and they are
148123 + * returned to that state when released.
148124 + *
148125 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
148126 + */
148127 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
148128 + struct qm_ceetm_channel *channel,
148129 + unsigned int idx,
148130 + void (*cscn)(struct qm_ceetm_ccg *,
148131 + void *cb_ctx,
148132 + int congested),
148133 + void *cb_ctx);
148134 +
148135 +/**
148136 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
148137 + * @ccg: the given ccg.
148138 + *
148139 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
148140 + * (class queues that are associated with the CCG) have not been released.
148141 + */
148142 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
148143 +
148144 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
148145 + * controls which CCG attributes are to be updated, and the remainder specify
148146 + * the values for those attributes. A CCG counts either frames or the bytes
148147 + * within those frames, but not both ('mode'). A CCG can optionally cause
148148 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
148149 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
148150 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
148151 + * to a "congestion state", but not both ('td_mode'). Congestion state has
148152 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
148153 + * notifications can be sent to software the CCG goes in to and out of this
148154 + * congested state ('cscn_en'). */
148155 +struct qm_ceetm_ccg_params {
148156 + /* Boolean fields together in a single bitfield struct */
148157 + struct {
148158 + /* Whether to count bytes or frames. 1==frames */
148159 + u8 mode:1;
148160 + /* En/disable tail-drop. 1==enable */
148161 + u8 td_en:1;
148162 + /* Tail-drop on congestion-state or threshold. 1=threshold */
148163 + u8 td_mode:1;
148164 + /* Generate congestion state change notifications. 1==enable */
148165 + u8 cscn_en:1;
148166 + /* Enable WRED rejections (per colour). 1==enable */
148167 + u8 wr_en_g:1;
148168 + u8 wr_en_y:1;
148169 + u8 wr_en_r:1;
148170 + } __packed;
148171 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
148172 + struct qm_cgr_cs_thres td_thres;
148173 + /* Congestion state thresholds, for entry and exit. */
148174 + struct qm_cgr_cs_thres cs_thres_in;
148175 + struct qm_cgr_cs_thres cs_thres_out;
148176 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
148177 + signed char oal;
148178 + /* Congestion state change notification for DCP portal, virtual CCGID*/
148179 + /* WRED parameters. */
148180 + struct qm_cgr_wr_parm wr_parm_g;
148181 + struct qm_cgr_wr_parm wr_parm_y;
148182 + struct qm_cgr_wr_parm wr_parm_r;
148183 +};
148184 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
148185 + * the CCGR are to be updated. */
148186 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
148187 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
148188 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
148189 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
148190 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
148191 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
148192 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
148193 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
148194 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
148195 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
148196 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
148197 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
148198 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
148199 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
148200 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
148201 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
148202 +
148203 +/**
148204 + * qman_ceetm_ccg_set
148205 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
148206 + * @ccg: the given CCG object.
148207 + * @we_mask: the write enable mask.
148208 + * @params: the parameters setting for this ccg
148209 + *
148210 + * Return 0 for success, or -EIO if configure ccg command returns error for
148211 + * "set" function, or -EINVAL if query ccg command returns error for "get"
148212 + * function.
148213 + */
148214 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
148215 + u16 we_mask,
148216 + const struct qm_ceetm_ccg_params *params);
148217 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
148218 + struct qm_ceetm_ccg_params *params);
148219 +
148220 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
148221 + * mask.
148222 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
148223 + * in the cscn target mask.
148224 + * @ccg: the give CCG object.
148225 + * @swp_idx: the index of the software portal.
148226 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
148227 + * the target mask.
148228 + * @we_mask: the write enable mask.
148229 + * @params: the parameters setting for this ccg
148230 + *
148231 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148232 + */
148233 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
148234 + u16 swp_idx,
148235 + unsigned int cscn_enabled,
148236 + u16 we_mask,
148237 + const struct qm_ceetm_ccg_params *params);
148238 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
148239 + u16 swp_idx,
148240 + unsigned int *cscn_enabled);
148241 +
148242 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
148243 + * target mask.
148244 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
148245 + * is in the cscn target mask.
148246 + * @ccg: the give CCG object.
148247 + * @dcp_idx: the index of the direct connect portal.
148248 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
148249 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
148250 + * the target mask.
148251 + * @we_mask: the write enable mask.
148252 + * @params: the parameters setting for this ccg
148253 + *
148254 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148255 + */
148256 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
148257 + u16 dcp_idx,
148258 + u8 vcgid,
148259 + unsigned int cscn_enabled,
148260 + u16 we_mask,
148261 + const struct qm_ceetm_ccg_params *params);
148262 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
148263 + u16 dcp_idx,
148264 + u8 *vcgid,
148265 + unsigned int *cscn_enabled);
148266 +
148267 +/**
148268 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
148269 + * CEETM CCG counters.
148270 + * @ccg: the given CCG object.
148271 + * @flags: indicates whether the statistics counter will be cleared after query.
148272 + * @frame_count: The number of the frames that have been counted since the
148273 + * counter was cleared last time.
148274 + * @byte_count: the number of bytes in all frames that have been counted.
148275 + *
148276 + * Return zero for success or -EINVAL if query statistics command returns error.
148277 + *
148278 + */
148279 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
148280 + u64 *frame_count, u64 *byte_count);
148281 +
148282 +/**
148283 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
148284 + * @lfqid: Logical Frame Queue ID
148285 + * @lfqmt_query: Results of the query command
148286 + *
148287 + * Returns zero for success or -EIO if the query command returns error.
148288 + *
148289 + */
148290 +int qman_ceetm_query_lfqmt(int lfqid,
148291 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
148292 +
148293 +/**
148294 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
148295 + * @cid: Target ID (CQID or CCGRID)
148296 + * @dcp_idx: CEETM portal ID
148297 + * @command_type: One of the following:
148298 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
148299 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
148300 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
148301 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
148302 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
148303 + * 5 = Write reject statistics. CID carries the CCGRID to be written
148304 + * @frame_count: Frame count value to be written if this is a write command
148305 + * @byte_count: Bytes count value to be written if this is a write command
148306 + *
148307 + * Returns zero for success or -EIO if the query command returns error.
148308 + */
148309 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
148310 + u16 command_type, u64 frame_count,
148311 + u64 byte_count);
148312 +
148313 +/**
148314 + * qman_set_wpm - Set waterfall power management
148315 + *
148316 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148317 + *
148318 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148319 + * accessible.
148320 + */
148321 +int qman_set_wpm(int wpm_enable);
148322 +
148323 +/**
148324 + * qman_get_wpm - Query the waterfall power management setting
148325 + *
148326 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148327 + *
148328 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148329 + * accessible.
148330 + */
148331 +int qman_get_wpm(int *wpm_enable);
148332 +
148333 +/* The below qman_p_***() variants might be called in a migration situation
148334 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
148335 + * execution was affine to prior to migration.
148336 + * @qman_portal specifies which portal the APIs will use.
148337 +*/
148338 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
148339 + *p);
148340 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
148341 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
148342 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
148343 +u32 qman_p_poll_slow(struct qman_portal *p);
148344 +void qman_p_poll(struct qman_portal *p);
148345 +void qman_p_stop_dequeues(struct qman_portal *p);
148346 +void qman_p_start_dequeues(struct qman_portal *p);
148347 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
148348 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
148349 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
148350 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
148351 + int park_request);
148352 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
148353 + u32 flags __maybe_unused, u32 vdqcr);
148354 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
148355 + const struct qm_fd *fd, u32 flags);
148356 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
148357 + const struct qm_fd *fd, u32 flags,
148358 + struct qman_fq *orp, u16 orp_seqnum);
148359 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
148360 + const struct qm_fd *fd, u32 flags,
148361 + qman_cb_precommit cb, void *cb_arg);
148362 +#ifdef __cplusplus
148363 +}
148364 +#endif
148365 +
148366 +#endif /* FSL_QMAN_H */
148367 --- /dev/null
148368 +++ b/include/linux/fsl_usdpaa.h
148369 @@ -0,0 +1,372 @@
148370 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
148371 + *
148372 + * This file is licensed under the terms of the GNU General Public License
148373 + * version 2. This program is licensed "as is" without any warranty of any
148374 + * kind, whether express or implied.
148375 + */
148376 +
148377 +#ifndef FSL_USDPAA_H
148378 +#define FSL_USDPAA_H
148379 +
148380 +#ifdef __cplusplus
148381 +extern "C" {
148382 +#endif
148383 +
148384 +#include <linux/uaccess.h>
148385 +#include <linux/ioctl.h>
148386 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
148387 +#include <linux/compat.h>
148388 +
148389 +#ifdef CONFIG_FSL_USDPAA
148390 +
148391 +/******************************/
148392 +/* Allocation of resource IDs */
148393 +/******************************/
148394 +
148395 +/* This enum is used to distinguish between the type of underlying object being
148396 + * manipulated. */
148397 +enum usdpaa_id_type {
148398 + usdpaa_id_fqid,
148399 + usdpaa_id_bpid,
148400 + usdpaa_id_qpool,
148401 + usdpaa_id_cgrid,
148402 + usdpaa_id_ceetm0_lfqid,
148403 + usdpaa_id_ceetm0_channelid,
148404 + usdpaa_id_ceetm1_lfqid,
148405 + usdpaa_id_ceetm1_channelid,
148406 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
148407 +};
148408 +#define USDPAA_IOCTL_MAGIC 'u'
148409 +struct usdpaa_ioctl_id_alloc {
148410 + uint32_t base; /* Return value, the start of the allocated range */
148411 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
148412 + uint32_t num; /* how many IDs to allocate (and return value) */
148413 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
148414 + int partial; /* whether to allow less than 'num' */
148415 +};
148416 +struct usdpaa_ioctl_id_release {
148417 + /* Input; */
148418 + enum usdpaa_id_type id_type;
148419 + uint32_t base;
148420 + uint32_t num;
148421 +};
148422 +struct usdpaa_ioctl_id_reserve {
148423 + enum usdpaa_id_type id_type;
148424 + uint32_t base;
148425 + uint32_t num;
148426 +};
148427 +
148428 +
148429 +/* ioctl() commands */
148430 +#define USDPAA_IOCTL_ID_ALLOC \
148431 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
148432 +#define USDPAA_IOCTL_ID_RELEASE \
148433 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
148434 +#define USDPAA_IOCTL_ID_RESERVE \
148435 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
148436 +
148437 +/**********************/
148438 +/* Mapping DMA memory */
148439 +/**********************/
148440 +
148441 +/* Maximum length for a map name, including NULL-terminator */
148442 +#define USDPAA_DMA_NAME_MAX 16
148443 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
148444 + * For a sharable and named map, specify _SHARED (whether creating one or
148445 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
148446 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
148447 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
148448 + * specified and the mapping already exists, the mapping will fail unless _LAZY
148449 + * is specified. When mapping to a pre-existing sharable map, the length must be
148450 + * an exact match. Lengths must be a power-of-4 multiple of page size.
148451 + *
148452 + * Note that this does not actually map the memory to user-space, that is done
148453 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
148454 + * ioctl() is what gives the process permission to do this, and a page-offset
148455 + * with which to do so.
148456 + */
148457 +#define USDPAA_DMA_FLAG_SHARE 0x01
148458 +#define USDPAA_DMA_FLAG_CREATE 0x02
148459 +#define USDPAA_DMA_FLAG_LAZY 0x04
148460 +#define USDPAA_DMA_FLAG_RDONLY 0x08
148461 +struct usdpaa_ioctl_dma_map {
148462 + /* Output parameters - virtual and physical addresses */
148463 + void *ptr;
148464 + uint64_t phys_addr;
148465 + /* Input parameter, the length of the region to be created (or if
148466 + * mapping an existing region, this must match it). Must be a power-of-4
148467 + * multiple of page size. */
148468 + uint64_t len;
148469 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148470 + uint32_t flags;
148471 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148472 + * of the existing mapping to use). */
148473 + char name[USDPAA_DMA_NAME_MAX];
148474 + /* If this ioctl() creates the mapping, this is an input parameter
148475 + * stating whether the region supports locking. If mapping an existing
148476 + * region, this is a return value indicating the same thing. */
148477 + int has_locking;
148478 + /* In the case of a successful map with _CREATE and _LAZY, this return
148479 + * value indicates whether we created the mapped region or whether it
148480 + * already existed. */
148481 + int did_create;
148482 +};
148483 +
148484 +#ifdef CONFIG_COMPAT
148485 +struct usdpaa_ioctl_dma_map_compat {
148486 + /* Output parameters - virtual and physical addresses */
148487 + compat_uptr_t ptr;
148488 + uint64_t phys_addr;
148489 + /* Input parameter, the length of the region to be created (or if
148490 + * mapping an existing region, this must match it). Must be a power-of-4
148491 + * multiple of page size. */
148492 + uint64_t len;
148493 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148494 + uint32_t flags;
148495 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148496 + * of the existing mapping to use). */
148497 + char name[USDPAA_DMA_NAME_MAX];
148498 + /* If this ioctl() creates the mapping, this is an input parameter
148499 + * stating whether the region supports locking. If mapping an existing
148500 + * region, this is a return value indicating the same thing. */
148501 + int has_locking;
148502 + /* In the case of a successful map with _CREATE and _LAZY, this return
148503 + * value indicates whether we created the mapped region or whether it
148504 + * already existed. */
148505 + int did_create;
148506 +};
148507 +
148508 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
148509 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
148510 +#endif
148511 +
148512 +
148513 +#define USDPAA_IOCTL_DMA_MAP \
148514 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
148515 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
148516 + * This ioctl will do both (though you can munmap() before calling the ioctl
148517 + * too). */
148518 +#define USDPAA_IOCTL_DMA_UNMAP \
148519 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
148520 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
148521 + * with a mmap()'d address, and the process will (interruptible) sleep if the
148522 + * lock is already held by another process. Process destruction will
148523 + * automatically clean up any held locks. */
148524 +#define USDPAA_IOCTL_DMA_LOCK \
148525 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
148526 +#define USDPAA_IOCTL_DMA_UNLOCK \
148527 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
148528 +
148529 +/***************************************/
148530 +/* Mapping and using QMan/BMan portals */
148531 +/***************************************/
148532 +enum usdpaa_portal_type {
148533 + usdpaa_portal_qman,
148534 + usdpaa_portal_bman,
148535 +};
148536 +
148537 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
148538 +
148539 +struct usdpaa_ioctl_portal_map {
148540 + /* Input parameter, is a qman or bman portal required. */
148541 +
148542 + enum usdpaa_portal_type type;
148543 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148544 + for don't care. The portal index will be populated by the
148545 + driver when the ioctl() successfully completes */
148546 + uint32_t index;
148547 +
148548 + /* Return value if the map succeeds, this gives the mapped
148549 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
148550 + struct usdpaa_portal_map {
148551 + void *cinh;
148552 + void *cena;
148553 + } addr;
148554 + /* Qman-specific return values */
148555 + uint16_t channel;
148556 + uint32_t pools;
148557 +};
148558 +
148559 +#ifdef CONFIG_COMPAT
148560 +struct compat_usdpaa_ioctl_portal_map {
148561 + /* Input parameter, is a qman or bman portal required. */
148562 + enum usdpaa_portal_type type;
148563 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148564 + for don't care. The portal index will be populated by the
148565 + driver when the ioctl() successfully completes */
148566 + uint32_t index;
148567 + /* Return value if the map succeeds, this gives the mapped
148568 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
148569 + struct usdpaa_portal_map_compat {
148570 + compat_uptr_t cinh;
148571 + compat_uptr_t cena;
148572 + } addr;
148573 + /* Qman-specific return values */
148574 + uint16_t channel;
148575 + uint32_t pools;
148576 +};
148577 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
148578 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
148579 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
148580 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
148581 +#endif
148582 +
148583 +#define USDPAA_IOCTL_PORTAL_MAP \
148584 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
148585 +#define USDPAA_IOCTL_PORTAL_UNMAP \
148586 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
148587 +
148588 +struct usdpaa_ioctl_irq_map {
148589 + enum usdpaa_portal_type type; /* Type of portal to map */
148590 + int fd; /* File descriptor that contains the portal */
148591 + void *portal_cinh; /* Cache inhibited area to identify the portal */
148592 +};
148593 +
148594 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
148595 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
148596 +
148597 +#ifdef CONFIG_COMPAT
148598 +
148599 +struct compat_ioctl_irq_map {
148600 + enum usdpaa_portal_type type; /* Type of portal to map */
148601 + compat_int_t fd; /* File descriptor that contains the portal */
148602 + compat_uptr_t portal_cinh; /* Used identify the portal */};
148603 +
148604 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
148605 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
148606 +#endif
148607 +
148608 +/* ioctl to query the amount of DMA memory used in the system */
148609 +struct usdpaa_ioctl_dma_used {
148610 + uint64_t free_bytes;
148611 + uint64_t total_bytes;
148612 +};
148613 +#define USDPAA_IOCTL_DMA_USED \
148614 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
148615 +
148616 +/* ioctl to allocate a raw portal */
148617 +struct usdpaa_ioctl_raw_portal {
148618 + /* inputs */
148619 + enum usdpaa_portal_type type; /* Type of portal to allocate */
148620 +
148621 + /* set to non zero to turn on stashing */
148622 + uint8_t enable_stash;
148623 + /* Stashing attributes for the portal */
148624 + uint32_t cpu;
148625 + uint32_t cache;
148626 + uint32_t window;
148627 +
148628 + /* Specifies the stash request queue this portal should use */
148629 + uint8_t sdest;
148630 +
148631 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148632 + * for don't care. The portal index will be populated by the
148633 + * driver when the ioctl() successfully completes */
148634 + uint32_t index;
148635 +
148636 + /* outputs */
148637 + uint64_t cinh;
148638 + uint64_t cena;
148639 +};
148640 +
148641 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
148642 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
148643 +
148644 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
148645 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
148646 +
148647 +#ifdef CONFIG_COMPAT
148648 +
148649 +struct compat_ioctl_raw_portal {
148650 + /* inputs */
148651 + enum usdpaa_portal_type type; /* Type of portal to allocate */
148652 +
148653 + /* set to non zero to turn on stashing */
148654 + uint8_t enable_stash;
148655 + /* Stashing attributes for the portal */
148656 + uint32_t cpu;
148657 + uint32_t cache;
148658 + uint32_t window;
148659 + /* Specifies the stash request queue this portal should use */
148660 + uint8_t sdest;
148661 +
148662 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
148663 + * for don't care. The portal index will be populated by the
148664 + * driver when the ioctl() successfully completes */
148665 + uint32_t index;
148666 +
148667 + /* outputs */
148668 + uint64_t cinh;
148669 + uint64_t cena;
148670 +};
148671 +
148672 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
148673 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
148674 +
148675 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
148676 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
148677 +
148678 +#endif
148679 +
148680 +#ifdef __KERNEL__
148681 +
148682 +/* Early-boot hook */
148683 +int __init fsl_usdpaa_init_early(void);
148684 +
148685 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
148686 + * faults within its ranges via this hook. */
148687 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
148688 +
148689 +#endif /* __KERNEL__ */
148690 +
148691 +#endif /* CONFIG_FSL_USDPAA */
148692 +
148693 +#ifdef __KERNEL__
148694 +/* This interface is needed in a few places and though it's not specific to
148695 + * USDPAA as such, creating a new header for it doesn't make any sense. The
148696 + * qbman kernel driver implements this interface and uses it as the backend for
148697 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
148698 + * interface for tracking per-process allocations handed out to user-space. */
148699 +struct dpa_alloc {
148700 + struct list_head free;
148701 + spinlock_t lock;
148702 + struct list_head used;
148703 +};
148704 +#define DECLARE_DPA_ALLOC(name) \
148705 + struct dpa_alloc name = { \
148706 + .free = { \
148707 + .prev = &name.free, \
148708 + .next = &name.free \
148709 + }, \
148710 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
148711 + .used = { \
148712 + .prev = &name.used, \
148713 + .next = &name.used \
148714 + } \
148715 + }
148716 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
148717 +{
148718 + INIT_LIST_HEAD(&alloc->free);
148719 + INIT_LIST_HEAD(&alloc->used);
148720 + spin_lock_init(&alloc->lock);
148721 +}
148722 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
148723 + int partial);
148724 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
148725 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
148726 +
148727 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
148728 + * desired range is not available, or 0 for success. */
148729 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
148730 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
148731 + * 'alloc' is empty. */
148732 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
148733 +/* Returns 1 if the specified id is alloced, 0 otherwise */
148734 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
148735 +#endif /* __KERNEL__ */
148736 +
148737 +#ifdef __cplusplus
148738 +}
148739 +#endif
148740 +
148741 +#endif /* FSL_USDPAA_H */
148742 --- /dev/null
148743 +++ b/include/uapi/linux/fmd/Kbuild
148744 @@ -0,0 +1,5 @@
148745 +header-y += integrations/
148746 +header-y += Peripherals/
148747 +
148748 +header-y += ioctls.h
148749 +header-y += net_ioctls.h
148750 --- /dev/null
148751 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
148752 @@ -0,0 +1,4 @@
148753 +header-y += fm_ioctls.h
148754 +header-y += fm_port_ioctls.h
148755 +header-y += fm_pcd_ioctls.h
148756 +header-y += fm_test_ioctls.h
148757 --- /dev/null
148758 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
148759 @@ -0,0 +1,628 @@
148760 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
148761 + * All rights reserved.
148762 + *
148763 + * Redistribution and use in source and binary forms, with or without
148764 + * modification, are permitted provided that the following conditions are met:
148765 + * * Redistributions of source code must retain the above copyright
148766 + * notice, this list of conditions and the following disclaimer.
148767 + * * Redistributions in binary form must reproduce the above copyright
148768 + * notice, this list of conditions and the following disclaimer in the
148769 + * documentation and/or other materials provided with the distribution.
148770 + * * Neither the name of Freescale Semiconductor nor the
148771 + * names of its contributors may be used to endorse or promote products
148772 + * derived from this software without specific prior written permission.
148773 + *
148774 + *
148775 + * ALTERNATIVELY, this software may be distributed under the terms of the
148776 + * GNU General Public License ("GPL") as published by the Free Software
148777 + * Foundation, either version 2 of that License or (at your option) any
148778 + * later version.
148779 + *
148780 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
148781 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
148782 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
148783 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
148784 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
148785 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
148786 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
148787 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
148788 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
148789 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
148790 + */
148791 +
148792 +/**************************************************************************//**
148793 + @File fm_ioctls.h
148794 +
148795 + @Description FM Char device ioctls
148796 +*//***************************************************************************/
148797 +#ifndef __FM_IOCTLS_H
148798 +#define __FM_IOCTLS_H
148799 +
148800 +
148801 +/**************************************************************************//**
148802 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
148803 +
148804 + @Description FM Linux ioctls definitions and enums
148805 +
148806 + @{
148807 +*//***************************************************************************/
148808 +
148809 +/**************************************************************************//**
148810 + @Collection FM IOCTL device ('/dev') definitions
148811 +*//***************************************************************************/
148812 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
148813 +
148814 +#define DEV_FM_MINOR_BASE 0
148815 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
148816 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
148817 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
148818 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
148819 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
148820 +
148821 +#define FM_IOC_NUM(n) (n)
148822 +#define FM_PCD_IOC_NUM(n) (n+20)
148823 +#define FM_PORT_IOC_NUM(n) (n+70)
148824 +/* @} */
148825 +
148826 +#define IOC_FM_MAX_NUM_OF_PORTS 64
148827 +
148828 +
148829 +/**************************************************************************//**
148830 + @Description Enum for defining port types
148831 + (must match enum e_FmPortType defined in fm_ext.h)
148832 +*//***************************************************************************/
148833 +typedef enum ioc_fm_port_type {
148834 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
148835 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
148836 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
148837 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
148838 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
148839 + e_IOC_FM_PORT_TYPE_DUMMY
148840 +} ioc_fm_port_type;
148841 +
148842 +
148843 +/**************************************************************************//**
148844 + @Group lnx_ioctl_FM_lib_grp FM library
148845 +
148846 + @Description FM API functions, definitions and enums
148847 + The FM module is the main driver module and is a mandatory module
148848 + for FM driver users. Before any further module initialization,
148849 + this module must be initialized.
148850 + The FM is a "single-tone" module. It is responsible of the common
148851 + HW modules: FPM, DMA, common QMI, common BMI initializations and
148852 + run-time control routines. This module must be initialized always
148853 + when working with any of the FM modules.
148854 + NOTE - We assumes that the FML will be initialize only by core No. 0!
148855 +
148856 + @{
148857 +*//***************************************************************************/
148858 +
148859 +/**************************************************************************//**
148860 + @Description FM Exceptions
148861 +*//***************************************************************************/
148862 +typedef enum ioc_fm_exceptions {
148863 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
148864 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
148865 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
148866 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
148867 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
148868 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
148869 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
148870 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
148871 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
148872 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
148873 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
148874 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
148875 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
148876 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
148877 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
148878 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
148879 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
148880 +} ioc_fm_exceptions;
148881 +
148882 +/**************************************************************************//**
148883 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
148884 +
148885 + @Description FM Runtime control unit API functions, definitions and enums.
148886 + The FM driver provides a set of control routines for each module.
148887 + These routines may only be called after the module was fully
148888 + initialized (both configuration and initialization routines were
148889 + called). They are typically used to get information from hardware
148890 + (status, counters/statistics, revision etc.), to modify a current
148891 + state or to force/enable a required action. Run-time control may
148892 + be called whenever necessary and as many times as needed.
148893 + @{
148894 +*//***************************************************************************/
148895 +
148896 +/**************************************************************************//**
148897 + @Collection General FM defines.
148898 + *//***************************************************************************/
148899 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
148900 + FM_MAX_NUM_OF_1G_RX_PORTS + \
148901 + FM_MAX_NUM_OF_10G_RX_PORTS + \
148902 + FM_MAX_NUM_OF_1G_TX_PORTS + \
148903 + FM_MAX_NUM_OF_10G_TX_PORTS)
148904 +/* @} */
148905 +
148906 +/**************************************************************************//**
148907 + @Description Structure for Port bandwidth requirement. Port is identified
148908 + by type and relative id.
148909 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
148910 +*//***************************************************************************/
148911 +typedef struct ioc_fm_port_bandwidth_t {
148912 + ioc_fm_port_type type; /**< FM port type */
148913 + uint8_t relative_port_id; /**< Type relative port id */
148914 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
148915 +} ioc_fm_port_bandwidth_t;
148916 +
148917 +/**************************************************************************//**
148918 + @Description A Structure containing an array of Port bandwidth requirements.
148919 + The user should state the ports requiring bandwidth in terms of
148920 + percentage - i.e. all port's bandwidths in the array must add
148921 + up to 100.
148922 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
148923 +*//***************************************************************************/
148924 +typedef struct ioc_fm_port_bandwidth_params {
148925 + uint8_t num_of_ports;
148926 + /**< num of ports listed in the array below */
148927 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
148928 + /**< for each port, it's bandwidth (all port's
148929 + bandwidths must add up to 100.*/
148930 +} ioc_fm_port_bandwidth_params;
148931 +
148932 +/**************************************************************************//**
148933 + @Description enum for defining FM counters
148934 +*//***************************************************************************/
148935 +typedef enum ioc_fm_counters {
148936 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
148937 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
148938 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
148939 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
148940 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
148941 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
148942 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
148943 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
148944 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
148945 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
148946 +} ioc_fm_counters;
148947 +
148948 +typedef struct ioc_fm_obj_t {
148949 + void *obj;
148950 +} ioc_fm_obj_t;
148951 +
148952 +/**************************************************************************//**
148953 + @Description A structure for returning revision information
148954 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
148955 +*//***************************************************************************/
148956 +typedef struct ioc_fm_revision_info_t {
148957 + uint8_t major; /**< Major revision */
148958 + uint8_t minor; /**< Minor revision */
148959 +} ioc_fm_revision_info_t;
148960 +
148961 +/**************************************************************************//**
148962 + @Description A structure for FM counters
148963 +*//***************************************************************************/
148964 +typedef struct ioc_fm_counters_params_t {
148965 + ioc_fm_counters cnt; /**< The requested counter */
148966 + uint32_t val; /**< The requested value to get/set from/into the counter */
148967 +} ioc_fm_counters_params_t;
148968 +
148969 +typedef union ioc_fm_api_version_t {
148970 + struct {
148971 + uint8_t major;
148972 + uint8_t minor;
148973 + uint8_t respin;
148974 + uint8_t reserved;
148975 + } version;
148976 + uint32_t ver;
148977 +} ioc_fm_api_version_t;
148978 +
148979 +#if (DPAA_VERSION >= 11)
148980 +/**************************************************************************//**
148981 + @Description A structure of information about each of the external
148982 + buffer pools used by a port or storage-profile.
148983 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
148984 +*//***************************************************************************/
148985 +typedef struct ioc_fm_ext_pool_params {
148986 + uint8_t id; /**< External buffer pool id */
148987 + uint16_t size; /**< External buffer pool buffer size */
148988 +} ioc_fm_ext_pool_params;
148989 +
148990 +/**************************************************************************//**
148991 + @Description A structure for informing the driver about the external
148992 + buffer pools allocated in the BM and used by a port or a
148993 + storage-profile.
148994 + (must be identical to t_FmExtPools defined in fm_ext.h)
148995 +*//***************************************************************************/
148996 +typedef struct ioc_fm_ext_pools {
148997 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
148998 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
148999 + /**< Parameters for each port */
149000 +} ioc_fm_ext_pools;
149001 +
149002 +typedef struct ioc_fm_vsp_params_t {
149003 + void *p_fm; /**< A handle to the FM object this VSP related to */
149004 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
149005 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
149006 + parameter associated with Rx / OP port */
149007 + uint16_t liodn_offset; /**< VSP's LIODN offset */
149008 + struct {
149009 + ioc_fm_port_type port_type; /**< Port type */
149010 + uint8_t port_id; /**< Port Id - relative to type */
149011 + } port_params;
149012 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
149013 + defined in relevant FM object */
149014 + void *id; /**< return value */
149015 +} ioc_fm_vsp_params_t;
149016 +#endif /* (DPAA_VERSION >= 11) */
149017 +
149018 +/**************************************************************************//**
149019 + @Description A structure for defining BM pool depletion criteria
149020 +*//***************************************************************************/
149021 +typedef struct ioc_fm_buf_pool_depletion_t {
149022 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
149023 + a number of pools (all together!) are depleted */
149024 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
149025 + pause frames transmission. */
149026 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
149027 + /**< For each pool, TRUE if it should be considered for
149028 + depletion (Note - this pool must be used by this port!). */
149029 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
149030 + a single-pool is depleted; */
149031 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
149032 + /**< For each pool, TRUE if it should be considered for
149033 + depletion (Note - this pool must be used by this port!) */
149034 +#if (DPAA_VERSION >= 11)
149035 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
149036 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
149037 + which is transmitted */
149038 +#endif /* (DPAA_VERSION >= 11) */
149039 +} ioc_fm_buf_pool_depletion_t;
149040 +
149041 +#if (DPAA_VERSION >= 11)
149042 +typedef struct ioc_fm_buf_pool_depletion_params_t {
149043 + void *p_fm_vsp;
149044 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
149045 +} ioc_fm_buf_pool_depletion_params_t;
149046 +#endif /* (DPAA_VERSION >= 11) */
149047 +
149048 +typedef struct ioc_fm_buffer_prefix_content_t {
149049 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
149050 + of the external buffer; Note that the private-area will
149051 + start from the base of the buffer address. */
149052 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
149053 + User may use FM_PORT_GetBufferPrsResult() in order to
149054 + get the parser-result from a buffer. */
149055 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
149056 + User may use FM_PORT_GetBufferTimeStamp() in order to
149057 + get the parser-result from a buffer. */
149058 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
149059 + User may use FM_PORT_GetBufferHashResult() in order to
149060 + get the parser-result from a buffer. */
149061 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
149062 + AD, hash-result, key, etc. */
149063 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
149064 + other value for selecting a data alignment (must be a power of 2);
149065 + if write optimization is used, must be >= 16. */
149066 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
149067 + Note that this field impacts the size of the buffer-prefix
149068 + (i.e. it pushes the data offset);
149069 + This field is irrelevant if DPAA_VERSION==10 */
149070 +} ioc_fm_buffer_prefix_content_t;
149071 +
149072 +typedef struct ioc_fm_buffer_prefix_content_params_t {
149073 + void *p_fm_vsp;
149074 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
149075 +} ioc_fm_buffer_prefix_content_params_t;
149076 +
149077 +#if (DPAA_VERSION >= 11)
149078 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
149079 + void *p_fm_vsp;
149080 + bool no_sg;
149081 +} ioc_fm_vsp_config_no_sg_params_t;
149082 +
149083 +typedef struct ioc_fm_vsp_prs_result_params_t {
149084 + void *p_fm_vsp;
149085 + void *p_data;
149086 +} ioc_fm_vsp_prs_result_params_t;
149087 +#endif
149088 +
149089 +typedef struct fm_ctrl_mon_t {
149090 + uint8_t percent_cnt[2];
149091 +} fm_ctrl_mon_t;
149092 +
149093 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
149094 + uint8_t fm_ctrl_index;
149095 + fm_ctrl_mon_t *p_mon;
149096 +} ioc_fm_ctrl_mon_counters_params_t;
149097 +
149098 +/**************************************************************************//**
149099 + @Function FM_IOC_SET_PORTS_BANDWIDTH
149100 +
149101 + @Description Sets relative weights between ports when accessing common resources.
149102 +
149103 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
149104 + their sum must equal 100.
149105 +
149106 + @Return E_OK on success; Error code otherwise.
149107 +
149108 + @Cautions Allowed only following FM_Init().
149109 +*//***************************************************************************/
149110 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
149111 +
149112 +/**************************************************************************//**
149113 + @Function FM_IOC_GET_REVISION
149114 +
149115 + @Description Returns the FM revision
149116 +
149117 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
149118 +
149119 + @Return None.
149120 +
149121 + @Cautions Allowed only following FM_Init().
149122 +*//***************************************************************************/
149123 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
149124 +
149125 +/**************************************************************************//**
149126 + @Function FM_IOC_GET_COUNTER
149127 +
149128 + @Description Reads one of the FM counters.
149129 +
149130 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
149131 +
149132 + @Return Counter's current value.
149133 +
149134 + @Cautions Allowed only following FM_Init().
149135 + Note that it is user's responsibilty to call this routine only
149136 + for enabled counters, and there will be no indication if a
149137 + disabled counter is accessed.
149138 +*//***************************************************************************/
149139 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
149140 +
149141 +/**************************************************************************//**
149142 + @Function FM_IOC_SET_COUNTER
149143 +
149144 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
149145 +
149146 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
149147 +
149148 + @Return E_OK on success; Error code otherwise.
149149 +
149150 + @Cautions Allowed only following FM_Init().
149151 +*//***************************************************************************/
149152 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
149153 +
149154 +/**************************************************************************//**
149155 + @Function FM_IOC_FORCE_INTR
149156 +
149157 + @Description Causes an interrupt event on the requested source.
149158 +
149159 + @Param[in] ioc_fm_exceptions An exception to be forced.
149160 +
149161 + @Return E_OK on success; Error code if the exception is not enabled,
149162 + or is not able to create interrupt.
149163 +
149164 + @Cautions Allowed only following FM_Init().
149165 +*//***************************************************************************/
149166 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
149167 +
149168 +/**************************************************************************//**
149169 + @Function FM_IOC_GET_API_VERSION
149170 +
149171 + @Description Reads the FMD IOCTL API version.
149172 +
149173 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
149174 +
149175 + @Return Version's value.
149176 +*//***************************************************************************/
149177 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
149178 +
149179 +#if (DPAA_VERSION >= 11)
149180 +/**************************************************************************//**
149181 + @Function FM_VSP_Config
149182 +
149183 + @Description Creates descriptor for the FM VSP module.
149184 +
149185 + The routine returns a handle (descriptor) to the FM VSP object.
149186 + This descriptor must be passed as first parameter to all other
149187 + FM VSP function calls.
149188 +
149189 + No actual initialization or configuration of FM hardware is
149190 + done by this routine.
149191 +
149192 +@Param[in] p_FmVspParams Pointer to data structure of parameters
149193 +
149194 + @Retval Handle to FM VSP object, or NULL for Failure.
149195 +*//***************************************************************************/
149196 +#if defined(CONFIG_COMPAT)
149197 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
149198 +#endif
149199 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
149200 +
149201 +/**************************************************************************//**
149202 + @Function FM_VSP_Init
149203 +
149204 + @Description Initializes the FM VSP module
149205 +
149206 + @Param[in] h_FmVsp - FM VSP module descriptor
149207 +
149208 + @Return E_OK on success; Error code otherwise.
149209 +*//***************************************************************************/
149210 +#if defined(CONFIG_COMPAT)
149211 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
149212 +#endif
149213 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
149214 +
149215 +/**************************************************************************//**
149216 + @Function FM_VSP_Free
149217 +
149218 + @Description Frees all resources that were assigned to FM VSP module.
149219 +
149220 + Calling this routine invalidates the descriptor.
149221 +
149222 + @Param[in] h_FmVsp - FM VSP module descriptor
149223 +
149224 + @Return E_OK on success; Error code otherwise.
149225 +*//***************************************************************************/
149226 +#if defined(CONFIG_COMPAT)
149227 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
149228 +#endif
149229 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
149230 +
149231 +/**************************************************************************//**
149232 + @Function FM_VSP_ConfigPoolDepletion
149233 +
149234 + @Description Calling this routine enables pause frame generation depending on the
149235 + depletion status of BM pools. It also defines the conditions to activate
149236 + this functionality. By default, this functionality is disabled.
149237 +
149238 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
149239 +
149240 + @Return E_OK on success; Error code otherwise.
149241 +
149242 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149243 +*//***************************************************************************/
149244 +#if defined(CONFIG_COMPAT)
149245 +#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)
149246 +#endif
149247 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
149248 +
149249 +/**************************************************************************//**
149250 + @Function FM_VSP_ConfigBufferPrefixContent
149251 +
149252 + @Description Defines the structure, size and content of the application buffer.
149253 +
149254 + The prefix will
149255 + In VSPs defined for Tx ports, if 'passPrsResult', the application
149256 + should set a value to their offsets in the prefix of
149257 + the FM will save the first 'privDataSize', than,
149258 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
149259 + and timeStamp, and the packet itself (in this order), to the
149260 + application buffer, and to offset.
149261 +
149262 + Calling this routine changes the buffer margins definitions
149263 + in the internal driver data base from its default
149264 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
149265 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
149266 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
149267 +
149268 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
149269 +
149270 + @Return E_OK on success; Error code otherwise.
149271 +
149272 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149273 +*//***************************************************************************/
149274 +#if defined(CONFIG_COMPAT)
149275 +#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)
149276 +#endif
149277 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
149278 +
149279 +/**************************************************************************//**
149280 + @Function FM_VSP_ConfigNoScatherGather
149281 +
149282 + @Description Calling this routine changes the possibility to receive S/G frame
149283 + in the internal driver data base
149284 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
149285 +
149286 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
149287 +
149288 + @Return E_OK on success; Error code otherwise.
149289 +
149290 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149291 +*//***************************************************************************/
149292 +#if defined(CONFIG_COMPAT)
149293 +#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)
149294 +#endif
149295 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
149296 +
149297 +/**************************************************************************//**
149298 + @Function FM_VSP_GetBufferPrsResult
149299 +
149300 + @Description Returns the pointer to the parse result in the data buffer.
149301 + In Rx ports this is relevant after reception, if parse
149302 + result is configured to be part of the data passed to the
149303 + application. For non Rx ports it may be used to get the pointer
149304 + of the area in the buffer where parse result should be
149305 + initialized - if so configured.
149306 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
149307 + configuration.
149308 +
149309 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
149310 +
149311 + @Return Parse result pointer on success, NULL if parse result was not
149312 + configured for this port.
149313 +
149314 + @Cautions Allowed only following FM_VSP_Init().
149315 +*//***************************************************************************/
149316 +#if defined(CONFIG_COMPAT)
149317 +#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)
149318 +#endif
149319 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
149320 +#endif /* (DPAA_VERSION >= 11) */
149321 +
149322 +/**************************************************************************//**
149323 + @Function FM_CtrlMonStart
149324 +
149325 + @Description Start monitoring utilization of all available FM controllers.
149326 +
149327 + In order to obtain FM controllers utilization the following sequence
149328 + should be used:
149329 + -# FM_CtrlMonStart()
149330 + -# FM_CtrlMonStop()
149331 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149332 +
149333 + @Return E_OK on success; Error code otherwise.
149334 +
149335 + @Cautions Allowed only following FM_Init().
149336 +*//***************************************************************************/
149337 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
149338 +
149339 +
149340 +/**************************************************************************//**
149341 + @Function FM_CtrlMonStop
149342 +
149343 + @Description Stop monitoring utilization of all available FM controllers.
149344 +
149345 + In order to obtain FM controllers utilization the following sequence
149346 + should be used:
149347 + -# FM_CtrlMonStart()
149348 + -# FM_CtrlMonStop()
149349 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149350 +
149351 + @Return E_OK on success; Error code otherwise.
149352 +
149353 + @Cautions Allowed only following FM_Init().
149354 +*//***************************************************************************/
149355 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
149356 +
149357 +/**************************************************************************//**
149358 + @Function FM_CtrlMonGetCounters
149359 +
149360 + @Description Obtain FM controller utilization parameters.
149361 +
149362 + In order to obtain FM controllers utilization the following sequence
149363 + should be used:
149364 + -# FM_CtrlMonStart()
149365 + -# FM_CtrlMonStop()
149366 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149367 +
149368 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
149369 +
149370 + @Return E_OK on success; Error code otherwise.
149371 +
149372 + @Cautions Allowed only following FM_Init().
149373 +*//***************************************************************************/
149374 +#if defined(CONFIG_COMPAT)
149375 +#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)
149376 +#endif
149377 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
149378 +
149379 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
149380 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
149381 +/** @} */ /* end of lnx_ioctl_FM_grp */
149382 +
149383 +#define FMD_API_VERSION_MAJOR 21
149384 +#define FMD_API_VERSION_MINOR 1
149385 +#define FMD_API_VERSION_RESPIN 0
149386 +
149387 +#endif /* __FM_IOCTLS_H */
149388 --- /dev/null
149389 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
149390 @@ -0,0 +1,3084 @@
149391 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149392 + * All rights reserved.
149393 + *
149394 + * Redistribution and use in source and binary forms, with or without
149395 + * modification, are permitted provided that the following conditions are met:
149396 + * * Redistributions of source code must retain the above copyright
149397 + * notice, this list of conditions and the following disclaimer.
149398 + * * Redistributions in binary form must reproduce the above copyright
149399 + * notice, this list of conditions and the following disclaimer in the
149400 + * documentation and/or other materials provided with the distribution.
149401 + * * Neither the name of Freescale Semiconductor nor the
149402 + * names of its contributors may be used to endorse or promote products
149403 + * derived from this software without specific prior written permission.
149404 + *
149405 + *
149406 + * ALTERNATIVELY, this software may be distributed under the terms of the
149407 + * GNU General Public License ("GPL") as published by the Free Software
149408 + * Foundation, either version 2 of that License or (at your option) any
149409 + * later version.
149410 + *
149411 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149412 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149413 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149414 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149415 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149416 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149417 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149418 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149419 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149420 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149421 + */
149422 +
149423 +
149424 +/******************************************************************************
149425 + @File fm_pcd_ioctls.h
149426 +
149427 + @Description FM PCD ...
149428 +*//***************************************************************************/
149429 +#ifndef __FM_PCD_IOCTLS_H
149430 +#define __FM_PCD_IOCTLS_H
149431 +
149432 +#include "net_ioctls.h"
149433 +#include "fm_ioctls.h"
149434 +
149435 +
149436 +/**************************************************************************//**
149437 +
149438 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149439 +
149440 + @Description Frame Manager Linux ioctls definitions and enums
149441 +
149442 + @{
149443 +*//***************************************************************************/
149444 +
149445 +/**************************************************************************//**
149446 + @Group lnx_ioctl_FM_PCD_grp FM PCD
149447 +
149448 + @Description Frame Manager PCD API functions, definitions and enums
149449 +
149450 + The FM PCD module is responsible for the initialization of all
149451 + global classifying FM modules. This includes the parser general and
149452 + common registers, the key generator global and common registers,
149453 + and the policer global and common registers.
149454 + In addition, the FM PCD SW module will initialize all required
149455 + key generator schemes, coarse classification flows, and policer
149456 + profiles. When an FM module is configured to work with one of these
149457 + entities, it will register to it using the FM PORT API. The PCD
149458 + module will manage the PCD resources - i.e. resource management of
149459 + KeyGen schemes, etc.
149460 +
149461 + @{
149462 +*//***************************************************************************/
149463 +
149464 +/**************************************************************************//**
149465 + @Collection General PCD defines
149466 +*//***************************************************************************/
149467 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
149468 +
149469 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
149470 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
149471 + /**< Number of distinction units is limited by
149472 + register size (32 bits) minus reserved bits
149473 + for private headers. */
149474 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
149475 + in a distinction unit */
149476 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
149477 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
149478 + For HW implementation reasons, in most
149479 + cases less than this will be allowed; The
149480 + driver will return an initialization error
149481 + if resource is unavailable. */
149482 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
149483 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
149484 +
149485 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
149486 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
149487 +
149488 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
149489 + insert manipulation */
149490 +
149491 +#if DPAA_VERSION >= 11
149492 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
149493 +#endif /* DPAA_VERSION >= 11 */
149494 +/* @} */
149495 +
149496 +#ifdef FM_CAPWAP_SUPPORT
149497 +#error "FM_CAPWAP_SUPPORT not implemented!"
149498 +#endif
149499 +
149500 +
149501 +/**************************************************************************//**
149502 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
149503 +
149504 + @Description Frame Manager PCD Initialization Unit API
149505 +
149506 + @{
149507 +*//***************************************************************************/
149508 +
149509 +/**************************************************************************//**
149510 + @Description PCD counters
149511 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
149512 +*//***************************************************************************/
149513 +typedef enum ioc_fm_pcd_counters {
149514 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
149515 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
149516 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
149517 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
149518 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
149519 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
149520 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
149521 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
149522 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
149523 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
149524 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
149525 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
149526 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
149527 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
149528 + 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. */
149529 + 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. */
149530 + 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. */
149531 + 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. */
149532 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
149533 + 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. */
149534 + 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). */
149535 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
149536 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
149537 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
149538 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
149539 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
149540 +} ioc_fm_pcd_counters;
149541 +
149542 +/**************************************************************************//**
149543 + @Description PCD interrupts
149544 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
149545 +*//***************************************************************************/
149546 +typedef enum ioc_fm_pcd_exceptions {
149547 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
149548 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
149549 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
149550 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
149551 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
149552 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
149553 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
149554 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
149555 +} ioc_fm_pcd_exceptions;
149556 +
149557 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
149558 +
149559 +
149560 +/**************************************************************************//**
149561 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
149562 +
149563 + @Description Frame Manager PCD Runtime Unit
149564 +
149565 + The runtime control allows creation of PCD infrastructure modules
149566 + such as Network Environment Characteristics, Classification Plan
149567 + Groups and Coarse Classification Trees.
149568 + It also allows on-the-fly initialization, modification and removal
149569 + of PCD modules such as KeyGen schemes, coarse classification nodes
149570 + and Policer profiles.
149571 +
149572 + In order to explain the programming model of the PCD driver interface
149573 + a few terms should be explained, and will be used below.
149574 + - Distinction Header - One of the 16 protocols supported by the FM parser,
149575 + or one of the SHIM headers (1 or 2). May be a header with a special
149576 + option (see below).
149577 + - Interchangeable Headers Group - This is a group of Headers recognized
149578 + by either one of them. For example, if in a specific context the user
149579 + chooses to treat IPv4 and IPV6 in the same way, they may create an
149580 + interchangeable Headers Unit consisting of these 2 headers.
149581 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
149582 + Group.
149583 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
149584 + IPv6, includes multicast, broadcast and other protocol specific options.
149585 + In terms of hardware it relates to the options available in the classification
149586 + plan.
149587 + - Network Environment Characteristics - a set of Distinction Units that define
149588 + the total recognizable header selection for a certain environment. This is
149589 + NOT the list of all headers that will ever appear in a flow, but rather
149590 + everything that needs distinction in a flow, where distinction is made by KeyGen
149591 + schemes and coarse classification action descriptors.
149592 +
149593 + The PCD runtime modules initialization is done in stages. The first stage after
149594 + initializing the PCD module itself is to establish a Network Flows Environment
149595 + Definition. The application may choose to establish one or more such environments.
149596 + Later, when needed, the application will have to state, for some of its modules,
149597 + to which single environment it belongs.
149598 +
149599 + @{
149600 +*//***************************************************************************/
149601 +
149602 +
149603 +/**************************************************************************//**
149604 + @Description structure for FM counters
149605 +*//***************************************************************************/
149606 +typedef struct ioc_fm_pcd_counters_params_t {
149607 + ioc_fm_pcd_counters cnt; /**< The requested counter */
149608 + uint32_t val; /**< The requested value to get/set from/into the counter */
149609 +} ioc_fm_pcd_counters_params_t;
149610 +
149611 +/**************************************************************************//**
149612 + @Description structure for FM exception definitios
149613 +*//***************************************************************************/
149614 +typedef struct ioc_fm_pcd_exception_params_t {
149615 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
149616 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
149617 +} ioc_fm_pcd_exception_params_t;
149618 +
149619 +/**************************************************************************//**
149620 + @Description A structure for SW parser labels
149621 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
149622 + *//***************************************************************************/
149623 +typedef struct ioc_fm_pcd_prs_label_params_t {
149624 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
149625 + resolution), relative to Parser RAM. */
149626 + ioc_net_header_type hdr; /**< The existence of this header will invoke
149627 + the SW parser code. */
149628 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
149629 + attachments for the same header, use this
149630 + index to distinguish between them. */
149631 +} ioc_fm_pcd_prs_label_params_t;
149632 +
149633 +/**************************************************************************//**
149634 + @Description A structure for SW parser
149635 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
149636 + *//***************************************************************************/
149637 +typedef struct ioc_fm_pcd_prs_sw_params_t {
149638 + bool override; /**< FALSE to invoke a check that nothing else
149639 + was loaded to this address, including
149640 + internal patches.
149641 + TRUE to override any existing code.*/
149642 + uint32_t size; /**< SW parser code size */
149643 + uint16_t base; /**< SW parser base (in instruction counts!
149644 + must be larger than 0x20)*/
149645 + uint8_t *p_code; /**< SW parser code */
149646 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
149647 + /**< SW parser data (parameters) */
149648 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
149649 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
149650 + /**< SW parser labels table,
149651 + containing num_of_labels entries */
149652 +} ioc_fm_pcd_prs_sw_params_t;
149653 +
149654 +/**************************************************************************//**
149655 + @Description A structure to set the a KeyGen default value
149656 + *//***************************************************************************/
149657 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
149658 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
149659 + uint32_t value; /**< The requested default value */
149660 +} ioc_fm_pcd_kg_dflt_value_params_t;
149661 +
149662 +
149663 +/**************************************************************************//**
149664 + @Function FM_PCD_Enable
149665 +
149666 + @Description This routine should be called after PCD is initialized for enabling all
149667 + PCD engines according to their existing configuration.
149668 +
149669 + @Return 0 on success; Error code otherwise.
149670 +
149671 + @Cautions Allowed only when PCD is disabled.
149672 +*//***************************************************************************/
149673 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
149674 +
149675 +/**************************************************************************//**
149676 + @Function FM_PCD_Disable
149677 +
149678 + @Description This routine may be called when PCD is enabled in order to
149679 + disable all PCD engines. It may be called
149680 + only when none of the ports in the system are using the PCD.
149681 +
149682 + @Return 0 on success; Error code otherwise.
149683 +
149684 + @Cautions Allowed only when PCD is enabled.
149685 +*//***************************************************************************/
149686 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
149687 +
149688 + /**************************************************************************//**
149689 + @Function FM_PCD_PrsLoadSw
149690 +
149691 + @Description This routine may be called only when all ports in the
149692 + system are actively using the classification plan scheme.
149693 + In such cases it is recommended in order to save resources.
149694 + The driver automatically saves 8 classification plans for
149695 + ports that do NOT use the classification plan mechanism, to
149696 + avoid this (in order to save those entries) this routine may
149697 + be called.
149698 +
149699 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
149700 +
149701 + @Return 0 on success; Error code otherwise.
149702 +
149703 + @Cautions Allowed only when PCD is disabled.
149704 +*//***************************************************************************/
149705 +#if defined(CONFIG_COMPAT)
149706 +#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)
149707 +#endif
149708 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
149709 +
149710 +/**************************************************************************//**
149711 + @Function FM_PCD_KgSetDfltValue
149712 +
149713 + @Description Calling this routine sets a global default value to be used
149714 + by the KeyGen when parser does not recognize a required
149715 + field/header.
149716 + By default default values are 0.
149717 +
149718 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
149719 +
149720 + @Return 0 on success; Error code otherwise.
149721 +
149722 + @Cautions Allowed only when PCD is disabled.
149723 +*//***************************************************************************/
149724 +#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)
149725 +
149726 +/**************************************************************************//**
149727 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
149728 +
149729 + @Description Calling this routine allows the keygen to access data past
149730 + the parser finishing point.
149731 +
149732 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
149733 +
149734 + @Return 0 on success; Error code otherwise.
149735 +
149736 + @Cautions Allowed only when PCD is disabled.
149737 +*//***************************************************************************/
149738 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
149739 +
149740 +/**************************************************************************//**
149741 + @Function FM_PCD_SetException
149742 +
149743 + @Description Calling this routine enables/disables PCD interrupts.
149744 +
149745 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
149746 +
149747 + @Return 0 on success; Error code otherwise.
149748 +*//***************************************************************************/
149749 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
149750 +
149751 +/**************************************************************************//**
149752 + @Function FM_PCD_GetCounter
149753 +
149754 + @Description Reads one of the FM PCD counters.
149755 +
149756 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
149757 +
149758 + @Return 0 on success; Error code otherwise.
149759 +
149760 + @Cautions Note that it is user's responsibilty to call this routine only
149761 + for enabled counters, and there will be no indication if a
149762 + disabled counter is accessed.
149763 +*//***************************************************************************/
149764 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
149765 +
149766 +/**************************************************************************//**
149767 +
149768 + @Function FM_PCD_KgSchemeGetCounter
149769 +
149770 + @Description Reads scheme packet counter.
149771 +
149772 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
149773 +
149774 + @Return Counter's current value.
149775 +
149776 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
149777 +*//***************************************************************************/
149778 +#if defined(CONFIG_COMPAT)
149779 +#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)
149780 +#endif
149781 +#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)
149782 +
149783 +#if 0
149784 +TODO: unused IOCTL
149785 +/**************************************************************************//**
149786 + @Function FM_PCD_ModifyCounter
149787 +
149788 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
149789 +
149790 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
149791 +
149792 + @Return 0 on success; Error code otherwise.
149793 +*//***************************************************************************/
149794 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
149795 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
149796 +#endif
149797 +
149798 +/**************************************************************************//**
149799 + @Function FM_PCD_ForceIntr
149800 +
149801 + @Description Causes an interrupt event on the requested source.
149802 +
149803 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
149804 +
149805 + @Return 0 on success; error code if the exception is not enabled,
149806 + or is not able to create interrupt.
149807 +*//***************************************************************************/
149808 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
149809 +
149810 +/**************************************************************************//**
149811 + @Collection Definitions of coarse classification parameters as required by KeyGen
149812 + (when coarse classification is the next engine after this scheme).
149813 +*//***************************************************************************/
149814 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
149815 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
149816 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
149817 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
149818 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
149819 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
149820 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
149821 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
149822 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
149823 +/* @} */
149824 +
149825 +/**************************************************************************//**
149826 + @Collection A set of definitions to allow protocol
149827 + special option description.
149828 +*//***************************************************************************/
149829 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
149830 +
149831 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
149832 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
149833 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
149834 +
149835 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
149836 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
149837 +
149838 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
149839 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
149840 +
149841 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
149842 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
149843 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
149844 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
149845 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
149846 +
149847 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
149848 + IPV4 Reassembly manipulation requires network
149849 + environment with IPV4 header and IPV4_FRAG_1 option */
149850 +
149851 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
149852 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
149853 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
149854 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
149855 +
149856 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
149857 + IPV6 Reassembly manipulation requires network
149858 + environment with IPV6 header and IPV6_FRAG_1 option */
149859 +#if (DPAA_VERSION >= 11)
149860 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
149861 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
149862 + CAPWAP Reassembly manipulation requires network
149863 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
149864 + in case where fragment found, the fragment-extension offset
149865 + may be found at 'shim2' (in parser-result). */
149866 +#endif /* (DPAA_VERSION >= 11) */
149867 +
149868 +/* @} */
149869 +
149870 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
149871 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
149872 +/**************************************************************************//**
149873 + @Collection A set of definitions to support Header Manipulation selection.
149874 +*//***************************************************************************/
149875 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
149876 +
149877 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
149878 +
149879 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
149880 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
149881 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
149882 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
149883 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
149884 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
149885 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
149886 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
149887 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
149888 +
149889 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
149890 +
149891 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
149892 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
149893 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
149894 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
149895 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
149896 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
149897 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
149898 +
149899 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
149900 +
149901 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
149902 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
149903 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
149904 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
149905 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
149906 +
149907 +/* @} */
149908 +
149909 +/**************************************************************************//**
149910 + @Description A type used for returning the order of the key extraction.
149911 + each value in this array represents the index of the extraction
149912 + command as defined by the user in the initialization extraction array.
149913 + The valid size of this array is the user define number of extractions
149914 + required (also marked by the second '0' in this array).
149915 +*//***************************************************************************/
149916 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
149917 +
149918 +/**************************************************************************//**
149919 + @Description All PCD engines
149920 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
149921 +*//***************************************************************************/
149922 +typedef enum ioc_fm_pcd_engine {
149923 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
149924 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
149925 + e_IOC_FM_PCD_KG, /**< KeyGen */
149926 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
149927 + e_IOC_FM_PCD_PLCR, /**< Policer */
149928 + e_IOC_FM_PCD_PRS, /**< Parser */
149929 +#if DPAA_VERSION >= 11
149930 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
149931 +#endif /* DPAA_VERSION >= 11 */
149932 + e_IOC_FM_PCD_HASH /**< Hash Table */
149933 +} ioc_fm_pcd_engine;
149934 +
149935 +/**************************************************************************//**
149936 + @Description An enum for selecting extraction by header types
149937 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
149938 +*//***************************************************************************/
149939 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
149940 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
149941 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
149942 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
149943 +} ioc_fm_pcd_extract_by_hdr_type;
149944 +
149945 +/**************************************************************************//**
149946 + @Description An enum for selecting extraction source (when it is not the header)
149947 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
149948 +*//***************************************************************************/
149949 +typedef enum ioc_fm_pcd_extract_from {
149950 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
149951 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
149952 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
149953 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
149954 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
149955 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
149956 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
149957 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
149958 +} ioc_fm_pcd_extract_from;
149959 +
149960 +/**************************************************************************//**
149961 + @Description An enum for selecting extraction type
149962 +*//***************************************************************************/
149963 +typedef enum ioc_fm_pcd_extract_type {
149964 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
149965 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
149966 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
149967 +} ioc_fm_pcd_extract_type;
149968 +
149969 +/**************************************************************************//**
149970 + @Description An enum for selecting a default
149971 +*//***************************************************************************/
149972 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
149973 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
149974 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
149975 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
149976 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
149977 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
149978 +} ioc_fm_pcd_kg_extract_dflt_select;
149979 +
149980 +/**************************************************************************//**
149981 + @Description Enumeration type defining all default groups - each group shares
149982 + a default value, one of four user-initialized values.
149983 +*//***************************************************************************/
149984 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
149985 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
149986 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
149987 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
149988 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
149989 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
149990 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
149991 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
149992 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
149993 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
149994 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
149995 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
149996 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
149997 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
149998 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
149999 + any data extraction that is not the full
150000 + field described above */
150001 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
150002 + any data extraction without validation */
150003 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
150004 + extraction from parser result or
150005 + direct use of default value */
150006 +} ioc_fm_pcd_kg_known_fields_dflt_types;
150007 +
150008 +/**************************************************************************//**
150009 + @Description Enumeration type for defining header index for scenarios with
150010 + multiple (tunneled) headers
150011 +*//***************************************************************************/
150012 +typedef enum ioc_fm_pcd_hdr_index {
150013 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
150014 + to specify regular IP (not tunneled). */
150015 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
150016 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
150017 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
150018 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
150019 +} ioc_fm_pcd_hdr_index;
150020 +
150021 +/**************************************************************************//**
150022 + @Description Enumeration type for selecting the policer profile functional type
150023 +*//***************************************************************************/
150024 +typedef enum ioc_fm_pcd_profile_type_selection {
150025 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
150026 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
150027 +} ioc_fm_pcd_profile_type_selection;
150028 +
150029 +/**************************************************************************//**
150030 + @Description Enumeration type for selecting the policer profile algorithm
150031 +*//***************************************************************************/
150032 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
150033 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
150034 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
150035 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
150036 +} ioc_fm_pcd_plcr_algorithm_selection;
150037 +
150038 +/**************************************************************************//**
150039 + @Description Enumeration type for selecting a policer profile color mode
150040 +*//***************************************************************************/
150041 +typedef enum ioc_fm_pcd_plcr_color_mode {
150042 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
150043 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
150044 +} ioc_fm_pcd_plcr_color_mode;
150045 +
150046 +/**************************************************************************//**
150047 + @Description Enumeration type for selecting a policer profile color
150048 +*//***************************************************************************/
150049 +typedef enum ioc_fm_pcd_plcr_color {
150050 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
150051 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
150052 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
150053 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
150054 +} ioc_fm_pcd_plcr_color;
150055 +
150056 +/**************************************************************************//**
150057 + @Description Enumeration type for selecting the policer profile packet frame length selector
150058 +*//***************************************************************************/
150059 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
150060 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
150061 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
150062 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
150063 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
150064 +} ioc_fm_pcd_plcr_frame_length_select;
150065 +
150066 +/**************************************************************************//**
150067 + @Description Enumeration type for selecting roll-back frame
150068 +*//***************************************************************************/
150069 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
150070 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
150071 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
150072 +} ioc_fm_pcd_plcr_roll_back_frame_select;
150073 +
150074 +/**************************************************************************//**
150075 + @Description Enumeration type for selecting the policer profile packet or byte mode
150076 +*//***************************************************************************/
150077 +typedef enum ioc_fm_pcd_plcr_rate_mode {
150078 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
150079 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
150080 +} ioc_fm_pcd_plcr_rate_mode;
150081 +
150082 +/**************************************************************************//**
150083 + @Description Enumeration type for defining action of frame
150084 +*//***************************************************************************/
150085 +typedef enum ioc_fm_pcd_done_action {
150086 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
150087 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
150088 +} ioc_fm_pcd_done_action;
150089 +
150090 +/**************************************************************************//**
150091 + @Description Enumeration type for selecting the policer counter
150092 +*//***************************************************************************/
150093 +typedef enum ioc_fm_pcd_plcr_profile_counters {
150094 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
150095 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
150096 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
150097 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
150098 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
150099 +} ioc_fm_pcd_plcr_profile_counters;
150100 +
150101 +/**************************************************************************//**
150102 + @Description Enumeration type for selecting the PCD action after extraction
150103 +*//***************************************************************************/
150104 +typedef enum ioc_fm_pcd_action {
150105 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
150106 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
150107 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
150108 +} ioc_fm_pcd_action;
150109 +
150110 +/**************************************************************************//**
150111 + @Description Enumeration type for selecting type of insert manipulation
150112 +*//***************************************************************************/
150113 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
150114 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
150115 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
150116 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150117 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
150118 +#endif /* FM_CAPWAP_SUPPORT */
150119 +} ioc_fm_pcd_manip_hdr_insrt_type;
150120 +
150121 +/**************************************************************************//**
150122 + @Description Enumeration type for selecting type of remove manipulation
150123 +*//***************************************************************************/
150124 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
150125 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
150126 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
150127 +} ioc_fm_pcd_manip_hdr_rmv_type;
150128 +
150129 +/**************************************************************************//**
150130 + @Description An enum for selecting specific L2 fields removal
150131 +*//***************************************************************************/
150132 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
150133 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
150134 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
150135 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
150136 + the header which follows the MPLS header */
150137 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
150138 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
150139 +
150140 +/**************************************************************************//**
150141 + @Description Enumeration type for selecting specific fields updates
150142 +*//***************************************************************************/
150143 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
150144 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
150145 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
150146 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
150147 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
150148 +} ioc_fm_pcd_manip_hdr_field_update_type;
150149 +
150150 +/**************************************************************************//**
150151 + @Description Enumeration type for selecting VLAN updates
150152 +*//***************************************************************************/
150153 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
150154 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
150155 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
150156 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
150157 +
150158 +/**************************************************************************//**
150159 + @Description Enumeration type for selecting specific L2 fields removal
150160 +*//***************************************************************************/
150161 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
150162 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
150163 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
150164 +
150165 +#if (DPAA_VERSION >= 11)
150166 +/**************************************************************************//**
150167 + @Description Enumeration type for selecting QoS mapping mode
150168 +
150169 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
150170 + User should instruct the port to read the parser-result
150171 +*//***************************************************************************/
150172 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
150173 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
150174 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
150175 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
150176 +
150177 +/**************************************************************************//**
150178 + @Description Enumeration type for selecting QoS source
150179 +
150180 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
150181 + User should left room for the parser-result on input/output buffer
150182 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
150183 +*//***************************************************************************/
150184 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
150185 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
150186 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
150187 +} ioc_fm_pcd_manip_hdr_qos_src;
150188 +#endif /* (DPAA_VERSION >= 11) */
150189 +
150190 +/**************************************************************************//**
150191 + @Description Enumeration type for selecting type of header insertion
150192 +*//***************************************************************************/
150193 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
150194 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
150195 +#if (DPAA_VERSION >= 11)
150196 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
150197 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
150198 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
150199 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
150200 +#endif /* (DPAA_VERSION >= 11) */
150201 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
150202 +
150203 +/**************************************************************************//**
150204 + @Description Enumeration type for selecting specific custom command
150205 +*//***************************************************************************/
150206 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
150207 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
150208 +} ioc_fm_pcd_manip_hdr_custom_type;
150209 +
150210 +/**************************************************************************//**
150211 + @Description Enumeration type for selecting specific custom command
150212 +*//***************************************************************************/
150213 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
150214 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
150215 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
150216 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
150217 +
150218 +/**************************************************************************//**
150219 + @Description Enumeration type for selecting type of header removal
150220 +*//***************************************************************************/
150221 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
150222 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
150223 +#if (DPAA_VERSION >= 11)
150224 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
150225 +#endif /* (DPAA_VERSION >= 11) */
150226 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
150227 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
150228 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
150229 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
150230 +
150231 +/**************************************************************************//**
150232 + @Description Enumeration type for selecting type of timeout mode
150233 +*//***************************************************************************/
150234 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
150235 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
150236 + from the first fragment to the last */
150237 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
150238 +} ioc_fm_pcd_manip_reassem_time_out_mode;
150239 +
150240 +/**************************************************************************//**
150241 + @Description Enumeration type for selecting type of WaysNumber mode
150242 +*//***************************************************************************/
150243 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
150244 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
150245 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
150246 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
150247 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
150248 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
150249 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
150250 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
150251 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
150252 +} ioc_fm_pcd_manip_reassem_ways_number;
150253 +
150254 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150255 +/**************************************************************************//**
150256 + @Description Enumeration type for selecting type of statistics mode
150257 +*//***************************************************************************/
150258 +typedef enum ioc_fm_pcd_stats {
150259 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
150260 +} ioc_fm_pcd_stats;
150261 +#endif
150262 +
150263 +/**************************************************************************//**
150264 + @Description Enumeration type for selecting manipulation type
150265 +*//***************************************************************************/
150266 +typedef enum ioc_fm_pcd_manip_type {
150267 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
150268 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
150269 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
150270 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
150271 +} ioc_fm_pcd_manip_type;
150272 +
150273 +/**************************************************************************//**
150274 + @Description Enumeration type for selecting type of statistics mode
150275 +*//***************************************************************************/
150276 +typedef enum ioc_fm_pcd_cc_stats_mode {
150277 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
150278 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
150279 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
150280 +#if (DPAA_VERSION >= 11)
150281 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
150282 +#endif /* (DPAA_VERSION >= 11) */
150283 +} ioc_fm_pcd_cc_stats_mode;
150284 +
150285 +/**************************************************************************//**
150286 + @Description Enumeration type for determining the action in case an IP packet
150287 + is larger than MTU but its DF (Don't Fragment) bit is set.
150288 +*//***************************************************************************/
150289 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
150290 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
150291 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
150292 + /**< Obsolete, cannot enqueue to error queue;
150293 + In practice, selects to discard packets;
150294 + Will be removed in the future */
150295 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
150296 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
150297 +} ioc_fm_pcd_manip_dont_frag_action;
150298 +
150299 +/**************************************************************************//**
150300 + @Description Enumeration type for selecting type of special offload manipulation
150301 +*//***************************************************************************/
150302 +typedef enum ioc_fm_pcd_manip_special_offload_type {
150303 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
150304 +#if (DPAA_VERSION >= 11)
150305 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
150306 +#endif /* (DPAA_VERSION >= 11) */
150307 +} ioc_fm_pcd_manip_special_offload_type;
150308 +
150309 +/**************************************************************************//**
150310 + @Description A union of protocol dependent special options
150311 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
150312 +*//***************************************************************************/
150313 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
150314 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
150315 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
150316 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
150317 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
150318 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
150319 +#if (DPAA_VERSION >= 11)
150320 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
150321 +#endif /* (DPAA_VERSION >= 11) */
150322 +} ioc_fm_pcd_hdr_protocol_opt_u;
150323 +
150324 +/**************************************************************************//**
150325 + @Description A union holding all known protocol fields
150326 +*//***************************************************************************/
150327 +typedef union ioc_fm_pcd_fields_u {
150328 + ioc_header_field_eth_t eth; /**< Ethernet */
150329 + ioc_header_field_vlan_t vlan; /**< VLAN */
150330 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
150331 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
150332 + ioc_header_field_mpls_t mpls; /**< MPLS */
150333 + ioc_header_field_ip_t ip; /**< IP */
150334 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
150335 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
150336 + ioc_header_field_udp_t udp; /**< UDP */
150337 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
150338 + ioc_header_field_tcp_t tcp; /**< TCP */
150339 + ioc_header_field_sctp_t sctp; /**< SCTP */
150340 + ioc_header_field_dccp_t dccp; /**< DCCP */
150341 + ioc_header_field_gre_t gre; /**< GRE */
150342 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
150343 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
150344 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
150345 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
150346 +} ioc_fm_pcd_fields_u;
150347 +
150348 +/**************************************************************************//**
150349 + @Description Parameters for defining header extraction for key generation
150350 +*//***************************************************************************/
150351 +typedef struct ioc_fm_pcd_from_hdr_t {
150352 + uint8_t size; /**< Size in byte */
150353 + uint8_t offset; /**< Byte offset */
150354 +} ioc_fm_pcd_from_hdr_t;
150355 +
150356 +/**************************************************************************//**
150357 + @Description Parameters for defining field extraction for key generation
150358 +*//***************************************************************************/
150359 +typedef struct ioc_fm_pcd_from_field_t {
150360 + ioc_fm_pcd_fields_u field; /**< Field selection */
150361 + uint8_t size; /**< Size in byte */
150362 + uint8_t offset; /**< Byte offset */
150363 +} ioc_fm_pcd_from_field_t;
150364 +
150365 +/**************************************************************************//**
150366 + @Description Parameters for defining a single network environment unit
150367 + A distinction unit should be defined if it will later be used
150368 + by one or more PCD engines to distinguish between flows.
150369 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
150370 +*//***************************************************************************/
150371 +typedef struct ioc_fm_pcd_distinction_unit_t {
150372 + struct {
150373 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
150374 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
150375 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
150376 +} ioc_fm_pcd_distinction_unit_t;
150377 +
150378 +/**************************************************************************//**
150379 + @Description Parameters for defining all different distinction units supported
150380 + by a specific PCD Network Environment Characteristics module.
150381 +
150382 + Each unit represent a protocol or a group of protocols that may
150383 + be used later by the different PCD engines to distinguish between flows.
150384 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
150385 +*//***************************************************************************/
150386 +typedef struct ioc_fm_pcd_net_env_params_t {
150387 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
150388 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150389 + /**< An array of num_of_distinction_units of the
150390 + different units to be identified */
150391 + void *id; /**< Output parameter; Returns the net-env Id to be used */
150392 +} ioc_fm_pcd_net_env_params_t;
150393 +
150394 +/**************************************************************************//**
150395 + @Description Parameters for defining a single extraction action when
150396 + creating a key
150397 +*//***************************************************************************/
150398 +typedef struct ioc_fm_pcd_extract_entry_t {
150399 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150400 + union {
150401 + struct {
150402 + ioc_net_header_type hdr; /**< Header selection */
150403 + bool ignore_protocol_validation;
150404 + /**< Ignore protocol validation */
150405 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150406 + IP. Otherwise should be cleared.*/
150407 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
150408 + union {
150409 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
150410 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
150411 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
150412 + } extract_by_hdr_type;
150413 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150414 + struct {
150415 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
150416 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
150417 + uint16_t ic_indx_mask; /**< Relevant only for CC when
150418 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
150419 + Note that the number of bits that are set within
150420 + this mask must be log2 of the CC-node 'num_of_keys'.
150421 + Note that the mask cannot be set on the lower bits. */
150422 + uint8_t offset; /**< Byte offset */
150423 + uint8_t size; /**< Size in bytes */
150424 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150425 + } extract_params;
150426 +} ioc_fm_pcd_extract_entry_t;
150427 +
150428 +/**************************************************************************//**
150429 + @Description A structure for defining masks for each extracted
150430 + field in the key.
150431 +*//***************************************************************************/
150432 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
150433 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
150434 + uint8_t offset; /**< Byte offset */
150435 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
150436 +} ioc_fm_pcd_kg_extract_mask_t;
150437 +
150438 +/**************************************************************************//**
150439 + @Description A structure for defining default selection per groups
150440 + of fields
150441 +*//***************************************************************************/
150442 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
150443 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
150444 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
150445 +} ioc_fm_pcd_kg_extract_dflt_t;
150446 +
150447 +
150448 +/**************************************************************************//**
150449 + @Description A structure for defining all parameters needed for
150450 + generation a key and using a hash function
150451 +*//***************************************************************************/
150452 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
150453 + uint32_t private_dflt0; /**< Scheme default register 0 */
150454 + uint32_t private_dflt1; /**< Scheme default register 1 */
150455 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
150456 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150457 + /**< An array of extraction definitions. */
150458 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
150459 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
150460 + /**< For each extraction used in this scheme, specify the required
150461 + default register to be used when header is not found.
150462 + types not specified in this array will get undefined value. */
150463 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
150464 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
150465 + uint8_t hash_shift; /**< Hash result right shift.
150466 + Selects the 24 bits out of the 64 hash result.
150467 + 0 means using the 24 LSB's, otherwise use the
150468 + 24 LSB's after shifting right.*/
150469 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
150470 + of queues for the key and hash functionality */
150471 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
150472 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
150473 + destination fields on all layers; If TRUE, driver will check that for
150474 + all layers, if SRC extraction is selected, DST extraction must also be
150475 + selected, and vice versa. */
150476 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
150477 +
150478 +/**************************************************************************//**
150479 + @Description A structure of parameters for defining a single
150480 + Qid mask (extracted OR).
150481 +*//***************************************************************************/
150482 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
150483 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150484 + union {
150485 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150486 + ioc_net_header_type hdr;
150487 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150488 + IP. Otherwise should be cleared.*/
150489 + bool ignore_protocol_validation;
150490 +
150491 + } extract_by_hdr;
150492 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150493 + } extract_params;
150494 + uint8_t extraction_offset; /**< Offset for extraction */
150495 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
150496 + field not found */
150497 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
150498 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
150499 + the extracted byte; Assume byte is placed as the 8 MSB's in
150500 + a 32 bit word where the lower bits
150501 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
150502 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
150503 + extracted byte will effect the 8 LSB's of the FQID,
150504 + if bitOffsetInFqid=31 than the byte's MSB will effect
150505 + the FQID's LSB; 0 means - no effect on FQID;
150506 + Note that one, and only one of
150507 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
150508 + extracted byte must effect either FQID or Policer profile).*/
150509 + uint8_t bit_offset_in_plcr_profile;
150510 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
150511 + effect using the extracted byte; Assume byte is placed
150512 + as the 8 MSB's in a 16 bit word where the lower bits
150513 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
150514 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
150515 + than the extracted byte will effect the whole policer profile id,
150516 + if bitOffsetInFqid=15 than the byte's MSB will effect
150517 + the Policer Profile id's LSB;
150518 + 0 means - no effect on policer profile; Note that one, and only one of
150519 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
150520 + extracted byte must effect either FQID or Policer profile).*/
150521 +} ioc_fm_pcd_kg_extracted_or_params_t;
150522 +
150523 +/**************************************************************************//**
150524 + @Description A structure for configuring scheme counter
150525 +*//***************************************************************************/
150526 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
150527 + bool update; /**< FALSE to keep the current counter state
150528 + and continue from that point, TRUE to update/reset
150529 + the counter when the scheme is written. */
150530 + uint32_t value; /**< If update=TRUE, this value will be written into the
150531 + counter; clear this field to reset the counter. */
150532 +} ioc_fm_pcd_kg_scheme_counter_t;
150533 +
150534 +
150535 +/**************************************************************************//**
150536 + @Description A structure for retrieving FMKG_SE_SPC
150537 +*//***************************************************************************/
150538 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
150539 + uint32_t val; /**< return value */
150540 + void *id; /**< scheme handle */
150541 +} ioc_fm_pcd_kg_scheme_spc_t;
150542 +
150543 +/**************************************************************************//**
150544 + @Description A structure for defining policer profile parameters as required by keygen
150545 + (when policer is the next engine after this scheme).
150546 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
150547 +*//***************************************************************************/
150548 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
150549 + bool shared_profile; /**< TRUE if this profile is shared between ports
150550 + (i.e. managed by master partition) May not be TRUE
150551 + if profile is after Coarse Classification*/
150552 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
150553 + id, if FALSE fqid_offset_relative_profile_id_base is used
150554 + together with fqid_offset_shift and num_of_profiles
150555 + parameters, to define a range of profiles from
150556 + which the KeyGen result will determine the
150557 + destination policer profile. */
150558 + union {
150559 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
150560 + This parameter should indicate the policer profile offset within the port's
150561 + policer profiles or SHARED window. */
150562 + struct {
150563 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
150564 + uint8_t fqid_offset_relative_profile_id_base;
150565 + /**< OR of KG results without the qid base
150566 + This parameter should indicate the policer profile
150567 + offset within the port's policer profiles window
150568 + or SHARED window depends on shared_profile */
150569 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
150570 + } indirect_profile; /**< Indirect profile parameters */
150571 + } profile_select; /**< Direct/indirect profile selection and parameters */
150572 +} ioc_fm_pcd_kg_plcr_profile_t;
150573 +
150574 +#if DPAA_VERSION >= 11
150575 +/**************************************************************************//**
150576 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
150577 +*//***************************************************************************/
150578 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
150579 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
150580 + profile id;
150581 + If FALSE, fqidOffsetRelativeProfileIdBase is used
150582 + together with fqidOffsetShift and numOfProfiles
150583 + parameters to define a range of profiles from which
150584 + the KeyGen result will determine the destination
150585 + storage profile. */
150586 + union {
150587 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
150588 + should indicate the storage profile offset within the
150589 + port's storage profiles window. */
150590 + struct {
150591 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
150592 + uint8_t fqid_offset_relative_profile_id_base;
150593 + /**< OR of KeyGen results without the FQID base;
150594 + should indicate the policer profile offset within the
150595 + port's storage profiles window. */
150596 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
150597 + } indirect_profile; /**< Indirect profile parameters. */
150598 + } profile_select; /**< Direct/indirect profile selection and parameters. */
150599 +} ioc_fm_pcd_kg_storage_profile_t;
150600 +#endif /* DPAA_VERSION >= 11 */
150601 +
150602 +/**************************************************************************//**
150603 + @Description Parameters for defining CC as the next engine after KeyGen
150604 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
150605 +*//***************************************************************************/
150606 +typedef struct ioc_fm_pcd_kg_cc_t {
150607 + void *tree_id; /**< CC Tree id */
150608 + uint8_t grp_id; /**< CC group id within the CC tree */
150609 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
150610 + policing is required. */
150611 + bool bypass_plcr_profile_generation;
150612 + /**< TRUE to bypass KeyGen policer profile generation;
150613 + selected profile is the one set at port initialization. */
150614 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
150615 + bypass_plcr_profile_generation = FALSE */
150616 +} ioc_fm_pcd_kg_cc_t;
150617 +
150618 +/**************************************************************************//**
150619 + @Description Parameters for defining initializing a KeyGen scheme
150620 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
150621 +*//***************************************************************************/
150622 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
150623 + bool modify; /**< TRUE to change an existing scheme */
150624 + union {
150625 + uint8_t relative_scheme_id;
150626 + /**< if modify=FALSE: partition-relative scheme id */
150627 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
150628 + } scm_id;
150629 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
150630 + for match vector; KeyGen will ignore it when matching */
150631 + struct { /**< HL relevant only if always_direct=FALSE */
150632 + void *net_env_id; /**< The id of the Network Environment as returned
150633 + by FM_PCD_NetEnvCharacteristicsSet() */
150634 + uint8_t num_of_distinction_units;
150635 + /**< Number of NetEnv units listed in unit_ids array */
150636 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150637 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
150638 + } net_env_params;
150639 + bool use_hash; /**< use the KG Hash functionality */
150640 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
150641 + /**< used only if useHash = TRUE */
150642 + bool bypass_fqid_generation;
150643 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
150644 + In such a case FQID after KG will be the default FQID
150645 + defined for the relevant port, or the FQID defined by CC
150646 + in cases where CC was the previous engine. */
150647 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
150648 + If hash is used and an even distribution is expected
150649 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
150650 + hash_distribution_num_of_fqids. */
150651 + uint8_t num_of_used_extracted_ors;
150652 + /**< Number of FQID masks listed in extracted_ors array*/
150653 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
150654 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
150655 + registers are shared between qid_masks
150656 + functionality and some of the extraction
150657 + actions; Normally only some will be used
150658 + for qid_mask. Driver will return error if
150659 + resource is full at initialization time. */
150660 +#if DPAA_VERSION >= 11
150661 + bool override_storage_profile;
150662 + /**< TRUE if KeyGen override previously decided storage profile */
150663 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
150664 +#endif /* DPAA_VERSION >= 11 */
150665 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
150666 + union { /**< depends on nextEngine */
150667 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
150668 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
150669 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
150670 + } kg_next_engine_params;
150671 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
150672 + the scheme counter */
150673 + void *id; /**< Returns the scheme Id to be used */
150674 +} ioc_fm_pcd_kg_scheme_params_t;
150675 +
150676 +/**************************************************************************//**
150677 + @Collection
150678 +*//***************************************************************************/
150679 +#if DPAA_VERSION >= 11
150680 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
150681 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
150682 +#endif /* DPAA_VERSION >= 11 */
150683 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
150684 +/* @} */
150685 +
150686 +/**************************************************************************//**
150687 + @Description Parameters for defining CC as the next engine after a CC node.
150688 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
150689 +*//***************************************************************************/
150690 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
150691 + void *cc_node_id; /**< Id of the next CC node */
150692 +} ioc_fm_pcd_cc_next_cc_params_t;
150693 +
150694 +#if DPAA_VERSION >= 11
150695 +/**************************************************************************//**
150696 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
150697 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
150698 +*//***************************************************************************/
150699 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
150700 + void* frm_replic_id; /**< The id of the next frame replicator group */
150701 +} ioc_fm_pcd_cc_next_fr_params_t;
150702 +#endif /* DPAA_VERSION >= 11 */
150703 +
150704 +/**************************************************************************//**
150705 + @Description A structure for defining PLCR params when PLCR is the
150706 + next engine after a CC node
150707 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
150708 +*//***************************************************************************/
150709 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
150710 + bool override_params; /**< TRUE if CC override previously decided parameters*/
150711 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
150712 + TRUE if this profile is shared between ports */
150713 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
150714 + (otherwise profile id is taken from keygen);
150715 + This parameter should indicate the policer
150716 + profile offset within the port's
150717 + policer profiles or from SHARED window.*/
150718 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
150719 + FQID for enquing the frame;
150720 + In earlier chips if policer next engine is KEYGEN,
150721 + this parameter can be 0, because the KEYGEN always decides
150722 + the enqueue FQID.*/
150723 +#if DPAA_VERSION >= 11
150724 + uint8_t new_relative_storage_profile_id;
150725 + /**< Indicates the relative storage profile offset within
150726 + the port's storage profiles window;
150727 + Relevant only if the port was configured with VSP. */
150728 +#endif /* DPAA_VERSION >= 11 */
150729 +} ioc_fm_pcd_cc_next_plcr_params_t;
150730 +
150731 +/**************************************************************************//**
150732 + @Description A structure for defining enqueue params when BMI is the
150733 + next engine after a CC node
150734 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
150735 +*//***************************************************************************/
150736 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
150737 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
150738 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
150739 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
150740 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
150741 + (otherwise FQID is taken from KeyGen),
150742 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
150743 +#if DPAA_VERSION >= 11
150744 + uint8_t new_relative_storage_profile_id;
150745 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
150746 + storage profile offset within the port's storage profiles
150747 + window; Relevant only if the port was configured with VSP. */
150748 +#endif /* DPAA_VERSION >= 11 */
150749 +
150750 +} ioc_fm_pcd_cc_next_enqueue_params_t;
150751 +
150752 +/**************************************************************************//**
150753 + @Description A structure for defining KG params when KG is the next engine after a CC node
150754 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
150755 +*//***************************************************************************/
150756 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
150757 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
150758 + Note - this parameters are irrelevant for earlier chips */
150759 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
150760 + (otherwise FQID is taken from KeyGen),
150761 + Note - this parameters are irrelevant for earlier chips */
150762 +#if DPAA_VERSION >= 11
150763 + uint8_t new_relative_storage_profile_id;
150764 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
150765 + storage profile offset within the port's storage profiles
150766 + window; Relevant only if the port was configured with VSP. */
150767 +#endif /* DPAA_VERSION >= 11 */
150768 + void *p_direct_scheme; /**< Direct scheme id to go to. */
150769 +} ioc_fm_pcd_cc_next_kg_params_t;
150770 +
150771 +/**************************************************************************//**
150772 + @Description Parameters for defining the next engine after a CC node.
150773 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
150774 +*//***************************************************************************/
150775 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
150776 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
150777 + according to nextEngine definition */
150778 + union {
150779 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
150780 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
150781 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
150782 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
150783 +#if DPAA_VERSION >= 11
150784 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
150785 +#endif /* DPAA_VERSION >= 11 */
150786 + } params; /**< Union used for all the next-engine parameters options */
150787 + void *manip_id; /**< Handle to Manipulation object.
150788 + Relevant if next engine is of type result
150789 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
150790 + bool statistics_en; /**< If TRUE, statistics counters are incremented
150791 + for each frame passing through this
150792 + Coarse Classification entry. */
150793 +} ioc_fm_pcd_cc_next_engine_params_t;
150794 +
150795 +/**************************************************************************//**
150796 + @Description Parameters for defining a single CC key
150797 +*//***************************************************************************/
150798 +typedef struct ioc_fm_pcd_cc_key_params_t {
150799 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
150800 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
150801 + in keySize. p_key and p_mask (if defined) has to be
150802 + of the same size defined in the key_size */
150803 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
150804 + /**< parameters for the next for the defined Key in p_key */
150805 +
150806 +} ioc_fm_pcd_cc_key_params_t;
150807 +
150808 +/**************************************************************************//**
150809 + @Description Parameters for defining CC keys parameters
150810 + The driver supports two methods for CC node allocation: dynamic and static.
150811 + Static mode was created in order to prevent runtime alloc/free
150812 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
150813 + the driver automatically allocates the memory according to
150814 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
150815 + size that may be used for this CC-Node taking into consideration
150816 + 'mask_support' and 'statistics_mode' parameters.
150817 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
150818 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
150819 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
150820 + all required structures are allocated according to 'num_of_keys'
150821 + parameter. During runtime modification, these structures are
150822 + re-allocated according to the updated number of keys.
150823 +
150824 + Please note that 'action' and 'ic_indx_mask' mentioned in the
150825 + specific parameter explanations are passed in the extraction
150826 + parameters of the node (fields of extractccparams.extractnonhdr).
150827 +*//***************************************************************************/
150828 +typedef struct ioc_keys_params_t {
150829 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
150830 + A value of zero may be used for dynamic memory allocation. */
150831 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
150832 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
150833 + Should be TRUE to reserve table memory for key masks, even if
150834 + initial keys do not contain masks, or if the node was initialized
150835 + as 'empty' (without keys); this will allow user to add keys with
150836 + masks at runtime. */
150837 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
150838 + To enable statistics gathering, statistics should be enabled per
150839 + every key, using 'statistics_en' in next engine parameters structure
150840 + of that key;
150841 + If 'max_num_of_keys' is set, all required structures will be
150842 + preallocated for all keys. */
150843 +#if (DPAA_VERSION >= 11)
150844 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
150845 + /**< Relevant only for 'RMON' statistics mode
150846 + (this feature is supported only on B4860 device);
150847 + Holds a list of programmable thresholds. For each received frame,
150848 + its length in bytes is examined against these range thresholds and
150849 + the appropriate counter is incremented by 1. For example, to belong
150850 + to range i, the following should hold:
150851 + range i-1 threshold < frame length <= range i threshold
150852 + Each range threshold must be larger then its preceding range
150853 + threshold. Last range threshold must be 0xFFFF. */
150854 +#endif /* (DPAA_VERSION >= 11) */
150855 + uint16_t num_of_keys; /**< Number of initial keys;
150856 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
150857 + this field should be power-of-2 of the number of bits that are
150858 + set in 'ic_indx_mask'. */
150859 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
150860 + to be the standard size of the selected key; For other extraction
150861 + types, 'key_size' has to be as size of extraction; When 'action' =
150862 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
150863 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
150864 + /**< An array with 'num_of_keys' entries, each entry specifies the
150865 + corresponding key parameters;
150866 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
150867 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
150868 + for the 'miss' entry. */
150869 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
150870 + /**< Parameters for defining the next engine when a key is not matched;
150871 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
150872 +} ioc_keys_params_t;
150873 +
150874 +/**************************************************************************//**
150875 + @Description Parameters for defining a CC node
150876 +*//***************************************************************************/
150877 +typedef struct ioc_fm_pcd_cc_node_params_t {
150878 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
150879 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
150880 + void *id; /**< Output parameter; returns the CC node Id to be used */
150881 +} ioc_fm_pcd_cc_node_params_t;
150882 +
150883 +/**************************************************************************//**
150884 + @Description Parameters for defining a hash table
150885 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
150886 +*//***************************************************************************/
150887 +typedef struct ioc_fm_pcd_hash_table_params_t {
150888 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
150889 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
150890 + requested statistics mode will be allocated according to max_num_of_keys. */
150891 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
150892 + that leads to this hash-table. */
150893 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
150894 + The number-of-sets for this hash will be calculated
150895 + as (2^(number of bits set in 'hash_res_mask'));
150896 + The 4 lower bits must be cleared. */
150897 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
150898 + 2-bytes to be used as hash index. */
150899 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
150900 +
150901 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
150902 + /**< Parameters for defining the next engine when a key is not matched */
150903 + void *id;
150904 +} ioc_fm_pcd_hash_table_params_t;
150905 +
150906 +/**************************************************************************//**
150907 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
150908 +*//***************************************************************************/
150909 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
150910 + void *p_hash_tbl;
150911 + uint8_t key_size;
150912 + ioc_fm_pcd_cc_key_params_t key_params;
150913 +} ioc_fm_pcd_hash_table_add_key_params_t;
150914 +
150915 +/**************************************************************************//**
150916 + @Description Parameters for defining a CC tree group.
150917 +
150918 + This structure defines a CC group in terms of NetEnv units
150919 + and the action to be taken in each case. The unit_ids list must
150920 + be given in order from low to high indices.
150921 +
150922 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
150923 + structures where each defines the next action to be taken for
150924 + each units combination. for example:
150925 + num_of_distinction_units = 2
150926 + unit_ids = {1,3}
150927 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
150928 + unit 1 - not found; unit 3 - not found;
150929 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
150930 + unit 1 - not found; unit 3 - found;
150931 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
150932 + unit 1 - found; unit 3 - not found;
150933 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
150934 + unit 1 - found; unit 3 - found;
150935 +*//***************************************************************************/
150936 +typedef struct ioc_fm_pcd_cc_grp_params_t {
150937 + uint8_t num_of_distinction_units; /**< Up to 4 */
150938 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
150939 + /**< Indexes of the units as defined in
150940 + FM_PCD_NetEnvCharacteristicsSet() */
150941 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
150942 + /**< Maximum entries per group is 16 */
150943 +} ioc_fm_pcd_cc_grp_params_t;
150944 +
150945 +/**************************************************************************//**
150946 + @Description Parameters for defining the CC tree groups
150947 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
150948 +*//***************************************************************************/
150949 +typedef struct ioc_fm_pcd_cc_tree_params_t {
150950 + void *net_env_id; /**< Id of the Network Environment as returned
150951 + by FM_PCD_NetEnvCharacteristicsSet() */
150952 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
150953 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
150954 + /**< Parameters for each group. */
150955 + void *id; /**< Output parameter; Returns the tree Id to be used */
150956 +} ioc_fm_pcd_cc_tree_params_t;
150957 +
150958 +/**************************************************************************//**
150959 + @Description Parameters for defining policer byte rate
150960 +*//***************************************************************************/
150961 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
150962 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
150963 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
150964 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
150965 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
150966 +
150967 +/**************************************************************************//**
150968 + @Description Parameters for defining the policer profile (based on
150969 + RFC-2698 or RFC-4115 attributes).
150970 +*//***************************************************************************/
150971 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
150972 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
150973 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
150974 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
150975 + uint32_t committed_burst_size; /**< KBits or Packets */
150976 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
150977 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
150978 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
150979 +
150980 +/**************************************************************************//**
150981 + @Description Parameters for defining the next engine after policer
150982 +*//***************************************************************************/
150983 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
150984 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
150985 + void *p_profile; /**< Policer profile handle - used when next engine
150986 + is PLCR, must be a SHARED profile */
150987 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
150988 +} ioc_fm_pcd_plcr_next_engine_params_u;
150989 +
150990 +typedef struct ioc_fm_pcd_port_params_t {
150991 + ioc_fm_port_type port_type; /**< Type of port for this profile */
150992 + uint8_t port_id; /**< FM-Port id of port for this profile */
150993 +} ioc_fm_pcd_port_params_t;
150994 +
150995 +/**************************************************************************//**
150996 + @Description Parameters for defining the policer profile entry
150997 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
150998 +*//***************************************************************************/
150999 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
151000 + bool modify; /**< TRUE to change an existing profile */
151001 + union {
151002 + struct {
151003 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
151004 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
151005 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
151006 + } new_params; /**< Use it when modify = FALSE */
151007 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
151008 + } profile_select;
151009 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
151010 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
151011 +
151012 + union {
151013 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
151014 + any incoming packet with the default value. */
151015 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
151016 + pre-color value of 2'b11. */
151017 + } color;
151018 +
151019 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
151020 +
151021 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
151022 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
151023 +
151024 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
151025 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
151026 +
151027 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
151028 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
151029 +
151030 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
151031 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
151032 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
151033 +
151034 + void *id; /**< output parameter; Returns the profile Id to be used */
151035 +} ioc_fm_pcd_plcr_profile_params_t;
151036 +
151037 +/**************************************************************************//**
151038 + @Description A structure for modifying CC tree next engine
151039 +*//***************************************************************************/
151040 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
151041 + void *id; /**< CC tree Id to be used */
151042 + uint8_t grp_indx; /**< A Group index in the tree */
151043 + uint8_t indx; /**< Entry index in the group defined by grp_index */
151044 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151045 + /**< Parameters for the next for the defined Key in the p_Key */
151046 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
151047 +
151048 +/**************************************************************************//**
151049 + @Description A structure for modifying CC node next engine
151050 +*//***************************************************************************/
151051 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
151052 + void *id; /**< CC node Id to be used */
151053 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151054 + NOTE: This parameter is IGNORED for miss-key! */
151055 + uint8_t key_size; /**< Key size of added key */
151056 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151057 + /**< parameters for the next for the defined Key in the p_Key */
151058 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
151059 +
151060 +/**************************************************************************//**
151061 + @Description A structure for remove CC node key
151062 +*//***************************************************************************/
151063 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
151064 + void *id; /**< CC node Id to be used */
151065 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151066 + NOTE: This parameter is IGNORED for miss-key! */
151067 +} ioc_fm_pcd_cc_node_remove_key_params_t;
151068 +
151069 +/**************************************************************************//**
151070 + @Description A structure for modifying CC node key and next engine
151071 +*//***************************************************************************/
151072 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
151073 + void *id; /**< CC node Id to be used */
151074 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151075 + NOTE: This parameter is IGNORED for miss-key! */
151076 + uint8_t key_size; /**< Key size of added key */
151077 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
151078 + the array of the type ioc_fm_pcd_cc_key_params_t */
151079 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
151080 +
151081 +/**************************************************************************//**
151082 + @Description A structure for modifying CC node key
151083 +*//***************************************************************************/
151084 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
151085 + void *id; /**< CC node Id to be used */
151086 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151087 + NOTE: This parameter is IGNORED for miss-key! */
151088 + uint8_t key_size; /**< Key size of added key */
151089 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
151090 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
151091 + in keySize. p_Key and p_Mask (if defined) have to be
151092 + of the same size as defined in the key_size */
151093 +} ioc_fm_pcd_cc_node_modify_key_params_t;
151094 +
151095 +/**************************************************************************//**
151096 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
151097 +*//***************************************************************************/
151098 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
151099 + void *p_hash_tbl; /**< The id of the hash table */
151100 + uint8_t key_size; /**< The size of the key to remove */
151101 + uint8_t *p_key; /**< Pointer to the key to remove */
151102 +} ioc_fm_pcd_hash_table_remove_key_params_t;
151103 +
151104 +/**************************************************************************//**
151105 + @Description Parameters for selecting a location for requested manipulation
151106 +*//***************************************************************************/
151107 +typedef struct ioc_fm_manip_hdr_info_t {
151108 + ioc_net_header_type hdr; /**< Header selection */
151109 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
151110 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
151111 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
151112 +} ioc_fm_manip_hdr_info_t;
151113 +
151114 +/**************************************************************************//**
151115 + @Description Parameters for defining header removal by header type
151116 +*//***************************************************************************/
151117 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
151118 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
151119 + union {
151120 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
151121 + struct {
151122 + bool include;/**< If FALSE, remove until the specified header (not including the header);
151123 + If TRUE, remove also the specified header. */
151124 + ioc_fm_manip_hdr_info_t hdr_info;
151125 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151126 +#endif /* FM_CAPWAP_SUPPORT */
151127 +#if (DPAA_VERSION >= 11)
151128 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151129 +#endif /* (DPAA_VERSION >= 11) */
151130 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
151131 + Defines which L2 headers to remove. */
151132 + } u;
151133 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
151134 +
151135 +/**************************************************************************//**
151136 + @Description Parameters for configuring IP fragmentation manipulation
151137 +*//***************************************************************************/
151138 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
151139 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151140 + IP fragmentation will be executed.*/
151141 +#if DPAA_VERSION == 10
151142 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
151143 +#endif /* DPAA_VERSION == 10 */
151144 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151145 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151146 + received frame's buffer. */
151147 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151148 + This parameter is relevant when 'sg_bpid_en=TRUE';
151149 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151150 + of this pool need to be allocated in the same memory area as the received buffers.
151151 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151152 + mutual to all these sources. */
151153 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
151154 + than MTU and its DF bit is set, then this field will
151155 + determine the action to be taken.*/
151156 +} ioc_fm_pcd_manip_frag_ip_params_t;
151157 +
151158 +/**************************************************************************//**
151159 + @Description Parameters for configuring IP reassembly manipulation.
151160 +
151161 + This is a common structure for both IPv4 and IPv6 reassembly
151162 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
151163 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
151164 +*//***************************************************************************/
151165 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
151166 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
151167 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
151168 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
151169 + NOTE: The following comment is relevant only for FMAN v2 devices:
151170 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
151171 + the user schemes id to ensure that the reassembly's schemes will be first match.
151172 + The remaining schemes, if defined, should have higher relative scheme ID. */
151173 +#if DPAA_VERSION >= 11
151174 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
151175 + profile than the opening fragment (Non-Consistent-SP state)
151176 + then one of two possible scenarios occurs:
151177 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
151178 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
151179 +#else
151180 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
151181 +#endif /* DPAA_VERSION >= 11 */
151182 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151183 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151184 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
151185 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
151186 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
151187 + /**< Number of frames per hash entry needed for reassembly process:
151188 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
151189 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
151190 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
151191 + Must be power of 2;
151192 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
151193 + maxNumFramesInProcess has to be in the range of 4 - 512;
151194 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151195 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151196 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151197 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
151198 + uint32_t timeout_threshold_for_reassm_process;
151199 + /**< Represents the time interval in microseconds which defines
151200 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151201 +} ioc_fm_pcd_manip_reassem_ip_params_t;
151202 +
151203 +/**************************************************************************//**
151204 + @Description Parameters for defining IPSEC manipulation
151205 +*//***************************************************************************/
151206 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
151207 + bool decryption; /**< TRUE if being used in decryption direction;
151208 + FALSE if being used in encryption direction. */
151209 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
151210 + (direction depends on the 'decryption' field). */
151211 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
151212 + (direction depends on the 'decryption' field). */
151213 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
151214 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
151215 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
151216 + It is specifies the length of the outer IP header that was configured in the
151217 + corresponding SA. */
151218 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
151219 + The value must be a multiplication of 16 */
151220 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
151221 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
151222 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
151223 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
151224 +
151225 +#if (DPAA_VERSION >= 11)
151226 +/**************************************************************************//**
151227 + @Description Parameters for configuring CAPWAP fragmentation manipulation
151228 +
151229 + Restrictions:
151230 + - Maximum number of fragments per frame is 16.
151231 + - Transmit confirmation is not supported.
151232 + - Fragmentation nodes must be set as the last PCD action (i.e. the
151233 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
151234 + - Only BMan buffers shall be used for frames to be fragmented.
151235 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
151236 + does not support VSP. Therefore, on the same port where we have IPF we
151237 + cannot support VSP.
151238 +*//***************************************************************************/
151239 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
151240 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151241 + CAPWAP fragmentation will be executed.*/
151242 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151243 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151244 + received frame's buffer. */
151245 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151246 + This parameters is relevant when 'sgBpidEn=TRUE';
151247 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151248 + of this pool need to be allocated in the same memory area as the received buffers.
151249 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151250 + mutual to all these sources. */
151251 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
151252 + When this mode is enabled then only the first fragment include the CAPWAP header options
151253 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
151254 + options field (CAPWAP header is updated accordingly).*/
151255 +} ioc_fm_pcd_manip_frag_capwap_params_t;
151256 +
151257 +/**************************************************************************//**
151258 + @Description Parameters for configuring CAPWAP reassembly manipulation.
151259 +
151260 + Restrictions:
151261 + - Application must define one scheme to catch the reassembled frames.
151262 + - Maximum number of fragments per frame is 16.
151263 +
151264 +*//***************************************************************************/
151265 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
151266 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
151267 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
151268 + Rest schemes, if defined, should have higher relative scheme ID. */
151269 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151270 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151271 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
151272 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
151273 + considered as a valid length;
151274 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
151275 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
151276 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
151277 + /**< Number of frames per hash entry needed for reassembly process */
151278 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
151279 + Must be power of 2;
151280 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
151281 + maxNumFramesInProcess has to be in the range of 4 - 512;
151282 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151283 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151284 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151285 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
151286 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
151287 + uint32_t timeout_threshold_for_reassm_process;
151288 + /**< Represents the time interval in microseconds which defines
151289 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151290 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
151291 +
151292 +/**************************************************************************//**
151293 + @Description structure for defining CAPWAP manipulation
151294 +*//***************************************************************************/
151295 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
151296 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
151297 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
151298 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
151299 +
151300 +#endif /* (DPAA_VERSION >= 11) */
151301 +
151302 +/**************************************************************************//**
151303 + @Description Parameters for defining special offload manipulation
151304 +*//***************************************************************************/
151305 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
151306 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
151307 + union
151308 + {
151309 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
151310 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
151311 +
151312 +#if (DPAA_VERSION >= 11)
151313 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
151314 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
151315 +#endif /* (DPAA_VERSION >= 11) */
151316 + } u;
151317 +} ioc_fm_pcd_manip_special_offload_params_t;
151318 +
151319 +/**************************************************************************//**
151320 + @Description Parameters for defining generic removal manipulation
151321 +*//***************************************************************************/
151322 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
151323 + uint8_t offset; /**< Offset from beginning of header to the start
151324 + location of the removal */
151325 + uint8_t size; /**< Size of removed section */
151326 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
151327 +
151328 +/**************************************************************************//**
151329 + @Description Parameters for defining insertion manipulation
151330 +*//***************************************************************************/
151331 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
151332 + uint8_t size; /**< size of inserted section */
151333 + uint8_t *p_data; /**< data to be inserted */
151334 +} ioc_fm_pcd_manip_hdr_insrt_t;
151335 +
151336 +/**************************************************************************//**
151337 + @Description Parameters for defining generic insertion manipulation
151338 +*//***************************************************************************/
151339 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
151340 + uint8_t offset; /**< Offset from beginning of header to the start
151341 + location of the insertion */
151342 + uint8_t size; /**< Size of inserted section */
151343 + bool replace; /**< TRUE to override (replace) existing data at
151344 + 'offset', FALSE to insert */
151345 + uint8_t *p_data; /**< Pointer to data to be inserted */
151346 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
151347 +
151348 +/**************************************************************************//**
151349 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
151350 +*//***************************************************************************/
151351 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
151352 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
151353 + /**< A table of VPri values for each DSCP value;
151354 + The index is the D_SCP value (0-0x3F) and the
151355 + value is the corresponding VPRI (0-15). */
151356 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
151357 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
151358 + this field is the Q Tag default value if the
151359 + IP header is not found. */
151360 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
151361 +
151362 +/**************************************************************************//**
151363 + @Description Parameters for defining header manipulation VLAN fields updates
151364 +*//***************************************************************************/
151365 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
151366 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
151367 + union {
151368 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
151369 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
151370 + is the new VLAN pri. */
151371 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
151372 + /**< Parameters structure, Relevant only if update_type =
151373 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
151374 + } u;
151375 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
151376 +
151377 +/**************************************************************************//**
151378 + @Description Parameters for defining header manipulation IPV4 fields updates
151379 +*//***************************************************************************/
151380 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
151381 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151382 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
151383 + IOC_HDR_MANIP_IPV4_TOS */
151384 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
151385 + contains IOC_HDR_MANIP_IPV4_ID */
151386 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
151387 + contains IOC_HDR_MANIP_IPV4_SRC */
151388 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
151389 + contains IOC_HDR_MANIP_IPV4_DST */
151390 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
151391 +
151392 +/**************************************************************************//**
151393 + @Description Parameters for defining header manipulation IPV6 fields updates
151394 +*//***************************************************************************/
151395 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
151396 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151397 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
151398 + IOC_HDR_MANIP_IPV6_TC */
151399 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151400 + /**< 16 byte new IP SRC; Relevant only if valid_updates
151401 + contains IOC_HDR_MANIP_IPV6_SRC */
151402 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151403 + /**< 16 byte new IP DST; Relevant only if valid_updates
151404 + contains IOC_HDR_MANIP_IPV6_DST */
151405 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
151406 +
151407 +/**************************************************************************//**
151408 + @Description Parameters for defining header manipulation TCP/UDP fields updates
151409 +*//***************************************************************************/
151410 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
151411 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151412 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
151413 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
151414 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
151415 + contains IOC_HDR_MANIP_TCP_UDP_DST */
151416 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
151417 +
151418 +/**************************************************************************//**
151419 + @Description Parameters for defining header manipulation fields updates
151420 +*//***************************************************************************/
151421 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
151422 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
151423 + union {
151424 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
151425 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
151426 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
151427 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
151428 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
151429 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
151430 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
151431 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
151432 + } u;
151433 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
151434 +
151435 +/**************************************************************************//**
151436 + @Description Parameters for defining custom header manipulation for IP replacement
151437 +*//***************************************************************************/
151438 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
151439 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
151440 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
151441 + bool update_ipv4_id; /**< Relevant when replace_type =
151442 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
151443 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
151444 + update_ipv4_id = TRUE */
151445 + uint8_t hdr_size; /**< The size of the new IP header */
151446 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
151447 + /**< The new IP header */
151448 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
151449 +
151450 +/**************************************************************************//**
151451 + @Description Parameters for defining custom header manipulation
151452 +*//***************************************************************************/
151453 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
151454 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
151455 + union {
151456 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
151457 + /**< Parameters IP header replacement */
151458 + } u;
151459 +} ioc_fm_pcd_manip_hdr_custom_params_t;
151460 +
151461 +/**************************************************************************//**
151462 + @Description Parameters for defining specific L2 insertion manipulation
151463 +*//***************************************************************************/
151464 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
151465 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
151466 + bool update; /**< TRUE to update MPLS header */
151467 + uint8_t size; /**< size of inserted section */
151468 + uint8_t *p_data; /**< data to be inserted */
151469 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
151470 +
151471 +#if (DPAA_VERSION >= 11)
151472 +/**************************************************************************//**
151473 + @Description Parameters for defining IP insertion manipulation
151474 +*//***************************************************************************/
151475 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
151476 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
151477 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
151478 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
151479 + the inserted header */
151480 + uint16_t id; /**< 16 bit New IP ID */
151481 + bool dont_frag_overwrite;
151482 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
151483 + * This byte is configured to be overwritten when RPD is set. */
151484 + uint8_t last_dst_offset;
151485 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
151486 + * in order to calculate UDP checksum pseudo header;
151487 + * Otherwise set it to '0'. */
151488 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
151489 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
151490 +#endif /* (DPAA_VERSION >= 11) */
151491 +
151492 +/**************************************************************************//**
151493 + @Description Parameters for defining header insertion manipulation by header type
151494 +*//***************************************************************************/
151495 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
151496 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
151497 + union {
151498 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
151499 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
151500 + Selects which L2 headers to remove */
151501 +#if (DPAA_VERSION >= 11)
151502 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
151503 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
151504 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
151505 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
151506 +#endif /* (DPAA_VERSION >= 11) */
151507 + } u;
151508 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
151509 +
151510 +/**************************************************************************//**
151511 + @Description Parameters for defining header insertion manipulation
151512 +*//***************************************************************************/
151513 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
151514 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
151515 + union {
151516 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
151517 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
151518 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
151519 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
151520 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151521 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
151522 + /**< Parameters for defining header insertion manipulation by template,
151523 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
151524 +#endif /* FM_CAPWAP_SUPPORT */
151525 + } u;
151526 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
151527 +
151528 +/**************************************************************************//**
151529 + @Description Parameters for defining header removal manipulation
151530 +*//***************************************************************************/
151531 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
151532 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
151533 + union {
151534 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
151535 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
151536 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
151537 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
151538 + } u;
151539 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
151540 +
151541 +/**************************************************************************//**
151542 + @Description Parameters for defining header manipulation node
151543 +*//***************************************************************************/
151544 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
151545 + bool rmv; /**< TRUE, to define removal manipulation */
151546 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
151547 +
151548 + bool insrt; /**< TRUE, to define insertion manipulation */
151549 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
151550 +
151551 + bool field_update; /**< TRUE, to define field update manipulation */
151552 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
151553 +
151554 + bool custom; /**< TRUE, to define custom manipulation */
151555 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
151556 +
151557 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
151558 + completing the manipulation on the frame */
151559 +} ioc_fm_pcd_manip_hdr_params_t;
151560 +
151561 +
151562 +/**************************************************************************//**
151563 + @Description structure for defining fragmentation manipulation
151564 +*//***************************************************************************/
151565 +typedef struct ioc_fm_pcd_manip_frag_params_t {
151566 + ioc_net_header_type hdr; /**< Header selection */
151567 + union {
151568 +#if (DPAA_VERSION >= 11)
151569 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
151570 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
151571 +#endif /* (DPAA_VERSION >= 11) */
151572 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
151573 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
151574 + } u;
151575 +} ioc_fm_pcd_manip_frag_params_t;
151576 +
151577 +/**************************************************************************//**
151578 + @Description structure for defining reassemble manipulation
151579 +*//***************************************************************************/
151580 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
151581 + ioc_net_header_type hdr; /**< Header selection */
151582 + union {
151583 +#if (DPAA_VERSION >= 11)
151584 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
151585 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
151586 +#endif /* (DPAA_VERSION >= 11) */
151587 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
151588 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
151589 + } u;
151590 +} ioc_fm_pcd_manip_reassem_params_t;
151591 +
151592 +/**************************************************************************//**
151593 + @Description Parameters for defining a manipulation node
151594 +*//***************************************************************************/
151595 +typedef struct ioc_fm_pcd_manip_params_t {
151596 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
151597 + union {
151598 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
151599 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
151600 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
151601 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
151602 + } u;
151603 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
151604 + Allows concatenation of manipulation actions
151605 + This parameter is optional and may be NULL. */
151606 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
151607 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
151608 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
151609 + relevant if frag_or_reasm = TRUE */
151610 +#endif /* FM_CAPWAP_SUPPORT */
151611 + void *id;
151612 +} ioc_fm_pcd_manip_params_t;
151613 +
151614 +/**************************************************************************//**
151615 + @Description Structure for retrieving IP reassembly statistics
151616 +*//***************************************************************************/
151617 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
151618 + /* common counters for both IPv4 and IPv6 */
151619 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
151620 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
151621 + a Reassembly Frame Descriptor */
151622 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
151623 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
151624 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
151625 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
151626 +#if (DPAA_VERSION >= 11)
151627 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
151628 + successfully reassembled frames */
151629 +#endif /* (DPAA_VERSION >= 11) */
151630 +struct {
151631 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
151632 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
151633 + have been processed for all frames */
151634 + uint32_t processed_fragments; /**< Counts the number of processed fragments
151635 + (valid and error fragments) for all frames */
151636 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
151637 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
151638 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
151639 + to access an IP-Reassembly Automatic Learning Hash set */
151640 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
151641 + exceeds 16 */
151642 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
151643 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
151644 +
151645 +/**************************************************************************//**
151646 + @Description Structure for retrieving IP fragmentation statistics
151647 +*//***************************************************************************/
151648 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
151649 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
151650 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
151651 + uint32_t generated_fragments; /**< Number of fragments that were generated */
151652 +} ioc_fm_pcd_manip_frag_ip_stats_t;
151653 +
151654 +#if (DPAA_VERSION >= 11)
151655 +/**************************************************************************//**
151656 + @Description Structure for retrieving CAPWAP reassembly statistics
151657 +*//***************************************************************************/
151658 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
151659 + uint32_t timeout; /**< Counts the number of timeout occurrences */
151660 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
151661 + a Reassembly Frame Descriptor */
151662 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
151663 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
151664 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
151665 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
151666 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
151667 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
151668 + have been processed for all frames */
151669 + uint32_t processed_fragments; /**< Counts the number of processed fragments
151670 + (valid and error fragments) for all frames */
151671 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
151672 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
151673 + to access an Reassembly Automatic Learning Hash set */
151674 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
151675 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
151676 + exceeds 16 */
151677 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
151678 + length exceeds MaxReassembledFrameLength value */
151679 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
151680 +
151681 +/**************************************************************************//**
151682 + @Description Structure for retrieving CAPWAP fragmentation statistics
151683 +*//***************************************************************************/
151684 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
151685 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
151686 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
151687 + uint32_t generated_fragments; /**< Number of fragments that were generated */
151688 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
151689 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
151690 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
151691 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
151692 +#endif /* (DPAA_VERSION >= 11) */
151693 +
151694 +/**************************************************************************//**
151695 + @Description Structure for retrieving reassembly statistics
151696 +*//***************************************************************************/
151697 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
151698 + union {
151699 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
151700 +#if (DPAA_VERSION >= 11)
151701 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
151702 +#endif /* (DPAA_VERSION >= 11) */
151703 + } u;
151704 +} ioc_fm_pcd_manip_reassem_stats_t;
151705 +
151706 +/**************************************************************************//**
151707 + @Description structure for retrieving fragmentation statistics
151708 +*//***************************************************************************/
151709 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
151710 + union {
151711 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
151712 +#if (DPAA_VERSION >= 11)
151713 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
151714 +#endif /* (DPAA_VERSION >= 11) */
151715 + } u;
151716 +} ioc_fm_pcd_manip_frag_stats_t;
151717 +
151718 +/**************************************************************************//**
151719 + @Description structure for defining manipulation statistics
151720 +*//***************************************************************************/
151721 +typedef struct ioc_fm_pcd_manip_stats_t {
151722 + union {
151723 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
151724 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
151725 + } u;
151726 +} ioc_fm_pcd_manip_stats_t;
151727 +
151728 +/**************************************************************************//**
151729 + @Description Parameters for acquiring manipulation statistics
151730 +*//***************************************************************************/
151731 +typedef struct ioc_fm_pcd_manip_get_stats_t {
151732 + void *id;
151733 + ioc_fm_pcd_manip_stats_t stats;
151734 +} ioc_fm_pcd_manip_get_stats_t;
151735 +
151736 +#if DPAA_VERSION >= 11
151737 +/**************************************************************************//**
151738 + @Description Parameters for defining frame replicator group and its members
151739 +*//***************************************************************************/
151740 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
151741 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
151742 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
151743 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
151744 + /**< Array of members' parameters */
151745 + void *id;
151746 +} ioc_fm_pcd_frm_replic_group_params_t;
151747 +
151748 +typedef struct ioc_fm_pcd_frm_replic_member_t {
151749 + void *h_replic_group;
151750 + uint16_t member_index;
151751 +} ioc_fm_pcd_frm_replic_member_t;
151752 +
151753 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
151754 + ioc_fm_pcd_frm_replic_member_t member;
151755 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
151756 +} ioc_fm_pcd_frm_replic_member_params_t;
151757 +#endif /* DPAA_VERSION >= 11 */
151758 +
151759 +
151760 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
151761 + uint32_t byte_count; /**< This counter reflects byte count of frames that
151762 + were matched by this key. */
151763 + uint32_t frame_count; /**< This counter reflects count of frames that
151764 + were matched by this key. */
151765 +#if (DPAA_VERSION >= 11)
151766 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151767 + /**< These counters reflect how many frames matched
151768 + this key in 'RMON' statistics mode:
151769 + Each counter holds the number of frames of a
151770 + specific frames length range, according to the
151771 + ranges provided at initialization. */
151772 +#endif /* (DPAA_VERSION >= 11) */
151773 +} ioc_fm_pcd_cc_key_statistics_t;
151774 +
151775 +
151776 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
151777 + void *id;
151778 + uint16_t key_index;
151779 + ioc_fm_pcd_cc_key_statistics_t statistics;
151780 +} ioc_fm_pcd_cc_tbl_get_stats_t;
151781 +
151782 +/**************************************************************************//**
151783 + @Function FM_PCD_MatchTableGetKeyStatistics
151784 +
151785 + @Description This routine may be used to get statistics counters of specific key
151786 + in a CC Node.
151787 +
151788 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
151789 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
151790 + these counters reflect how many frames passed that were matched
151791 + this key; The total frames count will be returned in the counter
151792 + of the first range (as only one frame length range was defined).
151793 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
151794 + frame count will be separated to frame length counters, based on
151795 + provided frame length ranges.
151796 +
151797 + @Param[in] h_CcNode A handle to the node
151798 + @Param[in] keyIndex Key index for adding
151799 + @Param[out] p_KeyStatistics Key statistics counters
151800 +
151801 + @Return The specific key statistics.
151802 +
151803 + @Cautions Allowed only following FM_PCD_MatchTableSet().
151804 +*//***************************************************************************/
151805 +
151806 +#if defined(CONFIG_COMPAT)
151807 +#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)
151808 +#endif
151809 +#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)
151810 +
151811 +/**************************************************************************//**
151812 + @Function FM_PCD_MatchTableGetMissStatistics
151813 +
151814 + @Description This routine may be used to get statistics counters of miss entry
151815 + in a CC Node.
151816 +
151817 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
151818 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
151819 + these counters reflect how many frames were not matched to any
151820 + existing key and therefore passed through the miss entry; The
151821 + total frames count will be returned in the counter of the
151822 + first range (as only one frame length range was defined).
151823 +
151824 + @Param[in] h_CcNode A handle to the node
151825 + @Param[out] p_MissStatistics Statistics counters for 'miss'
151826 +
151827 + @Return E_OK on success; Error code otherwise.
151828 +
151829 + @Cautions Allowed only following FM_PCD_MatchTableSet().
151830 +*//***************************************************************************/
151831 +
151832 +#if defined(CONFIG_COMPAT)
151833 +#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)
151834 +#endif
151835 +#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)
151836 +
151837 +/**************************************************************************//**
151838 + @Function FM_PCD_HashTableGetMissStatistics
151839 +
151840 + @Description This routine may be used to get statistics counters of 'miss'
151841 + entry of the a hash table.
151842 +
151843 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
151844 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
151845 + these counters reflect how many frames were not matched to any
151846 + existing key and therefore passed through the miss entry;
151847 +
151848 + @Param[in] h_HashTbl A handle to a hash table
151849 + @Param[out] p_MissStatistics Statistics counters for 'miss'
151850 +
151851 + @Return E_OK on success; Error code otherwise.
151852 +
151853 + @Cautions Allowed only following FM_PCD_HashTableSet().
151854 +*//***************************************************************************/
151855 +
151856 +#if defined(CONFIG_COMPAT)
151857 +#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)
151858 +#endif
151859 +#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)
151860 +
151861 +
151862 +/**************************************************************************//**
151863 + @Function FM_PCD_NetEnvCharacteristicsSet
151864 +
151865 + @Description Define a set of Network Environment Characteristics.
151866 +
151867 + When setting an environment it is important to understand its
151868 + application. It is not meant to describe the flows that will run
151869 + on the ports using this environment, but what the user means TO DO
151870 + with the PCD mechanisms in order to parse-classify-distribute those
151871 + frames.
151872 + By specifying a distinction unit, the user means it would use that option
151873 + for distinction between frames at either a KeyGen scheme or a coarse
151874 + classification action descriptor. Using interchangeable headers to define a
151875 + unit means that the user is indifferent to which of the interchangeable
151876 + headers is present in the frame, and wants the distinction to be based
151877 + on the presence of either one of them.
151878 +
151879 + Depending on context, there are limitations to the use of environments. A
151880 + port using the PCD functionality is bound to an environment. Some or even
151881 + all ports may share an environment but also an environment per port is
151882 + possible. When initializing a scheme, a classification plan group (see below),
151883 + or a coarse classification tree, one of the initialized environments must be
151884 + stated and related to. When a port is bound to a scheme, a classification
151885 + plan group, or a coarse classification tree, it MUST be bound to the same
151886 + environment.
151887 +
151888 + The different PCD modules, may relate (for flows definition) ONLY on
151889 + distinction units as defined by their environment. When initializing a
151890 + scheme for example, it may not choose to select IPV4 as a match for
151891 + recognizing flows unless it was defined in the relating environment. In
151892 + fact, to guide the user through the configuration of the PCD, each module's
151893 + characterization in terms of flows is not done using protocol names, but using
151894 + environment indexes.
151895 +
151896 + In terms of HW implementation, the list of distinction units sets the LCV vectors
151897 + and later used for match vector, classification plan vectors and coarse classification
151898 + indexing.
151899 +
151900 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
151901 +
151902 + @Return 0 on success; Error code otherwise.
151903 +*//***************************************************************************/
151904 +#if defined(CONFIG_COMPAT)
151905 +#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)
151906 +#endif
151907 +#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)
151908 +
151909 +/**************************************************************************//**
151910 + @Function FM_PCD_NetEnvCharacteristicsDelete
151911 +
151912 + @Description Deletes a set of Network Environment Charecteristics.
151913 +
151914 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
151915 +
151916 + @Return 0 on success; Error code otherwise.
151917 +*//***************************************************************************/
151918 +#if defined(CONFIG_COMPAT)
151919 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
151920 +#endif
151921 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
151922 +
151923 +/**************************************************************************//**
151924 + @Function FM_PCD_KgSchemeSet
151925 +
151926 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
151927 + This routine should be called for adding or modifying a scheme.
151928 + When a scheme needs modifying, the API requires that it will be
151929 + rewritten. In such a case 'modify' should be TRUE. If the
151930 + routine is called for a valid scheme and 'modify' is FALSE,
151931 + it will return error.
151932 +
151933 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
151934 +
151935 + @Return 0 on success; Error code otherwise.
151936 +*//***************************************************************************/
151937 +#if defined(CONFIG_COMPAT)
151938 +#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)
151939 +#endif
151940 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
151941 +
151942 +/**************************************************************************//**
151943 + @Function FM_PCD_KgSchemeDelete
151944 +
151945 + @Description Deleting an initialized scheme.
151946 +
151947 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
151948 +
151949 + @Return 0 on success; Error code otherwise.
151950 +*//***************************************************************************/
151951 +#if defined(CONFIG_COMPAT)
151952 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
151953 +#endif
151954 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
151955 +
151956 +/**************************************************************************//**
151957 + @Function FM_PCD_CcRootBuild
151958 +
151959 + @Description This routine must be called to define a complete coarse
151960 + classification tree. This is the way to define coarse
151961 + classification to a certain flow - the KeyGen schemes
151962 + may point only to trees defined in this way.
151963 +
151964 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
151965 +
151966 + @Return 0 on success; Error code otherwise.
151967 +*//***************************************************************************/
151968 +#if defined(CONFIG_COMPAT)
151969 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
151970 +#endif
151971 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
151972 +
151973 +/**************************************************************************//**
151974 + @Function FM_PCD_CcRootDelete
151975 +
151976 + @Description Deleting a built tree.
151977 +
151978 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
151979 +*//***************************************************************************/
151980 +#if defined(CONFIG_COMPAT)
151981 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
151982 +#endif
151983 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
151984 +
151985 +/**************************************************************************//**
151986 + @Function FM_PCD_MatchTableSet
151987 +
151988 + @Description This routine should be called for each CC (coarse classification)
151989 + node. The whole CC tree should be built bottom up so that each
151990 + node points to already defined nodes. p_NodeId returns the node
151991 + Id to be used by other nodes.
151992 +
151993 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
151994 +
151995 + @Return 0 on success; Error code otherwise.
151996 +*//***************************************************************************/
151997 +#if defined(CONFIG_COMPAT)
151998 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
151999 +#endif
152000 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
152001 +
152002 +/**************************************************************************//**
152003 + @Function FM_PCD_MatchTableDelete
152004 +
152005 + @Description Deleting a built node.
152006 +
152007 + @Param[in] ioc_fm_obj_t - The id of a CC node.
152008 +
152009 + @Return 0 on success; Error code otherwise.
152010 +*//***************************************************************************/
152011 +#if defined(CONFIG_COMPAT)
152012 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
152013 +#endif
152014 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
152015 +
152016 +/**************************************************************************//**
152017 + @Function FM_PCD_CcRootModifyNextEngine
152018 +
152019 + @Description Modify the Next Engine Parameters in the entry of the tree.
152020 +
152021 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152022 +
152023 + @Return 0 on success; Error code otherwise.
152024 +
152025 + @Cautions Allowed only following FM_PCD_CcRootBuild().
152026 +*//***************************************************************************/
152027 +#if defined(CONFIG_COMPAT)
152028 +#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)
152029 +#endif
152030 +#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)
152031 +
152032 +/**************************************************************************//**
152033 + @Function FM_PCD_MatchTableModifyNextEngine
152034 +
152035 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
152036 +
152037 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
152038 +
152039 + @Return 0 on success; Error code otherwise.
152040 +
152041 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152042 +*//***************************************************************************/
152043 +#if defined(CONFIG_COMPAT)
152044 +#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)
152045 +#endif
152046 +#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)
152047 +
152048 +/**************************************************************************//**
152049 + @Function FM_PCD_MatchTableModifyMissNextEngine
152050 +
152051 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
152052 +
152053 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152054 +
152055 + @Return 0 on success; Error code otherwise.
152056 +
152057 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152058 +*//***************************************************************************/
152059 +#if defined(CONFIG_COMPAT)
152060 +#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)
152061 +#endif
152062 +#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)
152063 +
152064 +/**************************************************************************//**
152065 + @Function FM_PCD_MatchTableRemoveKey
152066 +
152067 + @Description Remove the key (including next engine parameters of this key)
152068 + defined by the index of the relevant node.
152069 +
152070 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
152071 +
152072 + @Return 0 on success; Error code otherwise.
152073 +
152074 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152075 + node and for all of the nodes that lead to it.
152076 +*//***************************************************************************/
152077 +#if defined(CONFIG_COMPAT)
152078 +#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)
152079 +#endif
152080 +#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)
152081 +
152082 +/**************************************************************************//**
152083 + @Function FM_PCD_MatchTableAddKey
152084 +
152085 + @Description Add the key (including next engine parameters of this key in the
152086 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
152087 + may be used when the user doesn't care about the position of the
152088 + key in the table - in that case, the key will be automatically
152089 + added by the driver in the last available entry.
152090 +
152091 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152092 +
152093 + @Return 0 on success; Error code otherwise.
152094 +
152095 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152096 + node and for all of the nodes that lead to it.
152097 +*//***************************************************************************/
152098 +#if defined(CONFIG_COMPAT)
152099 +#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)
152100 +#endif
152101 +#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)
152102 +
152103 +/**************************************************************************//**
152104 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
152105 +
152106 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
152107 +
152108 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152109 +
152110 + @Return 0 on success; Error code otherwise.
152111 +
152112 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
152113 + the node that points to this node
152114 +*//***************************************************************************/
152115 +#if defined(CONFIG_COMPAT)
152116 +#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)
152117 +#endif
152118 +#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)
152119 +
152120 +/**************************************************************************//**
152121 + @Function FM_PCD_MatchTableModifyKey
152122 +
152123 + @Description Modify the key at the index defined by key_index.
152124 +
152125 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
152126 +
152127 + @Return 0 on success; Error code otherwise.
152128 +
152129 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152130 + node and for all of the nodes that lead to it.
152131 +*//***************************************************************************/
152132 +#if defined(CONFIG_COMPAT)
152133 +#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)
152134 +#endif
152135 +#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)
152136 +
152137 +/**************************************************************************//**
152138 + @Function FM_PCD_HashTableSet
152139 +
152140 + @Description This routine initializes a hash table structure.
152141 + KeyGen hash result determines the hash bucket.
152142 + Next, KeyGen key is compared against all keys of this
152143 + bucket (exact match).
152144 + Number of sets (number of buckets) of the hash equals to the
152145 + number of 1-s in 'hash_res_mask' in the provided parameters.
152146 + Number of hash table ways is then calculated by dividing
152147 + 'max_num_of_keys' equally between the hash sets. This is the maximal
152148 + number of keys that a hash bucket may hold.
152149 + The hash table is initialized empty and keys may be
152150 + added to it following the initialization. Keys masks are not
152151 + supported in current hash table implementation.
152152 + The initialized hash table can be integrated as a node in a
152153 + CC tree.
152154 +
152155 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
152156 +
152157 + @Return 0 on success; Error code otherwise.
152158 +*//***************************************************************************/
152159 +#if defined(CONFIG_COMPAT)
152160 +#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)
152161 +#endif
152162 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
152163 +
152164 +
152165 +/**************************************************************************//**
152166 + @Function FM_PCD_HashTableDelete
152167 +
152168 + @Description This routine deletes the provided hash table and released all
152169 + its allocated resources.
152170 +
152171 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
152172 +
152173 + @Return 0 on success; Error code otherwise.
152174 +
152175 + @Cautions Allowed only following FM_PCD_HashTableSet().
152176 +*//***************************************************************************/
152177 +#if defined(CONFIG_COMPAT)
152178 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
152179 +#endif
152180 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
152181 +
152182 +/**************************************************************************//**
152183 + @Function FM_PCD_HashTableAddKey
152184 +
152185 + @Description This routine adds the provided key (including next engine
152186 + parameters of this key) to the hash table.
152187 + The key is added as the last key of the bucket that it is
152188 + mapped to.
152189 +
152190 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
152191 +
152192 + @Return 0 on success; error code otherwise.
152193 +
152194 + @Cautions Allowed only following FM_PCD_HashTableSet().
152195 +*//***************************************************************************/
152196 +#if defined(CONFIG_COMPAT)
152197 +#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)
152198 +#endif
152199 +#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)
152200 +
152201 +/**************************************************************************//**
152202 + @Function FM_PCD_HashTableRemoveKey
152203 +
152204 + @Description This routine removes the requested key (including next engine
152205 + parameters of this key) from the hash table.
152206 +
152207 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
152208 +
152209 + @Return 0 on success; Error code otherwise.
152210 +
152211 + @Cautions Allowed only following FM_PCD_HashTableSet().
152212 +*//***************************************************************************/
152213 +#if defined(CONFIG_COMPAT)
152214 +#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)
152215 +#endif
152216 +#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)
152217 +
152218 +/**************************************************************************//**
152219 + @Function FM_PCD_PlcrProfileSet
152220 +
152221 + @Description Sets a profile entry in the policer profile table.
152222 + The routine overrides any existing value.
152223 +
152224 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
152225 + policer profile entry.
152226 +
152227 + @Return 0 on success; Error code otherwise.
152228 +*//***************************************************************************/
152229 +#if defined(CONFIG_COMPAT)
152230 +#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)
152231 +#endif
152232 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
152233 +
152234 +/**************************************************************************//**
152235 + @Function FM_PCD_PlcrProfileDelete
152236 +
152237 + @Description Delete a profile entry in the policer profile table.
152238 + The routine set entry to invalid.
152239 +
152240 + @Param[in] ioc_fm_obj_t The id of a policer profile.
152241 +
152242 + @Return 0 on success; Error code otherwise.
152243 +*//***************************************************************************/
152244 +#if defined(CONFIG_COMPAT)
152245 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
152246 +#endif
152247 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
152248 +
152249 +/**************************************************************************//**
152250 + @Function FM_PCD_ManipNodeSet
152251 +
152252 + @Description This routine should be called for defining a manipulation
152253 + node. A manipulation node must be defined before the CC node
152254 + that precedes it.
152255 +
152256 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152257 +
152258 + @Return A handle to the initialized object on success; NULL code otherwise.
152259 +*//***************************************************************************/
152260 +#if defined(CONFIG_COMPAT)
152261 +#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)
152262 +#endif
152263 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
152264 +
152265 +/**************************************************************************//**
152266 + @Function FM_PCD_ManipNodeReplace
152267 +
152268 + @Description Change existing manipulation node to be according to new requirement.
152269 + (Here, it's implemented as a variant of the same IOCTL as for
152270 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
152271 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
152272 + the manip node's handle)
152273 +
152274 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152275 +
152276 + @Return 0 on success; error code otherwise.
152277 +
152278 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152279 +*//***************************************************************************/
152280 +#if defined(CONFIG_COMPAT)
152281 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152282 +#endif
152283 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
152284 +
152285 +/**************************************************************************//**
152286 + @Function FM_PCD_ManipNodeDelete
152287 +
152288 + @Description Delete an existing manipulation node.
152289 +
152290 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
152291 +
152292 + @Return 0 on success; error code otherwise.
152293 +
152294 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152295 +*//***************************************************************************/
152296 +#if defined(CONFIG_COMPAT)
152297 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
152298 +#endif
152299 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
152300 +
152301 +/**************************************************************************//**
152302 + @Function FM_PCD_ManipGetStatistics
152303 +
152304 + @Description Retrieve the manipulation statistics.
152305 +
152306 + @Param[in] h_ManipNode A handle to a manipulation node.
152307 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
152308 +
152309 + @Return E_OK on success; Error code otherwise.
152310 +
152311 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152312 +*//***************************************************************************/
152313 +#if defined(CONFIG_COMPAT)
152314 +#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)
152315 +#endif
152316 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
152317 +
152318 +/**************************************************************************//**
152319 +@Function FM_PCD_SetAdvancedOffloadSupport
152320 +
152321 +@Description This routine must be called in order to support the following features:
152322 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
152323 +
152324 +@Param[in] h_FmPcd FM PCD module descriptor.
152325 +
152326 +@Return 0 on success; error code otherwise.
152327 +
152328 +@Cautions Allowed only when PCD is disabled.
152329 +*//***************************************************************************/
152330 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
152331 +
152332 +#if (DPAA_VERSION >= 11)
152333 +/**************************************************************************//**
152334 + @Function FM_PCD_FrmReplicSetGroup
152335 +
152336 + @Description Initialize a Frame Replicator group.
152337 +
152338 + @Param[in] h_FmPcd FM PCD module descriptor.
152339 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
152340 + the frame replicator group.
152341 +
152342 + @Return A handle to the initialized object on success; NULL code otherwise.
152343 +
152344 + @Cautions Allowed only following FM_PCD_Init().
152345 +*//***************************************************************************/
152346 +#if defined(CONFIG_COMPAT)
152347 +#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)
152348 +#endif
152349 +#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)
152350 +
152351 +/**************************************************************************//**
152352 + @Function FM_PCD_FrmReplicDeleteGroup
152353 +
152354 + @Description Delete a Frame Replicator group.
152355 +
152356 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152357 +
152358 + @Return E_OK on success; Error code otherwise.
152359 +
152360 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
152361 +*//***************************************************************************/
152362 +#if defined(CONFIG_COMPAT)
152363 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
152364 +#endif
152365 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
152366 +
152367 +/**************************************************************************//**
152368 + @Function FM_PCD_FrmReplicAddMember
152369 +
152370 + @Description Add the member in the index defined by the memberIndex.
152371 +
152372 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152373 + @Param[in] memberIndex member index for adding.
152374 + @Param[in] p_MemberParams A pointer to the new member parameters.
152375 +
152376 + @Return E_OK on success; Error code otherwise.
152377 +
152378 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152379 +*//***************************************************************************/
152380 +#if defined(CONFIG_COMPAT)
152381 +#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)
152382 +#endif
152383 +#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)
152384 +
152385 +/**************************************************************************//**
152386 + @Function FM_PCD_FrmReplicRemoveMember
152387 +
152388 + @Description Remove the member defined by the index from the relevant group.
152389 +
152390 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152391 + @Param[in] memberIndex member index for removing.
152392 +
152393 + @Return E_OK on success; Error code otherwise.
152394 +
152395 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152396 +*//***************************************************************************/
152397 +#if defined(CONFIG_COMPAT)
152398 +#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)
152399 +#endif
152400 +#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)
152401 +
152402 +#endif
152403 +
152404 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152405 +/**************************************************************************//**
152406 + @Function FM_PCD_StatisticsSetNode
152407 +
152408 + @Description This routine should be called for defining a statistics node.
152409 +
152410 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
152411 +
152412 + @Return 0 on success; Error code otherwise.
152413 +*//***************************************************************************/
152414 +#if defined(CONFIG_COMPAT)
152415 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152416 +#endif
152417 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152418 +
152419 +#endif /* FM_CAPWAP_SUPPORT */
152420 +
152421 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
152422 +#if defined(CONFIG_COMPAT)
152423 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
152424 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
152425 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
152426 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
152427 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
152428 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
152429 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
152430 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
152431 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
152432 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
152433 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
152434 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
152435 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
152436 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
152437 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
152438 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
152439 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
152440 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
152441 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
152442 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
152443 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
152444 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
152445 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152446 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
152447 +#endif
152448 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
152449 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
152450 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
152451 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
152452 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
152453 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
152454 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
152455 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
152456 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
152457 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
152458 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
152459 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
152460 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
152461 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
152462 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
152463 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
152464 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
152465 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
152466 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
152467 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
152468 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
152469 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
152470 +
152471 +#endif /* __FM_PCD_IOCTLS_H */
152472 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
152473 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
152474 +/** @} */ /* end of lnx_ioctl_FM_grp group */
152475 --- /dev/null
152476 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
152477 @@ -0,0 +1,948 @@
152478 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
152479 + * All rights reserved.
152480 + *
152481 + * Redistribution and use in source and binary forms, with or without
152482 + * modification, are permitted provided that the following conditions are met:
152483 + * * Redistributions of source code must retain the above copyright
152484 + * notice, this list of conditions and the following disclaimer.
152485 + * * Redistributions in binary form must reproduce the above copyright
152486 + * notice, this list of conditions and the following disclaimer in the
152487 + * documentation and/or other materials provided with the distribution.
152488 + * * Neither the name of Freescale Semiconductor nor the
152489 + * names of its contributors may be used to endorse or promote products
152490 + * derived from this software without specific prior written permission.
152491 + *
152492 + *
152493 + * ALTERNATIVELY, this software may be distributed under the terms of the
152494 + * GNU General Public License ("GPL") as published by the Free Software
152495 + * Foundation, either version 2 of that License or (at your option) any
152496 + * later version.
152497 + *
152498 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
152499 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
152500 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
152501 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
152502 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
152503 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
152504 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
152505 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
152506 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
152507 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
152508 + */
152509 +
152510 +/******************************************************************************
152511 + @File fm_port_ioctls.h
152512 +
152513 + @Description FM Port routines
152514 +*//***************************************************************************/
152515 +#ifndef __FM_PORT_IOCTLS_H
152516 +#define __FM_PORT_IOCTLS_H
152517 +
152518 +#include "enet_ext.h"
152519 +#include "net_ioctls.h"
152520 +#include "fm_ioctls.h"
152521 +#include "fm_pcd_ioctls.h"
152522 +
152523 +
152524 +/**************************************************************************//**
152525 +
152526 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
152527 +
152528 + @Description FM Linux ioctls definitions and enums
152529 +
152530 + @{
152531 +*//***************************************************************************/
152532 +
152533 +/**************************************************************************//**
152534 + @Group lnx_ioctl_FM_PORT_grp FM Port
152535 +
152536 + @Description FM Port API
152537 +
152538 + The FM uses a general module called "port" to represent a Tx port
152539 + (MAC), an Rx port (MAC), offline parsing flow or host command
152540 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
152541 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
152542 + Host command/Offline parsing ports. The SW driver manages these
152543 + ports as sub-modules of the FM, i.e. after an FM is initialized,
152544 + its ports may be initialized and operated upon.
152545 +
152546 + The port is initialized aware of its type, but other functions on
152547 + a port may be indifferent to its type. When necessary, the driver
152548 + verifies coherency and returns error if applicable.
152549 +
152550 + On initialization, user specifies the port type and it's index
152551 + (relative to the port's type). Host command and Offline parsing
152552 + ports share the same id range, I.e user may not initialized host
152553 + command port 0 and offline parsing port 0.
152554 +
152555 + @{
152556 +*//***************************************************************************/
152557 +
152558 +/**************************************************************************//**
152559 + @Description An enum for defining port PCD modes.
152560 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
152561 +
152562 + This enum defines the superset of PCD engines support - i.e. not
152563 + all engines have to be used, but all have to be enabled. The real
152564 + flow of a specific frame depends on the PCD configuration and the
152565 + frame headers and payload.
152566 + Note: the first engine and the first engine after the parser (if
152567 + exists) should be in order, the order is important as it will
152568 + define the flow of the port. However, as for the rest engines
152569 + (the ones that follows), the order is not important anymore as
152570 + it is defined by the PCD graph itself.
152571 +*//***************************************************************************/
152572 +typedef enum ioc_fm_port_pcd_support {
152573 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
152574 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
152575 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
152576 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
152577 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
152578 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
152579 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
152580 + /**< Use all PCD engines */
152581 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
152582 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
152583 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
152584 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
152585 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152586 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
152587 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
152588 +#endif /* FM_CAPWAP_SUPPORT */
152589 +} ioc_fm_port_pcd_support;
152590 +
152591 +
152592 +/**************************************************************************//**
152593 + @Collection FM Frame error
152594 +*//***************************************************************************/
152595 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
152596 +
152597 +/* @} */
152598 +
152599 +
152600 +/**************************************************************************//**
152601 + @Description An enum for defining Dual Tx rate limiting scale.
152602 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
152603 +*//***************************************************************************/
152604 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
152605 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
152606 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
152607 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
152608 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
152609 +} ioc_fm_port_dual_rate_limiter_scale_down;
152610 +
152611 +/**************************************************************************//**
152612 + @Description A structure for defining Tx rate limiting
152613 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
152614 +*//***************************************************************************/
152615 +typedef struct ioc_fm_port_rate_limit_t {
152616 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
152617 + for offline parsing ports. (note that
152618 + for early chips burst size is
152619 + rounded up to a multiply of 1000 frames).*/
152620 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
152621 + offline parsing ports. Rate limit refers to
152622 + data rate (rather than line rate). */
152623 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
152624 + for some earlier chip revisions */
152625 +} ioc_fm_port_rate_limit_t;
152626 +
152627 +
152628 +
152629 +/**************************************************************************//**
152630 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
152631 +
152632 + @Description FM Port Runtime control unit API functions, definitions and enums.
152633 +
152634 + @{
152635 +*//***************************************************************************/
152636 +
152637 +/**************************************************************************//**
152638 + @Description An enum for defining FM Port counters.
152639 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
152640 +*//***************************************************************************/
152641 +typedef enum ioc_fm_port_counters {
152642 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
152643 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
152644 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
152645 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
152646 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
152647 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
152648 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
152649 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
152650 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
152651 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
152652 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
152653 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
152654 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
152655 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
152656 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
152657 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
152658 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
152659 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
152660 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
152661 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
152662 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
152663 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
152664 +} ioc_fm_port_counters;
152665 +
152666 +typedef struct ioc_fm_port_bmi_stats_t {
152667 + uint32_t cnt_cycle;
152668 + uint32_t cnt_task_util;
152669 + uint32_t cnt_queue_util;
152670 + uint32_t cnt_dma_util;
152671 + uint32_t cnt_fifo_util;
152672 + uint32_t cnt_rx_pause_activation;
152673 + uint32_t cnt_frame;
152674 + uint32_t cnt_discard_frame;
152675 + uint32_t cnt_dealloc_buf;
152676 + uint32_t cnt_rx_bad_frame;
152677 + uint32_t cnt_rx_large_frame;
152678 + uint32_t cnt_rx_filter_frame;
152679 + uint32_t cnt_rx_list_dma_err;
152680 + uint32_t cnt_rx_out_of_buffers_discard;
152681 + uint32_t cnt_wred_discard;
152682 + uint32_t cnt_length_err;
152683 + uint32_t cnt_unsupported_format;
152684 +} ioc_fm_port_bmi_stats_t;
152685 +
152686 +/**************************************************************************//**
152687 + @Description Structure for Port id parameters.
152688 + (Description may be inaccurate;
152689 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
152690 +
152691 + Fields commented 'IN' are passed by the port module to be used
152692 + by the FM module.
152693 + Fields commented 'OUT' will be filled by FM before returning to port.
152694 +*//***************************************************************************/
152695 +typedef struct ioc_fm_port_congestion_groups_t {
152696 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
152697 + to define the size of the following array */
152698 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
152699 + /**< An array of CG indexes;
152700 + Note that the size of the array should be
152701 + 'num_of_congestion_grps_to_consider'. */
152702 +#if DPAA_VERSION >= 11
152703 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
152704 + /**< A matrix that represents the map between the CG ids
152705 + defined in 'congestion_grps_to_consider' to the priorities
152706 + mapping array. */
152707 +#endif /* DPAA_VERSION >= 11 */
152708 +} ioc_fm_port_congestion_groups_t;
152709 +
152710 +
152711 +
152712 +/**************************************************************************//**
152713 + @Function FM_PORT_Disable
152714 +
152715 + @Description Gracefully disable an FM port. The port will not start new tasks after all
152716 + tasks associated with the port are terminated.
152717 +
152718 + @Return 0 on success; error code otherwise.
152719 +
152720 + @Cautions This is a blocking routine, it returns after port is
152721 + gracefully stopped, i.e. the port will not except new frames,
152722 + but it will finish all frames or tasks which were already began
152723 +*//***************************************************************************/
152724 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
152725 +
152726 +/**************************************************************************//**
152727 + @Function FM_PORT_Enable
152728 +
152729 + @Description A runtime routine provided to allow disable/enable of port.
152730 +
152731 + @Return 0 on success; error code otherwise.
152732 +*//***************************************************************************/
152733 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
152734 +
152735 +/**************************************************************************//**
152736 + @Function FM_PORT_SetRateLimit
152737 +
152738 + @Description Calling this routine enables rate limit algorithm.
152739 + By default, this functionality is disabled.
152740 + Note that rate-limit mechanism uses the FM time stamp.
152741 + The selected rate limit specified here would be
152742 + rounded DOWN to the nearest 16M.
152743 +
152744 + May be used for Tx and offline parsing ports only
152745 +
152746 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
152747 +
152748 + @Return 0 on success; error code otherwise.
152749 +*//***************************************************************************/
152750 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
152751 +
152752 +/**************************************************************************//**
152753 + @Function FM_PORT_DeleteRateLimit
152754 +
152755 + @Description Calling this routine disables the previously enabled rate limit.
152756 +
152757 + May be used for Tx and offline parsing ports only
152758 +
152759 + @Return 0 on success; error code otherwise.
152760 +*//***************************************************************************/
152761 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
152762 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
152763 +
152764 +
152765 +/**************************************************************************//**
152766 + @Function FM_PORT_AddCongestionGrps
152767 +
152768 + @Description This routine effects the corresponding Tx port.
152769 + It should be called in order to enable pause
152770 + frame transmission in case of congestion in one or more
152771 + of the congestion groups relevant to this port.
152772 + Each call to this routine may add one or more congestion
152773 + groups to be considered relevant to this port.
152774 +
152775 + May be used for Rx, or RX+OP ports only (depending on chip)
152776 +
152777 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
152778 + congestion group ids to consider.
152779 +
152780 + @Return 0 on success; error code otherwise.
152781 +*//***************************************************************************/
152782 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
152783 +
152784 +/**************************************************************************//**
152785 + @Function FM_PORT_RemoveCongestionGrps
152786 +
152787 + @Description This routine effects the corresponding Tx port. It should be
152788 + called when congestion groups were
152789 + defined for this port and are no longer relevant, or pause
152790 + frames transmitting is not required on their behalf.
152791 + Each call to this routine may remove one or more congestion
152792 + groups to be considered relevant to this port.
152793 +
152794 + May be used for Rx, or RX+OP ports only (depending on chip)
152795 +
152796 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
152797 + congestion group ids to consider.
152798 +
152799 + @Return 0 on success; error code otherwise.
152800 +*//***************************************************************************/
152801 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
152802 +
152803 +/**************************************************************************//**
152804 + @Function FM_PORT_SetErrorsRoute
152805 +
152806 + @Description Errors selected for this routine will cause a frame with that error
152807 + to be enqueued to error queue.
152808 + Errors not selected for this routine will cause a frame with that error
152809 + to be enqueued to the one of the other port queues.
152810 + By default all errors are defined to be enqueued to error queue.
152811 + Errors that were configured to be discarded (at initialization)
152812 + may not be selected here.
152813 +
152814 + May be used for Rx and offline parsing ports only
152815 +
152816 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
152817 +
152818 + @Return 0 on success; error code otherwise.
152819 +
152820 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
152821 + (szbs001: How is it possible to have one function that needs to be
152822 + called BEFORE FM_PORT_Init() implemented as an ioctl,
152823 + which will ALWAYS be called AFTER the FM_PORT_Init()
152824 + for that port!?!?!?!???!?!??!?!?)
152825 +*//***************************************************************************/
152826 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
152827 +
152828 +
152829 +/**************************************************************************//**
152830 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
152831 +
152832 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
152833 +
152834 + @{
152835 +*//***************************************************************************/
152836 +
152837 +/**************************************************************************//**
152838 + @Description A structure defining the KG scheme after the parser.
152839 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
152840 +
152841 + This is relevant only to change scheme selection mode - from
152842 + direct to indirect and vice versa, or when the scheme is selected directly,
152843 + to select the scheme id.
152844 +
152845 +*//***************************************************************************/
152846 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
152847 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
152848 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
152849 + 'scheme_id' selects the scheme after parser. */
152850 +} ioc_fm_pcd_kg_scheme_select_t;
152851 +
152852 +/**************************************************************************//**
152853 + @Description Scheme IDs structure
152854 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
152855 +*//***************************************************************************/
152856 +typedef struct ioc_fm_pcd_port_schemes_params_t {
152857 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
152858 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
152859 + port to be bound to */
152860 +} ioc_fm_pcd_port_schemes_params_t;
152861 +
152862 +/**************************************************************************//**
152863 + @Description A union for defining port protocol parameters for parser
152864 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
152865 +*//***************************************************************************/
152866 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
152867 + /* MPLS */
152868 + struct {
152869 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
152870 + interpreted as described in HW spec table. When the bit
152871 + is cleared, the parser will advance to MPLS next parse */
152872 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
152873 + } mpls_prs_options;
152874 +
152875 + /* VLAN */
152876 + struct {
152877 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
152878 + on VLAN TAG on top of 0x8100 and 0x88A8 */
152879 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
152880 + on VLAN TAG on top of 0x8100 and 0x88A8 */
152881 + } vlan_prs_options;
152882 +
152883 + /* PPP */
152884 + struct{
152885 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
152886 + } pppoe_prs_options;
152887 +
152888 + /* IPV6 */
152889 + struct {
152890 + bool routing_hdr_disable; /**< Disable routing header */
152891 + } ipv6_prs_options;
152892 +
152893 + /* UDP */
152894 + struct {
152895 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
152896 + } udp_prs_options;
152897 +
152898 + /* TCP */
152899 + struct {
152900 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
152901 + } tcp_prs_options;
152902 +} ioc_fm_pcd_hdr_prs_opts_u;
152903 +
152904 +/**************************************************************************//**
152905 + @Description A structure for defining each header for the parser
152906 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
152907 +*//***************************************************************************/
152908 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
152909 + ioc_net_header_type hdr; /**< Selected header */
152910 + bool err_disable; /**< TRUE to disable error indication */
152911 + bool soft_prs_enable; /**< Enable jump to SW parser when this
152912 + header is recognized by the HW parser. */
152913 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
152914 + attachments exists for the same header,
152915 + (in the main sw parser code) use this
152916 + index to distinguish between them. */
152917 + bool use_prs_opts; /**< TRUE to use parser options. */
152918 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
152919 + defining the parser options selected.*/
152920 +} ioc_fm_pcd_prs_additional_hdr_params_t;
152921 +
152922 +/**************************************************************************//**
152923 + @Description A structure for defining port PCD parameters
152924 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
152925 +*//***************************************************************************/
152926 +typedef struct ioc_fm_port_pcd_prs_params_t {
152927 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
152928 + port information into the parser result. This information
152929 + may be extracted by KeyGen and be used for frames
152930 + distribution when a per-port distinction is required,
152931 + it may also be used as a port logical id for analyzing
152932 + incoming frames. */
152933 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
152934 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
152935 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
152936 + uint8_t num_of_hdrs_with_additional_params;
152937 + /**< Normally 0, some headers may get special parameters */
152938 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
152939 + /**< 'num_of_hdrs_with_additional_params' structures
152940 + additional parameters for each header that requires them */
152941 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
152942 + indicate a VLAN tag (in addition to the TPID values
152943 + 0x8100 and 0x88A8). */
152944 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
152945 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
152946 + indicate a VLAN tag (in addition to the TPID values
152947 + 0x8100 and 0x88A8). */
152948 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
152949 +} ioc_fm_port_pcd_prs_params_t;
152950 +
152951 +/**************************************************************************//**
152952 + @Description A structure for defining coarse alassification parameters
152953 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
152954 +*//***************************************************************************/
152955 +typedef struct ioc_fm_port_pcd_cc_params_t {
152956 + void *cc_tree_id; /**< CC tree id */
152957 +} ioc_fm_port_pcd_cc_params_t;
152958 +
152959 +/**************************************************************************//**
152960 + @Description A structure for defining keygen parameters
152961 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
152962 +*//***************************************************************************/
152963 +typedef struct ioc_fm_port_pcd_kg_params_t {
152964 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
152965 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
152966 + /**< Array of 'num_of_schemes' schemes for the
152967 + port to be bound to */
152968 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
152969 + regardless of parser result */
152970 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
152971 + relevant only if direct=TRUE. */
152972 +} ioc_fm_port_pcd_kg_params_t;
152973 +
152974 +/**************************************************************************//**
152975 + @Description A structure for defining policer parameters
152976 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
152977 +*//***************************************************************************/
152978 +typedef struct ioc_fm_port_pcd_plcr_params_t {
152979 + void *plcr_profile_id; /**< Selected profile handle;
152980 + relevant in one of the following cases:
152981 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
152982 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
152983 + or if any flow uses a KG scheme where policer
152984 + profile is not generated (bypass_plcr_profile_generation selected) */
152985 +} ioc_fm_port_pcd_plcr_params_t;
152986 +
152987 +/**************************************************************************//**
152988 + @Description A structure for defining port PCD parameters
152989 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
152990 +*//***************************************************************************/
152991 +typedef struct ioc_fm_port_pcd_params_t {
152992 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
152993 + Describes the active PCD engines for this port. */
152994 + void *net_env_id; /**< HL Unused in PLCR only mode */
152995 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
152996 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
152997 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
152998 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
152999 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
153000 +#if (DPAA_VERSION >= 11)
153001 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
153002 +#endif /* (DPAA_VERSION >= 11) */
153003 +} ioc_fm_port_pcd_params_t;
153004 +
153005 +/**************************************************************************//**
153006 + @Description A structure for defining the Parser starting point
153007 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
153008 +*//***************************************************************************/
153009 +typedef struct ioc_fm_pcd_prs_start_t {
153010 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
153011 + start parsing */
153012 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
153013 + 'parsing_offset' */
153014 +} ioc_fm_pcd_prs_start_t;
153015 +
153016 +
153017 +/**************************************************************************//**
153018 + @Description FQID parameters structure
153019 +*//***************************************************************************/
153020 +typedef struct ioc_fm_port_pcd_fqids_params_t {
153021 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
153022 + uint8_t alignment; /**< Alignment required for this port */
153023 + uint32_t base_fqid; /**< output parameter - the base fqid */
153024 +} ioc_fm_port_pcd_fqids_params_t;
153025 +
153026 +
153027 +/**************************************************************************//**
153028 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
153029 +
153030 + @Description Allocates FQID's
153031 +
153032 + May be used for Rx and offline parsing ports only
153033 +
153034 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
153035 +
153036 + @Return 0 on success; error code otherwise.
153037 +*//***************************************************************************/
153038 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
153039 +
153040 +/**************************************************************************//**
153041 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
153042 +
153043 + @Description Frees previously-allocated FQIDs
153044 +
153045 + May be used for Rx and offline parsing ports only
153046 +
153047 + @Param[in] uint32_t Base FQID of previously allocated range.
153048 +
153049 + @Return 0 on success; error code otherwise.
153050 +*//***************************************************************************/
153051 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
153052 +
153053 +
153054 +/**************************************************************************//**
153055 + @Function FM_PORT_SetPCD
153056 +
153057 + @Description Calling this routine defines the port's PCD configuration.
153058 + It changes it from its default configuration which is PCD
153059 + disabled (BMI to BMI) and configures it according to the passed
153060 + parameters.
153061 +
153062 + May be used for Rx and offline parsing ports only
153063 +
153064 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
153065 + configuration.
153066 +
153067 + @Return 0 on success; error code otherwise.
153068 +*//***************************************************************************/
153069 +#if defined(CONFIG_COMPAT)
153070 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
153071 +#endif
153072 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
153073 +
153074 +/**************************************************************************//**
153075 + @Function FM_PORT_DeletePCD
153076 +
153077 + @Description Calling this routine releases the port's PCD configuration.
153078 + The port returns to its default configuration which is PCD
153079 + disabled (BMI to BMI) and all PCD configuration is removed.
153080 +
153081 + May be used for Rx and offline parsing ports which are
153082 + in PCD mode only
153083 +
153084 + @Return 0 on success; error code otherwise.
153085 +*//***************************************************************************/
153086 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
153087 +
153088 +/**************************************************************************//**
153089 + @Function FM_PORT_AttachPCD
153090 +
153091 + @Description This routine may be called after FM_PORT_DetachPCD was called,
153092 + to return to the originally configured PCD support flow.
153093 + The couple of routines are used to allow PCD configuration changes
153094 + that demand that PCD will not be used while changes take place.
153095 +
153096 + May be used for Rx and offline parsing ports which are
153097 + in PCD mode only
153098 +
153099 + @Return 0 on success; error code otherwise.
153100 +*//***************************************************************************/
153101 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
153102 +
153103 +/**************************************************************************//**
153104 + @Function FM_PORT_DetachPCD
153105 +
153106 + @Description Calling this routine detaches the port from its PCD functionality.
153107 + The port returns to its default flow which is BMI to BMI.
153108 +
153109 + May be used for Rx and offline parsing ports which are
153110 + in PCD mode only
153111 +
153112 + @Return 0 on success; error code otherwise.
153113 +*//***************************************************************************/
153114 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
153115 +
153116 +/**************************************************************************//**
153117 + @Function FM_PORT_PcdPlcrAllocProfiles
153118 +
153119 + @Description This routine may be called only for ports that use the Policer in
153120 + order to allocate private policer profiles.
153121 +
153122 + @Param[in] uint16_t The number of required policer profiles
153123 +
153124 + @Return 0 on success; error code otherwise.
153125 +
153126 + @Cautions Allowed before FM_PORT_SetPCD() only.
153127 +*//***************************************************************************/
153128 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
153129 +
153130 +/**************************************************************************//**
153131 + @Function FM_PORT_PcdPlcrFreeProfiles
153132 +
153133 + @Description This routine should be called for freeing private policer profiles.
153134 +
153135 + @Return 0 on success; error code otherwise.
153136 +
153137 + @Cautions Allowed before FM_PORT_SetPCD() only.
153138 +*//***************************************************************************/
153139 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
153140 +
153141 +/**************************************************************************//**
153142 + @Function FM_PORT_PcdKgModifyInitialScheme
153143 +
153144 + @Description This routine may be called only for ports that use the keygen in
153145 + order to change the initial scheme frame should be routed to.
153146 + The change may be of a scheme id (in case of direct mode),
153147 + from direct to indirect, or from indirect to direct - specifying the scheme id.
153148 +
153149 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
153150 + a scheme is direct/indirect, and if direct - scheme id.
153151 +
153152 + @Return 0 on success; error code otherwise.
153153 +*//***************************************************************************/
153154 +#if defined(CONFIG_COMPAT)
153155 +#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)
153156 +#endif
153157 +#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)
153158 +
153159 +/**************************************************************************//**
153160 + @Function FM_PORT_PcdPlcrModifyInitialProfile
153161 +
153162 + @Description This routine may be called for ports with flows
153163 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
153164 + to change the initial Policer profile frame should be routed to.
153165 + The change may be of a profile and/or absolute/direct mode selection.
153166 +
153167 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
153168 +
153169 + @Return 0 on success; error code otherwise.
153170 +*//***************************************************************************/
153171 +#if defined(CONFIG_COMPAT)
153172 +#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)
153173 +#endif
153174 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
153175 +
153176 +/**************************************************************************//**
153177 + @Function FM_PORT_PcdCcModifyTree
153178 +
153179 + @Description This routine may be called to change this port connection to
153180 + a pre-initializes coarse classification Tree.
153181 +
153182 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
153183 +
153184 + @Return 0 on success; error code otherwise.
153185 +
153186 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
153187 +*//***************************************************************************/
153188 +#if defined(CONFIG_COMPAT)
153189 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
153190 +#endif
153191 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
153192 +
153193 +/**************************************************************************//**
153194 + @Function FM_PORT_PcdKgBindSchemes
153195 +
153196 + @Description These routines may be called for modifying the binding of ports
153197 + to schemes. The scheme itself is not added,
153198 + just this specific port starts using it.
153199 +
153200 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153201 +
153202 + @Return 0 on success; error code otherwise.
153203 +
153204 + @Cautions Allowed only following FM_PORT_SetPCD().
153205 +*//***************************************************************************/
153206 +#if defined(CONFIG_COMPAT)
153207 +#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)
153208 +#endif
153209 +#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)
153210 +
153211 +/**************************************************************************//**
153212 + @Function FM_PORT_PcdKgUnbindSchemes
153213 +
153214 + @Description These routines may be called for modifying the binding of ports
153215 + to schemes. The scheme itself is not removed or invalidated,
153216 + just this specific port stops using it.
153217 +
153218 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153219 +
153220 + @Return 0 on success; error code otherwise.
153221 +
153222 + @Cautions Allowed only following FM_PORT_SetPCD().
153223 +*//***************************************************************************/
153224 +#if defined(CONFIG_COMPAT)
153225 +#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)
153226 +#endif
153227 +#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)
153228 +
153229 +typedef struct ioc_fm_port_mac_addr_params_t {
153230 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
153231 +} ioc_fm_port_mac_addr_params_t;
153232 +
153233 +/**************************************************************************//**
153234 + @Function FM_MAC_AddHashMacAddr
153235 +
153236 + @Description Add an Address to the hash table. This is for filter purpose only.
153237 +
153238 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153239 +
153240 + @Return E_OK on success; Error code otherwise.
153241 +
153242 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
153243 + @Cautions Some address need to be filtered out in upper FM blocks.
153244 +*//***************************************************************************/
153245 +#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)
153246 +
153247 +/**************************************************************************//**
153248 + @Function FM_MAC_RemoveHashMacAddr
153249 +
153250 + @Description Delete an Address to the hash table. This is for filter purpose only.
153251 +
153252 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153253 +
153254 + @Return E_OK on success; Error code otherwise.
153255 +
153256 + @Cautions Allowed only following FM_MAC_Init().
153257 +*//***************************************************************************/
153258 +#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)
153259 +
153260 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
153261 + uint8_t priority;
153262 + uint16_t pause_time;
153263 + uint16_t thresh_time;
153264 +} ioc_fm_port_tx_pause_frames_params_t;
153265 +
153266 +/**************************************************************************//**
153267 + @Function FM_MAC_SetTxPauseFrames
153268 +
153269 + @Description Enable/Disable transmission of Pause-Frames.
153270 + The routine changes the default configuration:
153271 + pause-time - [0xf000]
153272 + threshold-time - [0]
153273 +
153274 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
153275 +
153276 + @Return E_OK on success; Error code otherwise.
153277 +
153278 + @Cautions Allowed only following FM_MAC_Init().
153279 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
153280 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
153281 + in the 'priority' field.
153282 +*//***************************************************************************/
153283 +#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)
153284 +
153285 +typedef struct ioc_fm_port_mac_statistics_t {
153286 + /* RMON */
153287 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
153288 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
153289 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
153290 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
153291 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
153292 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
153293 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
153294 + /* */
153295 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
153296 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
153297 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
153298 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
153299 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
153300 + This count does not include range length errors */
153301 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
153302 + a valid FCS and otherwise well formed */
153303 + /* Pause */
153304 + uint64_t te_stat_pause; /**< Pause MAC Control received */
153305 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
153306 + /* MIB II */
153307 + uint64_t if_in_octets; /**< Total number of byte received. */
153308 + uint64_t if_in_pkts; /**< Total number of packets received.*/
153309 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
153310 + NOTE: this counter is not supported on dTSEC MAC */
153311 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
153312 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
153313 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
153314 + uint64_t if_in_errors; /**< Number of frames received with error:
153315 + - FIFO Overflow Error
153316 + - CRC Error
153317 + - Frame Too Long Error
153318 + - Alignment Error
153319 + - The dedicated Error Code (0xfe, not a code error) was received */
153320 + uint64_t if_out_octets; /**< Total number of byte sent. */
153321 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
153322 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
153323 + NOTE: this counter is not supported on dTSEC MAC */
153324 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
153325 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
153326 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
153327 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
153328 + - FIFO Overflow Error
153329 + - FIFO Underflow Error
153330 + - Other */
153331 +} ioc_fm_port_mac_statistics_t;
153332 +
153333 +/**************************************************************************//**
153334 + @Function FM_MAC_GetStatistics
153335 +
153336 + @Description get all MAC statistics counters
153337 +
153338 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
153339 +
153340 + @Return E_OK on success; Error code otherwise.
153341 +
153342 + @Cautions Allowed only following FM_Init().
153343 +*//***************************************************************************/
153344 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
153345 +
153346 +/**************************************************************************//**
153347 + @Function FM_PORT_ConfigBufferPrefixContent
153348 +
153349 + @Description Defines the structure, size and content of the application buffer.
153350 + The prefix will
153351 + In Tx ports, if 'passPrsResult', the application
153352 + should set a value to their offsets in the prefix of
153353 + the FM will save the first 'privDataSize', than,
153354 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
153355 + and timeStamp, and the packet itself (in this order), to the
153356 + application buffer, and to offset.
153357 + Calling this routine changes the buffer margins definitions
153358 + in the internal driver data base from its default
153359 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
153360 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
153361 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
153362 +
153363 + May be used for all ports
153364 +
153365 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
153366 +
153367 + @Return E_OK on success; Error code otherwise.
153368 +
153369 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153370 +*//***************************************************************************/
153371 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
153372 +
153373 +#if (DPAA_VERSION >= 11)
153374 +typedef struct ioc_fm_port_vsp_alloc_params_t {
153375 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
153376 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
153377 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
153378 + if relevant function called for Rx port */
153379 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
153380 +}ioc_fm_port_vsp_alloc_params_t;
153381 +
153382 +/**************************************************************************//**
153383 + @Function FM_PORT_VSPAlloc
153384 +
153385 + @Description This routine allocated VSPs per port and forces the port to work
153386 + in VSP mode. Note that the port is initialized by default with the
153387 + physical-storage-profile only.
153388 +
153389 + @Param[in] h_FmPort A handle to a FM Port module.
153390 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
153391 +
153392 + @Return E_OK on success; Error code otherwise.
153393 +
153394 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
153395 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
153396 +*//***************************************************************************/
153397 +#if defined(CONFIG_COMPAT)
153398 +#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)
153399 +#endif
153400 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
153401 +#endif /* (DPAA_VERSION >= 11) */
153402 +
153403 +/**************************************************************************//**
153404 + @Function FM_PORT_GetBmiCounters
153405 +
153406 + @Description Read port's BMI stat counters and place them into
153407 + a designated structure of counters.
153408 +
153409 + @Param[in] h_FmPort A handle to a FM Port module.
153410 + @Param[out] p_BmiStats counters structure
153411 +
153412 + @Return E_OK on success; Error code otherwise.
153413 +
153414 + @Cautions Allowed only following FM_PORT_Init().
153415 +*//***************************************************************************/
153416 +
153417 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
153418 +
153419 +
153420 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
153421 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
153422 +
153423 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
153424 +/** @} */ /* end of lnx_ioctl_FM_grp group */
153425 +#endif /* __FM_PORT_IOCTLS_H */
153426 --- /dev/null
153427 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
153428 @@ -0,0 +1,208 @@
153429 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153430 + * All rights reserved.
153431 + *
153432 + * Redistribution and use in source and binary forms, with or without
153433 + * modification, are permitted provided that the following conditions are met:
153434 + * * Redistributions of source code must retain the above copyright
153435 + * notice, this list of conditions and the following disclaimer.
153436 + * * Redistributions in binary form must reproduce the above copyright
153437 + * notice, this list of conditions and the following disclaimer in the
153438 + * documentation and/or other materials provided with the distribution.
153439 + * * Neither the name of Freescale Semiconductor nor the
153440 + * names of its contributors may be used to endorse or promote products
153441 + * derived from this software without specific prior written permission.
153442 + *
153443 + *
153444 + * ALTERNATIVELY, this software may be distributed under the terms of the
153445 + * GNU General Public License ("GPL") as published by the Free Software
153446 + * Foundation, either version 2 of that License or (at your option) any
153447 + * later version.
153448 + *
153449 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153450 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153451 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153452 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153453 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153454 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153455 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153456 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153457 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153458 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153459 + */
153460 +
153461 +/**************************************************************************//**
153462 + @File fm_test_ioctls.h
153463 +
153464 + @Description FM Char device ioctls
153465 +*//***************************************************************************/
153466 +#ifndef __FM_TEST_IOCTLS_H
153467 +#define __FM_TEST_IOCTLS_H
153468 +
153469 +#include "ioctls.h"
153470 +
153471 +
153472 +/**************************************************************************//**
153473 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
153474 +
153475 + @Description FM-Test Linux ioctls definitions and enums
153476 +
153477 + @{
153478 +*//***************************************************************************/
153479 +
153480 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
153481 +
153482 +/**************************************************************************//**
153483 + @Collection TEST Parameters
153484 +*//***************************************************************************/
153485 +/**************************************************************************//**
153486 + @Description: Name of the FM-Test chardev
153487 +*//***************************************************************************/
153488 +#define DEV_FM_TEST_NAME "fm-test-port"
153489 +
153490 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
153491 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
153492 +
153493 +#define FMT_PORT_IOC_NUM(n) n
153494 +/* @} */
153495 +
153496 +/**************************************************************************//**
153497 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
153498 +
153499 + @Description TODO
153500 +
153501 + @{
153502 +*//***************************************************************************/
153503 +
153504 +/**************************************************************************//**
153505 + @Description TODO
153506 +*//***************************************************************************/
153507 +typedef uint8_t ioc_fmt_xxx_t;
153508 +
153509 +#define FM_PRS_MAX 32
153510 +#define FM_TIME_STAMP_MAX 8
153511 +
153512 +/**************************************************************************//**
153513 + @Description FM Port buffer content description
153514 +*//***************************************************************************/
153515 +typedef struct ioc_fmt_buff_context_t {
153516 + void *p_user_priv;
153517 + uint8_t fm_prs_res[FM_PRS_MAX];
153518 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
153519 +} ioc_fmt_buff_context_t;
153520 +
153521 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
153522 +typedef struct ioc_fmt_compat_buff_context_t {
153523 + compat_uptr_t p_user_priv;
153524 + uint8_t fm_prs_res[FM_PRS_MAX];
153525 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
153526 +} ioc_fmt_compat_buff_context_t;
153527 +#endif
153528 +
153529 +/**************************************************************************//**
153530 + @Description Buffer descriptor
153531 +*//***************************************************************************/
153532 +typedef struct ioc_fmt_buff_desc_t {
153533 + uint32_t qid;
153534 + void *p_data;
153535 + uint32_t size;
153536 + uint32_t status;
153537 + ioc_fmt_buff_context_t buff_context;
153538 +} ioc_fmt_buff_desc_t;
153539 +
153540 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
153541 +typedef struct ioc_fmt_compat_buff_desc_t {
153542 + uint32_t qid;
153543 + compat_uptr_t p_data;
153544 + uint32_t size;
153545 + uint32_t status;
153546 + ioc_fmt_compat_buff_context_t buff_context;
153547 +} ioc_fmt_compat_buff_desc_t;
153548 +#endif
153549 +
153550 +/**************************************************************************//**
153551 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
153552 +
153553 + @Description TODO
153554 + @{
153555 +*//***************************************************************************/
153556 +
153557 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
153558 +
153559 +
153560 +/**************************************************************************//**
153561 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
153562 +
153563 + @Description TODO
153564 +
153565 + @{
153566 +*//***************************************************************************/
153567 +
153568 +/**************************************************************************//**
153569 + @Description FM-Test FM port type
153570 +*//***************************************************************************/
153571 +typedef enum ioc_fmt_port_type {
153572 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
153573 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
153574 +} ioc_fmt_port_type;
153575 +
153576 +/**************************************************************************//**
153577 + @Description TODO
153578 +*//***************************************************************************/
153579 +typedef struct ioc_fmt_port_param_t {
153580 + uint8_t fm_id;
153581 + ioc_fmt_port_type fm_port_type;
153582 + uint8_t fm_port_id;
153583 + uint32_t num_tx_queues;
153584 +} ioc_fmt_port_param_t;
153585 +
153586 +
153587 +/**************************************************************************//**
153588 + @Function FMT_PORT_IOC_INIT
153589 +
153590 + @Description TODO
153591 +
153592 + @Param[in] ioc_fmt_port_param_t TODO
153593 +
153594 + @Cautions Allowed only after the FM equivalent port is already initialized.
153595 +*//***************************************************************************/
153596 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
153597 +
153598 +/**************************************************************************//**
153599 + @Function FMT_PORT_IOC_SET_DIAG_MODE
153600 +
153601 + @Description TODO
153602 +
153603 + @Param[in] ioc_diag_mode TODO
153604 +
153605 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153606 +*//***************************************************************************/
153607 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
153608 +
153609 +/**************************************************************************//**
153610 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
153611 +
153612 + @Description Set IP header manipulations for this port.
153613 +
153614 + @Param[in] int 1 to enable; 0 to disable
153615 +
153616 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153617 +*//***************************************************************************/
153618 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
153619 +
153620 +/**************************************************************************//**
153621 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
153622 +
153623 + @Description Set DPA in echo mode - all frame are sent back.
153624 +
153625 + @Param[in] int 1 to enable; 0 to disable
153626 +
153627 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
153628 +*//***************************************************************************/
153629 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
153630 +
153631 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
153632 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
153633 +/** @} */ /* end of lnx_ioctl_FMT_grp */
153634 +
153635 +
153636 +#endif /* __FM_TEST_IOCTLS_H */
153637 --- /dev/null
153638 +++ b/include/uapi/linux/fmd/integrations/Kbuild
153639 @@ -0,0 +1 @@
153640 +header-y += integration_ioctls.h
153641 --- /dev/null
153642 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
153643 @@ -0,0 +1,56 @@
153644 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153645 + * All rights reserved.
153646 + *
153647 + * Redistribution and use in source and binary forms, with or without
153648 + * modification, are permitted provided that the following conditions are met:
153649 + * * Redistributions of source code must retain the above copyright
153650 + * notice, this list of conditions and the following disclaimer.
153651 + * * Redistributions in binary form must reproduce the above copyright
153652 + * notice, this list of conditions and the following disclaimer in the
153653 + * documentation and/or other materials provided with the distribution.
153654 + * * Neither the name of Freescale Semiconductor nor the
153655 + * names of its contributors may be used to endorse or promote products
153656 + * derived from this software without specific prior written permission.
153657 + *
153658 + *
153659 + * ALTERNATIVELY, this software may be distributed under the terms of the
153660 + * GNU General Public License ("GPL") as published by the Free Software
153661 + * Foundation, either version 2 of that License or (at your option) any
153662 + * later version.
153663 + *
153664 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153665 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153666 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153667 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153668 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153669 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153670 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153671 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153672 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153673 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153674 + */
153675 +
153676 +/**************************************************************************//**
153677 + @File integration_ioctls.h
153678 +
153679 + @Description External header file for Integration unit routines.
153680 +*//***************************************************************************/
153681 +
153682 +#ifndef __INTG_IOCTLS_H
153683 +#define __INTG_IOCTLS_H
153684 +
153685 +
153686 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
153687 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
153688 +
153689 +/*#define FM_IOCTL_DBG*/
153690 +
153691 +#if defined(FM_IOCTL_DBG)
153692 + #define _fm_ioctl_dbg(format, arg...) \
153693 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
153694 + __func__, __LINE__, smp_processor_id(), ##arg)
153695 +#else
153696 +# define _fm_ioctl_dbg(arg...)
153697 +#endif
153698 +
153699 +#endif /* __INTG_IOCTLS_H */
153700 --- /dev/null
153701 +++ b/include/uapi/linux/fmd/ioctls.h
153702 @@ -0,0 +1,96 @@
153703 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153704 + * All rights reserved.
153705 + *
153706 + * Redistribution and use in source and binary forms, with or without
153707 + * modification, are permitted provided that the following conditions are met:
153708 + * * Redistributions of source code must retain the above copyright
153709 + * notice, this list of conditions and the following disclaimer.
153710 + * * Redistributions in binary form must reproduce the above copyright
153711 + * notice, this list of conditions and the following disclaimer in the
153712 + * documentation and/or other materials provided with the distribution.
153713 + * * Neither the name of Freescale Semiconductor nor the
153714 + * names of its contributors may be used to endorse or promote products
153715 + * derived from this software without specific prior written permission.
153716 + *
153717 + *
153718 + * ALTERNATIVELY, this software may be distributed under the terms of the
153719 + * GNU General Public License ("GPL") as published by the Free Software
153720 + * Foundation, either version 2 of that License or (at your option) any
153721 + * later version.
153722 + *
153723 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153724 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153725 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153726 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153727 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153728 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153729 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153730 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153731 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153732 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153733 + */
153734 +
153735 +/**************************************************************************//**
153736 + @File ioctls.h
153737 +
153738 + @Description Structures and definitions for Command Relay Ioctls
153739 +*//***************************************************************************/
153740 +
153741 +#ifndef __IOCTLS_H__
153742 +#define __IOCTLS_H__
153743 +
153744 +#include <asm/ioctl.h>
153745 +
153746 +#include "integration_ioctls.h"
153747 +
153748 +
153749 +/**************************************************************************//**
153750 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
153751 + @{
153752 +*//***************************************************************************/
153753 +
153754 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
153755 + the NCSW Linux module commands */
153756 +
153757 +
153758 +/**************************************************************************//**
153759 + @Description IOCTL Memory allocation types.
153760 +*//***************************************************************************/
153761 +typedef enum ioc_mem_type {
153762 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
153763 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
153764 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
153765 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
153766 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
153767 +} ioc_mem_type;
153768 +
153769 +/**************************************************************************//**
153770 + @Description Enumeration (bit flags) of communication modes (Transmit,
153771 + receive or both).
153772 +*//***************************************************************************/
153773 +typedef enum ioc_comm_mode {
153774 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
153775 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
153776 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
153777 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
153778 +} ioc_comm_mode;
153779 +
153780 +/**************************************************************************//**
153781 + @Description General Diagnostic Mode
153782 +*//***************************************************************************/
153783 +typedef enum ioc_diag_mode
153784 +{
153785 + e_IOC_DIAG_MODE_NONE = 0,
153786 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
153787 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
153788 + E.g. IO-pins, SerDes, etc. */
153789 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
153790 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
153791 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
153792 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
153793 +} ioc_diag_mode;
153794 +
153795 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
153796 +
153797 +
153798 +#endif /* __IOCTLS_H__ */
153799 --- /dev/null
153800 +++ b/include/uapi/linux/fmd/net_ioctls.h
153801 @@ -0,0 +1,430 @@
153802 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153803 + * All rights reserved.
153804 + *
153805 + * Redistribution and use in source and binary forms, with or without
153806 + * modification, are permitted provided that the following conditions are met:
153807 + * * Redistributions of source code must retain the above copyright
153808 + * notice, this list of conditions and the following disclaimer.
153809 + * * Redistributions in binary form must reproduce the above copyright
153810 + * notice, this list of conditions and the following disclaimer in the
153811 + * documentation and/or other materials provided with the distribution.
153812 + * * Neither the name of Freescale Semiconductor nor the
153813 + * names of its contributors may be used to endorse or promote products
153814 + * derived from this software without specific prior written permission.
153815 + *
153816 + *
153817 + * ALTERNATIVELY, this software may be distributed under the terms of the
153818 + * GNU General Public License ("GPL") as published by the Free Software
153819 + * Foundation, either version 2 of that License or (at your option) any
153820 + * later version.
153821 + *
153822 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153823 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153824 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153825 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153826 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153827 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153828 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153829 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153830 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153831 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153832 + */
153833 +
153834 +
153835 +/**************************************************************************//**
153836 + @File net_ioctls.h
153837 +
153838 + @Description This file contains common and general netcomm headers definitions.
153839 +*//***************************************************************************/
153840 +#ifndef __NET_IOCTLS_H
153841 +#define __NET_IOCTLS_H
153842 +
153843 +#include "ioctls.h"
153844 +
153845 +
153846 +typedef uint8_t ioc_header_field_ppp_t;
153847 +
153848 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
153849 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
153850 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
153851 +
153852 +
153853 +typedef uint8_t ioc_header_field_pppoe_t;
153854 +
153855 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
153856 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
153857 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
153858 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
153859 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
153860 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
153861 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
153862 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
153863 +
153864 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
153865 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
153866 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
153867 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
153868 +
153869 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
153870 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
153871 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
153872 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
153873 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
153874 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
153875 +
153876 +
153877 +typedef uint8_t ioc_header_field_eth_t;
153878 +
153879 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
153880 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
153881 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
153882 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
153883 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
153884 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
153885 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
153886 +
153887 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
153888 +
153889 +typedef uint16_t ioc_header_field_ip_t;
153890 +
153891 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
153892 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
153893 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
153894 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
153895 +
153896 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
153897 +
153898 +typedef uint16_t ioc_header_field_ipv4_t;
153899 +
153900 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
153901 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
153902 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
153903 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
153904 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
153905 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
153906 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
153907 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
153908 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
153909 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
153910 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
153911 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
153912 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
153913 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
153914 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
153915 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
153916 +
153917 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
153918 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
153919 +
153920 +
153921 +typedef uint8_t ioc_header_field_ipv6_t;
153922 +
153923 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
153924 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
153925 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
153926 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
153927 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
153928 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
153929 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
153930 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
153931 +
153932 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
153933 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
153934 +
153935 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
153936 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
153937 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
153938 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
153939 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
153940 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
153941 +
153942 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
153943 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
153944 +
153945 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
153946 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
153947 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
153948 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
153949 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
153950 +
153951 +
153952 +typedef uint16_t ioc_header_field_tcp_t;
153953 +
153954 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
153955 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
153956 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
153957 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
153958 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
153959 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
153960 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
153961 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
153962 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
153963 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
153964 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
153965 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
153966 +
153967 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
153968 +
153969 +
153970 +typedef uint8_t ioc_header_field_sctp_t;
153971 +
153972 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
153973 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
153974 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
153975 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
153976 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
153977 +
153978 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
153979 +
153980 +typedef uint8_t ioc_header_field_dccp_t;
153981 +
153982 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
153983 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
153984 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
153985 +
153986 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
153987 +
153988 +
153989 +typedef uint8_t ioc_header_field_udp_t;
153990 +
153991 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
153992 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
153993 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
153994 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
153995 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
153996 +
153997 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
153998 +
153999 +typedef uint8_t ioc_header_field_udp_lite_t;
154000 +
154001 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
154002 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
154003 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
154004 +
154005 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
154006 +
154007 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
154008 +
154009 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
154010 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
154011 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
154012 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
154013 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
154014 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
154015 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
154016 +
154017 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
154018 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
154019 +
154020 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
154021 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
154022 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
154023 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
154024 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
154025 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
154026 +
154027 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
154028 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
154029 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
154030 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
154031 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
154032 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
154033 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
154034 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
154035 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
154036 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
154037 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
154038 +
154039 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
154040 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
154041 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
154042 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
154043 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
154044 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
154045 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
154046 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
154047 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
154048 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
154049 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
154050 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
154051 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
154052 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
154053 +
154054 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
154055 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
154056 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
154057 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
154058 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
154059 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
154060 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
154061 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
154062 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
154063 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
154064 +
154065 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
154066 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
154067 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
154068 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
154069 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
154070 +
154071 +
154072 +typedef uint8_t ioc_header_field_vlan_t;
154073 +
154074 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
154075 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
154076 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
154077 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
154078 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
154079 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
154080 +
154081 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
154082 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
154083 + IOC_NET_HEADER_FIELD_VLAN_VID)
154084 +
154085 +
154086 +typedef uint8_t ioc_header_field_llc_t;
154087 +
154088 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
154089 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
154090 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
154091 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
154092 +
154093 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
154094 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
154095 +
154096 +
154097 +typedef uint8_t ioc_header_field_snap_t;
154098 +
154099 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
154100 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
154101 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
154102 +
154103 +
154104 +typedef uint8_t ioc_header_field_llc_snap_t;
154105 +
154106 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
154107 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
154108 +
154109 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
154110 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
154111 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
154112 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
154113 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
154114 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
154115 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
154116 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
154117 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
154118 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
154119 +
154120 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
154121 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
154122 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
154123 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
154124 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
154125 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
154126 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
154127 +
154128 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
154129 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
154130 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
154131 +
154132 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
154133 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
154134 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
154135 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
154136 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
154137 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
154138 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
154139 +
154140 +
154141 +typedef uint8_t ioc_header_field_gre_t;
154142 +
154143 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
154144 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
154145 +
154146 +
154147 +typedef uint8_t ioc_header_field_minencap_t;
154148 +
154149 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
154150 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
154151 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
154152 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
154153 +
154154 +
154155 +typedef uint8_t ioc_header_field_ipsec_ah_t;
154156 +
154157 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
154158 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
154159 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
154160 +
154161 +
154162 +typedef uint8_t ioc_header_field_ipsec_esp_t;
154163 +
154164 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
154165 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
154166 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
154167 +
154168 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
154169 +
154170 +
154171 +typedef uint8_t ioc_header_field_mpls_t;
154172 +
154173 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
154174 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
154175 +
154176 +
154177 +typedef uint8_t ioc_header_field_macsec_t;
154178 +
154179 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
154180 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
154181 +
154182 +
154183 +typedef enum {
154184 + e_IOC_NET_HEADER_TYPE_NONE = 0,
154185 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
154186 + e_IOC_NET_HEADER_TYPE_ETH,
154187 + e_IOC_NET_HEADER_TYPE_VLAN,
154188 + e_IOC_NET_HEADER_TYPE_IPv4,
154189 + e_IOC_NET_HEADER_TYPE_IPv6,
154190 + e_IOC_NET_HEADER_TYPE_IP,
154191 + e_IOC_NET_HEADER_TYPE_TCP,
154192 + e_IOC_NET_HEADER_TYPE_UDP,
154193 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
154194 + e_IOC_NET_HEADER_TYPE_IPHC,
154195 + e_IOC_NET_HEADER_TYPE_SCTP,
154196 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
154197 + e_IOC_NET_HEADER_TYPE_PPPoE,
154198 + e_IOC_NET_HEADER_TYPE_PPP,
154199 + e_IOC_NET_HEADER_TYPE_PPPMUX,
154200 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
154201 + e_IOC_NET_HEADER_TYPE_L2TPv2,
154202 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
154203 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
154204 + e_IOC_NET_HEADER_TYPE_LLC,
154205 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
154206 + e_IOC_NET_HEADER_TYPE_NLPID,
154207 + e_IOC_NET_HEADER_TYPE_SNAP,
154208 + e_IOC_NET_HEADER_TYPE_MPLS,
154209 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
154210 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
154211 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
154212 + e_IOC_NET_HEADER_TYPE_MACSEC,
154213 + e_IOC_NET_HEADER_TYPE_GRE,
154214 + e_IOC_NET_HEADER_TYPE_MINENCAP,
154215 + e_IOC_NET_HEADER_TYPE_DCCP,
154216 + e_IOC_NET_HEADER_TYPE_ICMP,
154217 + e_IOC_NET_HEADER_TYPE_IGMP,
154218 + e_IOC_NET_HEADER_TYPE_ARP,
154219 + e_IOC_NET_HEADER_TYPE_CAPWAP,
154220 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
154221 + e_IOC_NET_HEADER_TYPE_RFC2684,
154222 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
154223 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
154224 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
154225 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
154226 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
154227 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
154228 +} ioc_net_header_type;
154229 +
154230 +
154231 +#endif /* __NET_IOCTLS_H */